Bug Summary

File:dev/pci/agp_i810.c
Warning:line 255, column 3
Value stored to 'mmaddr' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name agp_i810.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -target-feature +retpoline-external-thunk -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D SUSPEND -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/dev/pci/agp_i810.c
1/* $OpenBSD: agp_i810.c,v 1.95 2022/03/11 18:00:45 mpi Exp $ */
2
3/*-
4 * Copyright (c) 2000 Doug Rabson
5 * Copyright (c) 2000 Ruslan Ermilov
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30
31#include "acpi.h"
32#include "drm.h"
33#include "vga.h"
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/malloc.h>
38#include <sys/device.h>
39#include <sys/rwlock.h>
40
41#include <dev/pci/pcivar.h>
42#include <dev/pci/pcireg.h>
43#include <dev/pci/pcidevs.h>
44#include <dev/pci/agpvar.h>
45#include <dev/pci/agpreg.h>
46#include <dev/pci/drm/i915/i915_drv.h>
47
48#include <machine/bus.h>
49
50#define READ1(off)((isc->map->bst)->read_1((isc->map->bsh), (off
)))
bus_space_read_1(isc->map->bst, isc->map->bsh, off)((isc->map->bst)->read_1((isc->map->bsh), (off
)))
51#define READ4(off)((isc->map->bst)->read_4((isc->map->bsh), (off
)))
bus_space_read_4(isc->map->bst, isc->map->bsh, off)((isc->map->bst)->read_4((isc->map->bsh), (off
)))
52#define WRITE4(off,v)((isc->map->bst)->write_4((isc->map->bsh), (off
), (v)))
bus_space_write_4(isc->map->bst, isc->map->bsh, off, v)((isc->map->bst)->write_4((isc->map->bsh), (off
), (v)))
53
54/*
55 * Intel IGP gtt bits.
56 */
57/* PTE is enabled */
58#define INTEL_ENABLED0x1 0x1
59/* I810/I815 only, memory is in dcache */
60#define INTEL_LOCAL0x2 0x2
61/* Memory is snooped, must not be accessed through gtt from the cpu. */
62#define INTEL_COHERENT0x6 0x6
63
64enum {
65 CHIP_NONE = 0, /* not integrated graphics */
66 CHIP_I810 = 1, /* i810/i815 */
67 CHIP_I830 = 2, /* i830/i845 */
68 CHIP_I855 = 3, /* i852GM/i855GM/i865G */
69 CHIP_I915 = 4, /* i915G/i915GM */
70 CHIP_I965 = 5, /* i965/i965GM */
71 CHIP_G33 = 6, /* G33/Q33/Q35 */
72 CHIP_G4X = 7, /* G4X */
73 CHIP_PINEVIEW = 8, /* Pineview/Pineview M */
74 CHIP_IRONLAKE = 9, /* Clarkdale/Arrandale */
75};
76
77struct agp_i810_softc {
78 struct device dev;
79 bus_dma_segment_t scrib_seg;
80 struct agp_softc *agpdev;
81 struct agp_gatt *gatt;
82 struct vga_pci_bar *map;
83 bus_space_tag_t gtt_bst;
84 bus_space_handle_t gtt_bsh;
85 bus_size_t gtt_size;
86 bus_dmamap_t scrib_dmamap;
87 bus_addr_t isc_apaddr;
88 bus_size_t isc_apsize; /* current aperture size */
89 int chiptype; /* i810-like or i830 */
90 u_int32_t dcache_size; /* i810 only */
91 u_int32_t stolen; /* number of i830/845 gtt
92 entries for stolen memory */
93};
94
95void agp_i810_attach(struct device *, struct device *, void *);
96int agp_i810_activate(struct device *, int);
97void agp_i810_configure(struct agp_i810_softc *);
98int agp_i810_probe(struct device *, void *, void *);
99int agp_i810_get_chiptype(struct pci_attach_args *);
100void agp_i810_bind_page(void *, bus_size_t, paddr_t, int);
101void agp_i810_unbind_page(void *, bus_size_t);
102void agp_i810_flush_tlb(void *);
103int agp_i810_enable(void *, u_int32_t mode);
104void intagp_write_gtt(struct agp_i810_softc *, bus_size_t, paddr_t);
105int intagp_gmch_match(struct pci_attach_args *);
106
107extern void intagp_dma_sync(bus_dma_tag_t, bus_dmamap_t,
108 bus_addr_t, bus_size_t, int);
109
110const struct cfattach intagp_ca = {
111 sizeof(struct agp_i810_softc), agp_i810_probe, agp_i810_attach,
112 NULL((void *)0), agp_i810_activate,
113};
114
115struct cfdriver intagp_cd = {
116 NULL((void *)0), "intagp", DV_DULL
117};
118
119struct agp_methods agp_i810_methods = {
120 agp_i810_bind_page,
121 agp_i810_unbind_page,
122 agp_i810_flush_tlb,
123 agp_i810_enable,
124};
125
126int
127agp_i810_get_chiptype(struct pci_attach_args *pa)
128{
129 switch (PCI_PRODUCT(pa->pa_id)(((pa->pa_id) >> 16) & 0xffff)) {
130 case PCI_PRODUCT_INTEL_82810_IGD0x7121:
131 case PCI_PRODUCT_INTEL_82810_DC100_IGD0x7123:
132 case PCI_PRODUCT_INTEL_82810E_IGD0x7125:
133 case PCI_PRODUCT_INTEL_82815_IGD0x1132:
134 return (CHIP_I810);
135 break;
136 case PCI_PRODUCT_INTEL_82830M_IGD0x3577:
137 case PCI_PRODUCT_INTEL_82845G_IGD0x2562:
138 return (CHIP_I830);
139 break;
140 case PCI_PRODUCT_INTEL_82854_IGD0x358e:
141 case PCI_PRODUCT_INTEL_82855GM_IGD0x3582:
142 case PCI_PRODUCT_INTEL_82865G_IGD0x2572:
143 return (CHIP_I855);
144 break;
145 case PCI_PRODUCT_INTEL_E7221_IGD0x258a:
146 case PCI_PRODUCT_INTEL_82915G_IGD_10x2582:
147 case PCI_PRODUCT_INTEL_82915G_IGD_20x2782:
148 case PCI_PRODUCT_INTEL_82915GM_IGD_10x2592:
149 case PCI_PRODUCT_INTEL_82915GM_IGD_20x2792:
150 case PCI_PRODUCT_INTEL_82945G_IGD_10x2772:
151 case PCI_PRODUCT_INTEL_82945G_IGD_20x2776:
152 case PCI_PRODUCT_INTEL_82945GM_IGD_10x27a2:
153 case PCI_PRODUCT_INTEL_82945GM_IGD_20x27a6:
154 case PCI_PRODUCT_INTEL_82945GME_IGD_10x27ae:
155 return (CHIP_I915);
156 break;
157 case PCI_PRODUCT_INTEL_82946GZ_IGD_10x2972:
158 case PCI_PRODUCT_INTEL_82946GZ_IGD_20x2973:
159 case PCI_PRODUCT_INTEL_82Q965_IGD_10x2992:
160 case PCI_PRODUCT_INTEL_82Q965_IGD_20x2993:
161 case PCI_PRODUCT_INTEL_82G965_IGD_10x29a2:
162 case PCI_PRODUCT_INTEL_82G965_IGD_20x29a3:
163 case PCI_PRODUCT_INTEL_82GM965_IGD_10x2a02:
164 case PCI_PRODUCT_INTEL_82GM965_IGD_20x2a03:
165 case PCI_PRODUCT_INTEL_82GME965_IGD_10x2a12:
166 case PCI_PRODUCT_INTEL_82GME965_IGD_20x2a13:
167 case PCI_PRODUCT_INTEL_82G35_IGD_10x2982:
168 case PCI_PRODUCT_INTEL_82G35_IGD_20x2983:
169 return (CHIP_I965);
170 break;
171 case PCI_PRODUCT_INTEL_82G33_IGD_10x29c2:
172 case PCI_PRODUCT_INTEL_82G33_IGD_20x29c3:
173 case PCI_PRODUCT_INTEL_82Q35_IGD_10x29b2:
174 case PCI_PRODUCT_INTEL_82Q35_IGD_20x29b3:
175 case PCI_PRODUCT_INTEL_82Q33_IGD_10x29d2:
176 case PCI_PRODUCT_INTEL_82Q33_IGD_20x29d3:
177 return (CHIP_G33);
178 break;
179 case PCI_PRODUCT_INTEL_82GM45_IGD_10x2a42:
180 case PCI_PRODUCT_INTEL_4SERIES_IGD0x2e02:
181 case PCI_PRODUCT_INTEL_82Q45_IGD_10x2e12:
182 case PCI_PRODUCT_INTEL_82G45_IGD_10x2e22:
183 case PCI_PRODUCT_INTEL_82G41_IGD_10x2e32:
184 case PCI_PRODUCT_INTEL_82B43_IGD_10x2e42:
185 case PCI_PRODUCT_INTEL_82B43_IGD_20x2e92:
186 return (CHIP_G4X);
187 break;
188 case PCI_PRODUCT_INTEL_PINEVIEW_IGC_10xa001:
189 case PCI_PRODUCT_INTEL_PINEVIEW_M_IGC_10xa011:
190 return (CHIP_PINEVIEW);
191 break;
192 case PCI_PRODUCT_INTEL_CLARKDALE_IGD0x0042:
193 case PCI_PRODUCT_INTEL_ARRANDALE_IGD0x0046:
194 return (CHIP_IRONLAKE);
195 break;
196 }
197
198 return (CHIP_NONE);
199}
200
201/*
202 * We're intel IGD, bus 0 function 0 dev 0 should be the GMCH, so it should
203 * be Intel
204 */
205int
206intagp_gmch_match(struct pci_attach_args *pa)
207{
208 if (pa->pa_bus == 0 && pa->pa_device == 0 && pa->pa_function == 0 &&
209 PCI_VENDOR(pa->pa_id)(((pa->pa_id) >> 0) & 0xffff) == PCI_VENDOR_INTEL0x8086 &&
210 PCI_CLASS(pa->pa_class)(((pa->pa_class) >> 24) & 0xff) == PCI_CLASS_BRIDGE0x06 &&
211 PCI_SUBCLASS(pa->pa_class)(((pa->pa_class) >> 16) & 0xff) == PCI_SUBCLASS_BRIDGE_HOST0x00)
212 return (1);
213 return (0);
214}
215
216int
217agp_i810_probe(struct device *parent, void *match, void *aux)
218{
219 struct pci_attach_args *pa = aux;
220
221 if (PCI_CLASS(pa->pa_class)(((pa->pa_class) >> 24) & 0xff) != PCI_CLASS_DISPLAY0x03 ||
222 PCI_SUBCLASS(pa->pa_class)(((pa->pa_class) >> 16) & 0xff) != PCI_SUBCLASS_DISPLAY_VGA0x00)
223 return (0);
224
225 return (agp_i810_get_chiptype(pa) != CHIP_NONE);
226}
227
228void
229agp_i810_attach(struct device *parent, struct device *self, void *aux)
230{
231 struct agp_i810_softc *isc = (struct agp_i810_softc *)self;
232 struct agp_gatt *gatt;
233 struct pci_attach_args *pa = aux, bpa;
234 struct inteldrm_softc *psc = (struct inteldrm_softc *)parent;
235 bus_addr_t mmaddr, gmaddr, tmp;
236 bus_size_t gtt_off = 0;
237 pcireg_t memtype, reg;
238 u_int32_t stolen;
239 u_int16_t gcc1;
240
241 isc->chiptype = agp_i810_get_chiptype(pa);
242
243 switch (isc->chiptype) {
244 case CHIP_I915:
245 case CHIP_G33:
246 case CHIP_PINEVIEW:
247 gmaddr = AGP_I915_GMADR0x18;
248 mmaddr = AGP_I915_MMADR0x10;
249 memtype = PCI_MAPREG_TYPE_MEM0x00000000;
250 break;
251 case CHIP_I965:
252 case CHIP_G4X:
253 case CHIP_IRONLAKE:
254 gmaddr = AGP_I965_GMADR0x18;
255 mmaddr = AGP_I965_MMADR0x10;
Value stored to 'mmaddr' is never read
256 memtype = PCI_MAPREG_TYPE_MEM0x00000000 | PCI_MAPREG_MEM_TYPE_64BIT0x00000004;
257 if (isc->chiptype == CHIP_I965)
258 gtt_off = AGP_I965_GTT0x80000;
259 else
260 gtt_off = AGP_G4X_GTT0x200000;
261 break;
262 default:
263 gmaddr = AGP_APBASE0x10;
264 mmaddr = AGP_I810_MMADR0x14;
265 memtype = PCI_MAPREG_TYPE_MEM0x00000000;
266 gtt_off = AGP_I810_GTT0x10000;
267 break;
268 }
269
270 if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, gmaddr, memtype,
271 &isc->isc_apaddr, &isc->isc_apsize, NULL((void *)0)) != 0) {
272 printf("can't get aperture info\n");
273 return;
274 }
275
276 isc->map = psc->vga_regs;
277
278 if (isc->chiptype == CHIP_I915 || isc->chiptype == CHIP_G33 ||
279 isc->chiptype == CHIP_PINEVIEW) {
280 if (pci_mapreg_map(pa, AGP_I915_GTTADR0x1C, memtype,
281 BUS_SPACE_MAP_LINEAR0x0002, &isc->gtt_bst, &isc->gtt_bsh,
282 NULL((void *)0), &isc->gtt_size, 0)) {
283 printf("can't map gatt registers\n");
284 goto out;
285 }
286 } else if (gtt_off >= isc->map->size) {
287 isc->gtt_bst = isc->map->bst;
288 isc->gtt_size = (isc->isc_apsize >> AGP_PAGE_SHIFT12) * 4;
289 if (bus_space_map(isc->gtt_bst, isc->map->base + gtt_off,
290 isc->gtt_size, BUS_SPACE_MAP_LINEAR0x0002, &isc->gtt_bsh)) {
291 printf("can't map gatt registers\n");
292 isc->gtt_size = 0;
293 goto out;
294 }
295 } else {
296 isc->gtt_bst = isc->map->bst;
297 if (bus_space_subregion(isc->map->bst, isc->map->bsh, gtt_off,
298 (isc->isc_apsize >> AGP_PAGE_SHIFT12) * 4, &isc->gtt_bsh)) {
299 printf("can't map gatt registers\n");
300 goto out;
301 }
302 }
303
304 gatt = malloc(sizeof(*gatt), M_AGP144, M_NOWAIT0x0002 | M_ZERO0x0008);
305 if (gatt == NULL((void *)0)) {
306 printf("can't alloc gatt\n");
307 goto out;
308 }
309 isc->gatt = gatt;
310
311 gatt->ag_entries = isc->isc_apsize >> AGP_PAGE_SHIFT12;
312
313 /*
314 * Find the GMCH, some of the registers we need to read for
315 * configuration purposes are on there. it's always at
316 * 0/0/0 (bus/dev/func).
317 */
318 if (pci_find_device(&bpa, intagp_gmch_match) == 0) {
319 printf("can't find GMCH\n");
320 goto out;
321 }
322
323 switch (isc->chiptype) {
324 case CHIP_I810:
325 /* Some i810s have on-chip memory called dcache */
326 if (READ1(AGP_I810_DRT)((isc->map->bst)->read_1((isc->map->bsh), (0x3000
)))
& AGP_I810_DRT_POPULATED0x01)
327 isc->dcache_size = 4 * 1024 * 1024;
328 else
329 isc->dcache_size = 0;
330
331 /* According to the specs the gatt on the i810 must be 64k */
332 if (agp_alloc_dmamem(pa->pa_dmat, 64 * 1024, &gatt->ag_dmamap,
333 &gatt->ag_physical, &gatt->ag_dmaseg) != 0) {
334 goto out;
335 }
336 gatt->ag_size = gatt->ag_entries * sizeof(u_int32_t);
337
338 if (bus_dmamem_map(pa->pa_dmat, &gatt->ag_dmaseg, 1, 64 * 1024,(*(pa->pa_dmat)->_dmamem_map)((pa->pa_dmat), (&gatt
->ag_dmaseg), (1), (64 * 1024), ((caddr_t *)&gatt->
ag_virtual), (0x0001))
339 (caddr_t *)&gatt->ag_virtual, BUS_DMA_NOWAIT)(*(pa->pa_dmat)->_dmamem_map)((pa->pa_dmat), (&gatt
->ag_dmaseg), (1), (64 * 1024), ((caddr_t *)&gatt->
ag_virtual), (0x0001))
!= 0)
340 goto out;
341 break;
342
343 case CHIP_I830:
344 /* The i830 automatically initializes the 128k gatt on boot. */
345
346 reg = pci_conf_read(bpa.pa_pc, bpa.pa_tag, AGP_I830_GCC00x50);
347 gcc1 = (u_int16_t)(reg >> 16);
348 switch (gcc1 & AGP_I830_GCC1_GMS0xf0) {
349 case AGP_I830_GCC1_GMS_STOLEN_5120x20:
350 isc->stolen = (512 - 132) * 1024 / 4096;
351 break;
352 case AGP_I830_GCC1_GMS_STOLEN_10240x30:
353 isc->stolen = (1024 - 132) * 1024 / 4096;
354 break;
355 case AGP_I830_GCC1_GMS_STOLEN_81920x40:
356 isc->stolen = (8192 - 132) * 1024 / 4096;
357 break;
358 default:
359 isc->stolen = 0;
360 printf("unknown memory configuration, disabling\n");
361 goto out;
362 }
363#ifdef DEBUG
364 if (isc->stolen > 0) {
365 printf(": detected %dk stolen memory",
366 isc->stolen * 4);
367 } else
368 printf(": no preallocated video memory\n");
369#endif
370
371 /* XXX */
372 isc->stolen = 0;
373
374 /* GATT address is already in there, make sure it's enabled */
375 gatt->ag_physical = READ4(AGP_I810_PGTBL_CTL)((isc->map->bst)->read_4((isc->map->bsh), (0x2020
)))
& ~1;
376 break;
377
378 case CHIP_I855:
379 /* FALLTHROUGH */
380 case CHIP_I915:
381 /* FALLTHROUGH */
382 case CHIP_I965:
383 /* FALLTHROUGH */
384 case CHIP_G33:
385 /* FALLTHROUGH */
386 case CHIP_G4X:
387 case CHIP_PINEVIEW:
388 case CHIP_IRONLAKE:
389
390 /* Stolen memory is set up at the beginning of the aperture by
391 * the BIOS, consisting of the GATT followed by 4kb for the
392 * BIOS display.
393 */
394
395 reg = pci_conf_read(bpa.pa_pc, bpa.pa_tag, AGP_I855_GCC10x50);
396 gcc1 = (u_int16_t)(reg >> 16);
397 switch (isc->chiptype) {
398 case CHIP_I855:
399 /* The 855GM automatically initializes the 128k gatt on boot. */
400 stolen = 128 + 4;
401 break;
402 case CHIP_I915:
403 /* The 915G automatically initializes the 256k gatt on boot. */
404 stolen = 256 + 4;
405 break;
406 case CHIP_I965:
407 switch (READ4(AGP_I810_PGTBL_CTL)((isc->map->bst)->read_4((isc->map->bsh), (0x2020
)))
&
408 AGP_I810_PGTBL_SIZE_MASK0x0000000e) {
409 case AGP_I810_PGTBL_SIZE_512KB(0 << 1):
410 stolen = 512 + 4;
411 break;
412 case AGP_I810_PGTBL_SIZE_256KB(1 << 1):
413 stolen = 256 + 4;
414 break;
415 case AGP_I810_PGTBL_SIZE_128KB(2 << 1):
416 default:
417 stolen = 128 + 4;
418 break;
419 }
420 break;
421 case CHIP_G33:
422 switch (gcc1 & AGP_G33_PGTBL_SIZE_MASK(3U << 8)) {
423 case AGP_G33_PGTBL_SIZE_2M(2U << 8):
424 stolen = 2048 + 4;
425 break;
426 case AGP_G33_PGTBL_SIZE_1M(1U << 8):
427 default:
428 stolen = 1024 + 4;
429 break;
430 }
431 break;
432 case CHIP_G4X:
433 case CHIP_PINEVIEW:
434 case CHIP_IRONLAKE:
435 /*
436 * GTT stolen is separate from graphics stolen on
437 * 4 series hardware. so ignore it in stolen gtt entries
438 * counting. However, 4Kb of stolen memory isn't mapped
439 * to the GTT.
440 */
441 stolen = 4;
442 break;
443 default:
444 printf("bad chiptype\n");
445 goto out;
446 }
447
448 switch (gcc1 & AGP_I855_GCC1_GMS0xf0) {
449 case AGP_I855_GCC1_GMS_STOLEN_1M0x10:
450 isc->stolen = (1024 - stolen) * 1024 / 4096;
451 break;
452 case AGP_I855_GCC1_GMS_STOLEN_4M0x20:
453 isc->stolen = (4096 - stolen) * 1024 / 4096;
454 break;
455 case AGP_I855_GCC1_GMS_STOLEN_8M0x30:
456 isc->stolen = (8192 - stolen) * 1024 / 4096;
457 break;
458 case AGP_I855_GCC1_GMS_STOLEN_16M0x40:
459 isc->stolen = (16384 - stolen) * 1024 / 4096;
460 break;
461 case AGP_I855_GCC1_GMS_STOLEN_32M0x50:
462 isc->stolen = (32768 - stolen) * 1024 / 4096;
463 break;
464 case AGP_I915_GCC1_GMS_STOLEN_48M0x60:
465 isc->stolen = (49152 - stolen) * 1024 / 4096;
466 break;
467 case AGP_I915_GCC1_GMS_STOLEN_64M0x70:
468 isc->stolen = (65536 - stolen) * 1024 / 4096;
469 break;
470 case AGP_G33_GCC1_GMS_STOLEN_128M0x80:
471 isc->stolen = (131072 - stolen) * 1024 / 4096;
472 break;
473 case AGP_G33_GCC1_GMS_STOLEN_256M0x90:
474 isc->stolen = (262144 - stolen) * 1024 / 4096;
475 break;
476 case AGP_INTEL_GMCH_GMS_STOLEN_96M0xa0:
477 isc->stolen = (98304 - stolen) * 1024 / 4096;
478 break;
479 case AGP_INTEL_GMCH_GMS_STOLEN_160M0xb0:
480 isc->stolen = (163840 - stolen) * 1024 / 4096;
481 break;
482 case AGP_INTEL_GMCH_GMS_STOLEN_224M0xc0:
483 isc->stolen = (229376 - stolen) * 1024 / 4096;
484 break;
485 case AGP_INTEL_GMCH_GMS_STOLEN_352M0xd0:
486 isc->stolen = (360448 - stolen) * 1024 / 4096;
487 break;
488 default:
489 isc->stolen = 0;
490 printf("unknown memory configuration, disabling\n");
491 goto out;
492 }
493#ifdef DEBUG
494 if (isc->stolen > 0) {
495 printf(": detected %dk stolen memory",
496 isc->stolen * 4);
497 } else
498 printf(": no preallocated video memory\n");
499#endif
500
501 /* XXX */
502 isc->stolen = 0;
503
504 /* GATT address is already in there, make sure it's enabled */
505 gatt->ag_physical = READ4(AGP_I810_PGTBL_CTL)((isc->map->bst)->read_4((isc->map->bsh), (0x2020
)))
& ~1;
506 break;
507
508 default:
509 printf(": unknown initialisation\n");
510 return;
511 }
512 /* Intel recommends that you have a fake page bound to the gtt always */
513 if (agp_alloc_dmamem(pa->pa_dmat, AGP_PAGE_SIZE4096, &isc->scrib_dmamap,
514 &tmp, &isc->scrib_seg) != 0) {
515 printf(": can't get scribble page\n");
516 return;
517 }
518 agp_i810_configure(isc);
519
520 isc->agpdev = (struct agp_softc *)agp_attach_bus(pa, &agp_i810_methods,
521 isc->isc_apaddr, isc->isc_apsize, &isc->dev);
522 isc->agpdev->sc_stolen_entries = isc->stolen;
523 return;
524out:
525
526 if (isc->gatt) {
527 if (isc->gatt->ag_size != 0)
528 agp_free_dmamem(pa->pa_dmat, isc->gatt->ag_size,
529 isc->gatt->ag_dmamap, &isc->gatt->ag_dmaseg);
530 free(isc->gatt, M_AGP144, sizeof (*isc->gatt));
531 }
532 if (isc->gtt_size != 0)
533 bus_space_unmap(isc->gtt_bst, isc->gtt_bsh, isc->gtt_size);
534}
535
536int
537agp_i810_activate(struct device *arg, int act)
538{
539 struct agp_i810_softc *isc = (struct agp_i810_softc *)arg;
540
541 /*
542 * Anything kept in agp over a suspend/resume cycle (and thus by X
543 * over a vt switch cycle) is undefined upon resume.
544 */
545 switch (act) {
546 case DVACT_RESUME4:
547 agp_i810_configure(isc);
548 break;
549 }
550
551 return (0);
552}
553
554void
555agp_i810_configure(struct agp_i810_softc *isc)
556{
557 bus_addr_t tmp;
558
559 tmp = isc->isc_apaddr;
560 if (isc->chiptype == CHIP_I810) {
561 tmp += isc->dcache_size;
562 } else {
563 tmp += isc->stolen << AGP_PAGE_SHIFT12;
564 }
565
566 agp_flush_cache();
567 /* Install the GATT. */
568 WRITE4(AGP_I810_PGTBL_CTL, isc->gatt->ag_physical | 1)((isc->map->bst)->write_4((isc->map->bsh), (0x2020
), (isc->gatt->ag_physical | 1)))
;
569
570 /* initialise all gtt entries to point to scribble page */
571 for (; tmp < (isc->isc_apaddr + isc->isc_apsize);
572 tmp += AGP_PAGE_SIZE4096)
573 agp_i810_unbind_page(isc, tmp);
574 /* XXX we'll need to restore the GTT contents when we go kms */
575
576 /*
577 * Make sure the chipset can see everything.
578 */
579 agp_flush_cache();
580}
581
582void
583agp_i810_bind_page(void *sc, bus_addr_t offset, paddr_t physical, int flags)
584{
585 struct agp_i810_softc *isc = sc;
586
587 /*
588 * COHERENT mappings mean set the snoop bit. this should never be
589 * accessed by the gpu through the gtt.
590 */
591 if (flags & BUS_DMA_COHERENT0x0004)
592 physical |= INTEL_COHERENT0x6;
593
594 intagp_write_gtt(isc, offset - isc->isc_apaddr, physical);
595}
596
597void
598agp_i810_unbind_page(void *sc, bus_size_t offset)
599{
600 struct agp_i810_softc *isc = sc;
601
602 intagp_write_gtt(isc, offset - isc->isc_apaddr,
603 isc->scrib_dmamap->dm_segs[0].ds_addr);
604}
605
606/*
607 * Writing via memory mapped registers already flushes all TLBs.
608 */
609void
610agp_i810_flush_tlb(void *sc)
611{
612}
613
614int
615agp_i810_enable(void *sc, u_int32_t mode)
616{
617 return (0);
618}
619
620void
621intagp_write_gtt(struct agp_i810_softc *isc, bus_size_t off, paddr_t v)
622{
623 u_int32_t pte = 0;
624 bus_size_t wroff;
625
626 if (isc->chiptype != CHIP_I810 &&
627 (off >> AGP_PAGE_SHIFT12) < isc->stolen) {
628 printf("intagp: binding into stolen memory! (0x%lx)\n",
629 (off >> AGP_PAGE_SHIFT12));
630 }
631
632 if (v != 0) {
633 pte = v | INTEL_ENABLED0x1;
634 /* 965+ can do 36-bit addressing, add in the extra bits */
635 switch (isc->chiptype) {
636 case CHIP_I965:
637 case CHIP_G4X:
638 case CHIP_PINEVIEW:
639 case CHIP_G33:
640 case CHIP_IRONLAKE:
641 pte |= (v & 0x0000000f00000000ULL) >> 28;
642 break;
643 }
644 }
645
646 wroff = (off >> AGP_PAGE_SHIFT12) * 4;
647 bus_space_write_4(isc->gtt_bst, isc->gtt_bsh, wroff, pte)((isc->gtt_bst)->write_4((isc->gtt_bsh), (wroff), (pte
)))
;
648}