Bug Summary

File:arch/amd64/pci/pci_machdep.c
Warning:line 608, column 11
The left operand of '==' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name pci_machdep.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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 -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 -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/lib/clang/13.0.0 -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/swsmu -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/powerplay -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/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 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 -D CONFIG_DRM_AMD_DC_DCN3_0 -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 -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 /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/arch/amd64/pci/pci_machdep.c
1/* $OpenBSD: pci_machdep.c,v 1.77 2021/03/11 11:16:55 jsg Exp $ */
2/* $NetBSD: pci_machdep.c,v 1.3 2003/05/07 21:33:58 fvdl Exp $ */
3
4/*-
5 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10 * NASA Ames Research Center.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/*
35 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
36 * Copyright (c) 1994 Charles M. Hannum. All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by Charles M. Hannum.
49 * 4. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
53 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
54 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
55 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
56 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
57 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
61 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 */
63
64/*
65 * Machine-specific functions for PCI autoconfiguration.
66 */
67
68#include <sys/param.h>
69#include <sys/systm.h>
70#include <sys/extent.h>
71#include <sys/malloc.h>
72
73#include <machine/bus.h>
74
75#include <machine/pio.h>
76#include <machine/intr.h>
77#include <machine/biosvar.h>
78
79#include <dev/isa/isareg.h>
80#include <dev/pci/pcivar.h>
81#include <dev/pci/pcireg.h>
82#include <dev/pci/pcidevs.h>
83#include <dev/pci/ppbreg.h>
84
85#include "ioapic.h"
86
87#if NIOAPIC1 > 0
88#include <machine/i82093var.h>
89#include <machine/mpbiosvar.h>
90#endif
91
92#include "acpi.h"
93
94#include "acpidmar.h"
95#if NACPIDMAR1 > 0
96#include <dev/acpi/acpidmar.h>
97#endif
98
99/*
100 * Memory Mapped Configuration space access.
101 *
102 * Since mapping the whole configuration space will cost us up to
103 * 256MB of kernel virtual memory, we use separate mappings per bus.
104 * The mappings are created on-demand, such that we only use kernel
105 * virtual memory for busses that are actually present.
106 */
107bus_addr_t pci_mcfg_addr;
108int pci_mcfg_min_bus, pci_mcfg_max_bus;
109bus_space_tag_t pci_mcfgt;
110bus_space_handle_t pci_mcfgh[256];
111
112struct mutex pci_conf_lock = MUTEX_INITIALIZER(IPL_HIGH){ ((void *)0), ((((0xd)) > 0x0 && ((0xd)) < 0x9
) ? 0x9 : ((0xd))), 0x0 }
;
113
114#define PCI_CONF_LOCK()do { mtx_enter(&pci_conf_lock); } while (0) \
115do { \
116 mtx_enter(&pci_conf_lock); \
117} while (0)
118
119#define PCI_CONF_UNLOCK()do { mtx_leave(&pci_conf_lock); } while (0) \
120do { \
121 mtx_leave(&pci_conf_lock); \
122} while (0)
123
124#define PCI_MODE1_ENABLE0x80000000UL 0x80000000UL
125#define PCI_MODE1_ADDRESS_REG0x0cf8 0x0cf8
126#define PCI_MODE1_DATA_REG0x0cfc 0x0cfc
127
128/*
129 * PCI doesn't have any special needs; just use the generic versions
130 * of these functions.
131 */
132struct bus_dma_tag pci_bus_dma_tag = {
133 NULL((void *)0), /* _may_bounce */
134 _bus_dmamap_create,
135 _bus_dmamap_destroy,
136 _bus_dmamap_load,
137 _bus_dmamap_load_mbuf,
138 _bus_dmamap_load_uio,
139 _bus_dmamap_load_raw,
140 _bus_dmamap_unload,
141 _bus_dmamap_sync,
142 _bus_dmamem_alloc,
143 _bus_dmamem_alloc_range,
144 _bus_dmamem_free,
145 _bus_dmamem_map,
146 _bus_dmamem_unmap,
147 _bus_dmamem_mmap,
148};
149
150void
151pci_mcfg_init(bus_space_tag_t iot, bus_addr_t addr, int segment,
152 int min_bus, int max_bus)
153{
154 if (segment == 0) {
155 pci_mcfgt = iot;
156 pci_mcfg_addr = addr;
157 pci_mcfg_min_bus = min_bus;
158 pci_mcfg_max_bus = max_bus;
159 }
160}
161
162pci_chipset_tag_t
163pci_lookup_segment(int segment)
164{
165 KASSERT(segment == 0)((segment == 0) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/arch/amd64/pci/pci_machdep.c"
, 165, "segment == 0"))
;
166 return NULL((void *)0);
167}
168
169void
170pci_attach_hook(struct device *parent, struct device *self,
171 struct pcibus_attach_args *pba)
172{
173}
174
175int
176pci_bus_maxdevs(pci_chipset_tag_t pc, int busno)
177{
178 return (32);
179}
180
181pcitag_t
182pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function)
183{
184 if (bus >= 256 || device >= 32 || function >= 8)
185 panic("pci_make_tag: bad request");
186
187 return (PCI_MODE1_ENABLE0x80000000UL |
188 (bus << 16) | (device << 11) | (function << 8));
189}
190
191void
192pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, int *bp, int *dp, int *fp)
193{
194 if (bp != NULL((void *)0))
195 *bp = (tag >> 16) & 0xff;
196 if (dp != NULL((void *)0))
197 *dp = (tag >> 11) & 0x1f;
198 if (fp != NULL((void *)0))
199 *fp = (tag >> 8) & 0x7;
200}
201
202int
203pci_conf_size(pci_chipset_tag_t pc, pcitag_t tag)
204{
205 int bus;
206
207 if (pci_mcfg_addr) {
208 pci_decompose_tag(pc, tag, &bus, NULL((void *)0), NULL((void *)0));
209 if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus)
210 return PCIE_CONFIG_SPACE_SIZE0x1000;
211 }
212
213 return PCI_CONFIG_SPACE_SIZE0x100;
214}
215
216void
217pci_mcfg_map_bus(int bus)
218{
219 if (pci_mcfgh[bus])
220 return;
221
222 if (bus_space_map(pci_mcfgt, pci_mcfg_addr + (bus << 20), 1 << 20,
223 0, &pci_mcfgh[bus]))
224 panic("pci_conf_read: cannot map mcfg space");
225}
226
227pcireg_t
228pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
229{
230 pcireg_t data;
231 int bus;
232
233 KASSERT((reg & 0x3) == 0)(((reg & 0x3) == 0) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/arch/amd64/pci/pci_machdep.c"
, 233, "(reg & 0x3) == 0"))
;
234
235 if (pci_mcfg_addr && reg >= PCI_CONFIG_SPACE_SIZE0x100) {
236 pci_decompose_tag(pc, tag, &bus, NULL((void *)0), NULL((void *)0));
237 if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus) {
238 pci_mcfg_map_bus(bus);
239 data = bus_space_read_4(pci_mcfgt, pci_mcfgh[bus],((pci_mcfgt)->read_4((pci_mcfgh[bus]), ((tag & 0x000ff00
) << 4 | reg)))
240 (tag & 0x000ff00) << 4 | reg)((pci_mcfgt)->read_4((pci_mcfgh[bus]), ((tag & 0x000ff00
) << 4 | reg)))
;
241 return data;
242 }
243 }
244
245 PCI_CONF_LOCK()do { mtx_enter(&pci_conf_lock); } while (0);
246 outl(PCI_MODE1_ADDRESS_REG, tag | reg)( (__builtin_constant_p((0x0cf8)) && (0x0cf8) < 0x100
) ? __outlc(0x0cf8, tag | reg) : __outl(0x0cf8, tag | reg))
;
247 data = inl(PCI_MODE1_DATA_REG)( (__builtin_constant_p((0x0cfc)) && (0x0cfc) < 0x100
) ? __inlc(0x0cfc) : __inl(0x0cfc))
;
248 outl(PCI_MODE1_ADDRESS_REG, 0)( (__builtin_constant_p((0x0cf8)) && (0x0cf8) < 0x100
) ? __outlc(0x0cf8, 0) : __outl(0x0cf8, 0))
;
249 PCI_CONF_UNLOCK()do { mtx_leave(&pci_conf_lock); } while (0);
250
251 return data;
252}
253
254void
255pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
256{
257 int bus;
258
259 KASSERT((reg & 0x3) == 0)(((reg & 0x3) == 0) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/arch/amd64/pci/pci_machdep.c"
, 259, "(reg & 0x3) == 0"))
;
260
261 if (pci_mcfg_addr && reg >= PCI_CONFIG_SPACE_SIZE0x100) {
262 pci_decompose_tag(pc, tag, &bus, NULL((void *)0), NULL((void *)0));
263 if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus) {
264 pci_mcfg_map_bus(bus);
265 bus_space_write_4(pci_mcfgt, pci_mcfgh[bus],((pci_mcfgt)->write_4((pci_mcfgh[bus]), ((tag & 0x000ff00
) << 4 | reg), (data)))
266 (tag & 0x000ff00) << 4 | reg, data)((pci_mcfgt)->write_4((pci_mcfgh[bus]), ((tag & 0x000ff00
) << 4 | reg), (data)))
;
267 return;
268 }
269 }
270
271 PCI_CONF_LOCK()do { mtx_enter(&pci_conf_lock); } while (0);
272 outl(PCI_MODE1_ADDRESS_REG, tag | reg)( (__builtin_constant_p((0x0cf8)) && (0x0cf8) < 0x100
) ? __outlc(0x0cf8, tag | reg) : __outl(0x0cf8, tag | reg))
;
273 outl(PCI_MODE1_DATA_REG, data)( (__builtin_constant_p((0x0cfc)) && (0x0cfc) < 0x100
) ? __outlc(0x0cfc, data) : __outl(0x0cfc, data))
;
274 outl(PCI_MODE1_ADDRESS_REG, 0)( (__builtin_constant_p((0x0cf8)) && (0x0cf8) < 0x100
) ? __outlc(0x0cf8, 0) : __outl(0x0cf8, 0))
;
275 PCI_CONF_UNLOCK()do { mtx_leave(&pci_conf_lock); } while (0);
276}
277
278int
279pci_msix_table_map(pci_chipset_tag_t pc, pcitag_t tag,
280 bus_space_tag_t memt, bus_space_handle_t *memh)
281{
282 bus_addr_t base;
283 pcireg_t reg, table, type;
284 int bir, offset;
285 int off, tblsz;
286
287 if (pci_get_capability(pc, tag, PCI_CAP_MSIX0x11, &off, &reg) == 0)
288 panic("%s: no msix capability", __func__);
289
290 table = pci_conf_read(pc, tag, off + PCI_MSIX_TABLE0x04);
291 bir = (table & PCI_MSIX_TABLE_BIR0x00000007);
292 offset = (table & PCI_MSIX_TABLE_OFF~(0x00000007));
293 tblsz = PCI_MSIX_MC_TBLSZ(reg)(((reg) & 0x07ff0000) >> 16) + 1;
294
295 bir = PCI_MAPREG_START0x10 + bir * 4;
296 type = pci_mapreg_type(pc, tag, bir);
297 if (pci_mapreg_info(pc, tag, bir, type, &base, NULL((void *)0), NULL((void *)0)) ||
298 _bus_space_map(memt, base + offset, tblsz * 16, 0, memh))
299 return -1;
300
301 return 0;
302}
303
304void
305pci_msix_table_unmap(pci_chipset_tag_t pc, pcitag_t tag,
306 bus_space_tag_t memt, bus_space_handle_t memh)
307{
308 pcireg_t reg;
309 int tblsz;
310
311 if (pci_get_capability(pc, tag, PCI_CAP_MSIX0x11, NULL((void *)0), &reg) == 0)
312 panic("%s: no msix capability", __func__);
313
314 tblsz = PCI_MSIX_MC_TBLSZ(reg)(((reg) & 0x07ff0000) >> 16) + 1;
315 _bus_space_unmap(memt, memh, tblsz * 16, NULL((void *)0));
316}
317
318void msi_hwmask(struct pic *, int);
319void msi_hwunmask(struct pic *, int);
320void msi_addroute(struct pic *, struct cpu_info *, int, int, int);
321void msi_delroute(struct pic *, struct cpu_info *, int, int, int);
322
323struct pic msi_pic = {
324 {0, {NULL((void *)0)}, NULL((void *)0), 0, "msi", NULL((void *)0), 0, 0},
325 PIC_MSI3,
326#ifdef MULTIPROCESSOR1
327 {},
328#endif
329 msi_hwmask,
330 msi_hwunmask,
331 msi_addroute,
332 msi_delroute,
333 NULL((void *)0),
334 ioapic_edge_stubs
335};
336
337void
338msi_hwmask(struct pic *pic, int pin)
339{
340}
341
342void
343msi_hwunmask(struct pic *pic, int pin)
344{
345}
346
347void
348msi_addroute(struct pic *pic, struct cpu_info *ci, int pin, int vec, int type)
349{
350 pci_chipset_tag_t pc = NULL((void *)0); /* XXX */
351 pcitag_t tag = pin;
352 pcireg_t reg, addr;
353 int off;
354
355 if (pci_get_capability(pc, tag, PCI_CAP_MSI0x05, &off, &reg) == 0)
356 panic("%s: no msi capability", __func__);
357
358 addr = 0xfee00000UL | (ci->ci_apicid << 12);
359
360 if (reg & PCI_MSI_MC_C640x00800000) {
361 pci_conf_write(pc, tag, off + PCI_MSI_MA0x04, addr);
362 pci_conf_write(pc, tag, off + PCI_MSI_MAU320x08, 0);
363 pci_conf_write(pc, tag, off + PCI_MSI_MD640x0c, vec);
364 } else {
365 pci_conf_write(pc, tag, off + PCI_MSI_MA0x04, addr);
366 pci_conf_write(pc, tag, off + PCI_MSI_MD320x08, vec);
367 }
368 pci_conf_write(pc, tag, off, reg | PCI_MSI_MC_MSIE0x00010000);
369}
370
371void
372msi_delroute(struct pic *pic, struct cpu_info *ci, int pin, int vec, int type)
373{
374 pci_chipset_tag_t pc = NULL((void *)0); /* XXX */
375 pcitag_t tag = pin;
376 pcireg_t reg;
377 int off;
378
379 if (pci_get_capability(pc, tag, PCI_CAP_MSI0x05, &off, &reg))
380 pci_conf_write(pc, tag, off, reg & ~PCI_MSI_MC_MSIE0x00010000);
381}
382
383int
384pci_intr_map_msi(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
385{
386 pci_chipset_tag_t pc = pa->pa_pc;
387 pcitag_t tag = pa->pa_tag;
388
389 if ((pa->pa_flags & PCI_FLAGS_MSI_ENABLED0x20) == 0 || mp_busses == NULL((void *)0) ||
390 pci_get_capability(pc, tag, PCI_CAP_MSI0x05, NULL((void *)0), NULL((void *)0)) == 0)
391 return 1;
392
393 ihp->tag = tag;
394 ihp->line = APIC_INT_VIA_MSG0x20000000;
395 ihp->pin = 0;
396 return 0;
397}
398
399void msix_hwmask(struct pic *, int);
400void msix_hwunmask(struct pic *, int);
401void msix_addroute(struct pic *, struct cpu_info *, int, int, int);
402void msix_delroute(struct pic *, struct cpu_info *, int, int, int);
403
404struct pic msix_pic = {
405 {0, {NULL((void *)0)}, NULL((void *)0), 0, "msix", NULL((void *)0), 0, 0},
406 PIC_MSI3,
407#ifdef MULTIPROCESSOR1
408 {},
409#endif
410 msix_hwmask,
411 msix_hwunmask,
412 msix_addroute,
413 msix_delroute,
414 NULL((void *)0),
415 ioapic_edge_stubs
416};
417
418/*
419 * We pack the MSI-X vector number into the lower 8 bits of the PCI
420 * tag and use that as the MSI-X "PIC" pin number. This allows us to
421 * address 256 MSI-X vectors which ought to be enough for anybody.
422 */
423#define PCI_MSIX_VEC_MASK0xff 0xff
424#define PCI_MSIX_VEC(pin)((pin) & 0xff) ((pin) & PCI_MSIX_VEC_MASK0xff)
425#define PCI_MSIX_TAG(pin)((pin) & ~0xff) ((pin) & ~PCI_MSIX_VEC_MASK0xff)
426#define PCI_MSIX_PIN(tag, vec)((tag) | (vec)) ((tag) | (vec))
427
428void
429msix_hwmask(struct pic *pic, int pin)
430{
431}
432
433void
434msix_hwunmask(struct pic *pic, int pin)
435{
436}
437
438void
439msix_addroute(struct pic *pic, struct cpu_info *ci, int pin, int vec, int type)
440{
441 pci_chipset_tag_t pc = NULL((void *)0); /* XXX */
442 bus_space_tag_t memt = X86_BUS_SPACE_MEM(&x86_bus_space_mem_ops); /* XXX */
443 bus_space_handle_t memh;
444 pcitag_t tag = PCI_MSIX_TAG(pin)((pin) & ~0xff);
445 int entry = PCI_MSIX_VEC(pin)((pin) & 0xff);
446 pcireg_t reg, addr;
447 uint32_t ctrl;
448 int off;
449
450 if (pci_get_capability(pc, tag, PCI_CAP_MSIX0x11, &off, &reg) == 0)
451 panic("%s: no msix capability", __func__);
452
453 KASSERT(entry <= PCI_MSIX_MC_TBLSZ(reg))((entry <= (((reg) & 0x07ff0000) >> 16)) ? (void
)0 : __assert("diagnostic ", "/usr/src/sys/arch/amd64/pci/pci_machdep.c"
, 453, "entry <= PCI_MSIX_MC_TBLSZ(reg)"))
;
454
455 if (pci_msix_table_map(pc, tag, memt, &memh))
456 panic("%s: cannot map registers", __func__);
457
458 addr = 0xfee00000UL | (ci->ci_apicid << 12);
459
460 bus_space_write_4(memt, memh, PCI_MSIX_MA(entry), addr)((memt)->write_4((memh), (((entry) * 16 + 0)), (addr)));
461 bus_space_write_4(memt, memh, PCI_MSIX_MAU32(entry), 0)((memt)->write_4((memh), (((entry) * 16 + 4)), (0)));
462 bus_space_write_4(memt, memh, PCI_MSIX_MD(entry), vec)((memt)->write_4((memh), (((entry) * 16 + 8)), (vec)));
463 bus_space_barrier(memt, memh, PCI_MSIX_MA(entry)((entry) * 16 + 0), 16,
464 BUS_SPACE_BARRIER_WRITE0x02);
465 ctrl = bus_space_read_4(memt, memh, PCI_MSIX_VC(entry))((memt)->read_4((memh), (((entry) * 16 + 12))));
466 bus_space_write_4(memt, memh, PCI_MSIX_VC(entry),((memt)->write_4((memh), (((entry) * 16 + 12)), (ctrl &
~0x00000001)))
467 ctrl & ~PCI_MSIX_VC_MASK)((memt)->write_4((memh), (((entry) * 16 + 12)), (ctrl &
~0x00000001)))
;
468
469 pci_msix_table_unmap(pc, tag, memt, memh);
470
471 pci_conf_write(pc, tag, off, reg | PCI_MSIX_MC_MSIXE0x80000000);
472}
473
474void
475msix_delroute(struct pic *pic, struct cpu_info *ci, int pin, int vec, int type)
476{
477 pci_chipset_tag_t pc = NULL((void *)0); /* XXX */
478 bus_space_tag_t memt = X86_BUS_SPACE_MEM(&x86_bus_space_mem_ops); /* XXX */
479 bus_space_handle_t memh;
480 pcitag_t tag = PCI_MSIX_TAG(pin)((pin) & ~0xff);
481 int entry = PCI_MSIX_VEC(pin)((pin) & 0xff);
482 pcireg_t reg;
483 uint32_t ctrl;
484
485 if (pci_get_capability(pc, tag, PCI_CAP_MSIX0x11, NULL((void *)0), &reg) == 0)
486 return;
487
488 KASSERT(entry <= PCI_MSIX_MC_TBLSZ(reg))((entry <= (((reg) & 0x07ff0000) >> 16)) ? (void
)0 : __assert("diagnostic ", "/usr/src/sys/arch/amd64/pci/pci_machdep.c"
, 488, "entry <= PCI_MSIX_MC_TBLSZ(reg)"))
;
489
490 if (pci_msix_table_map(pc, tag, memt, &memh))
491 return;
492
493 ctrl = bus_space_read_4(memt, memh, PCI_MSIX_VC(entry))((memt)->read_4((memh), (((entry) * 16 + 12))));
494 bus_space_write_4(memt, memh, PCI_MSIX_VC(entry),((memt)->write_4((memh), (((entry) * 16 + 12)), (ctrl | 0x00000001
)))
495 ctrl | PCI_MSIX_VC_MASK)((memt)->write_4((memh), (((entry) * 16 + 12)), (ctrl | 0x00000001
)))
;
496
497 pci_msix_table_unmap(pc, tag, memt, memh);
498}
499
500int
501pci_intr_map_msix(struct pci_attach_args *pa, int vec, pci_intr_handle_t *ihp)
502{
503 pci_chipset_tag_t pc = pa->pa_pc;
504 pcitag_t tag = pa->pa_tag;
505 pcireg_t reg;
506
507 KASSERT(PCI_MSIX_VEC(vec) == vec)((((vec) & 0xff) == vec) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/arch/amd64/pci/pci_machdep.c", 507, "PCI_MSIX_VEC(vec) == vec"
))
;
508
509 if ((pa->pa_flags & PCI_FLAGS_MSI_ENABLED0x20) == 0 || mp_busses == NULL((void *)0) ||
510 pci_get_capability(pc, tag, PCI_CAP_MSIX0x11, NULL((void *)0), &reg) == 0)
511 return 1;
512
513 if (vec > PCI_MSIX_MC_TBLSZ(reg)(((reg) & 0x07ff0000) >> 16))
514 return 1;
515
516 ihp->tag = PCI_MSIX_PIN(tag, vec)((tag) | (vec));
517 ihp->line = APIC_INT_VIA_MSGX0x40000000;
518 ihp->pin = 0;
519 return 0;
520}
521
522int
523pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
524{
525 int pin = pa->pa_rawintrpin;
526 int line = pa->pa_intrline;
527#if NIOAPIC1 > 0
528 struct mp_intr_map *mip;
1
'mip' declared without an initial value
529 int bus, dev, func;
530#endif
531
532 if (pin == 0) {
2
Assuming 'pin' is not equal to 0
3
Taking false branch
533 /* No IRQ used. */
534 goto bad;
535 }
536
537 if (pin > PCI_INTERRUPT_PIN_MAX0x04) {
4
Assuming 'pin' is <= PCI_INTERRUPT_PIN_MAX
5
Taking false branch
538 printf("pci_intr_map: bad interrupt pin %d\n", pin);
539 goto bad;
540 }
541
542 ihp->tag = pa->pa_tag;
543 ihp->line = line;
544 ihp->pin = pin;
545
546#if NIOAPIC1 > 0
547 pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &dev, &func);
548
549 if (mp_busses != NULL((void *)0)) {
6
Assuming 'mp_busses' is equal to NULL
7
Taking false branch
550 int mpspec_pin = (dev << 2) | (pin - 1);
551
552 if (bus < mp_nbusses) {
553 for (mip = mp_busses[bus].mb_intrs;
554 mip != NULL((void *)0); mip = mip->next) {
555 if (&mp_busses[bus] == mp_isa_bus ||
556 &mp_busses[bus] == mp_eisa_bus)
557 continue;
558 if (mip->bus_pin == mpspec_pin) {
559 ihp->line = mip->ioapic_ih | line;
560 return 0;
561 }
562 }
563 }
564
565 if (pa->pa_bridgetag) {
566 int swizpin = PPB_INTERRUPT_SWIZZLE(pin, dev)((((pin) + (dev) - 1) % 4) + 1);
567 if (pa->pa_bridgeih[swizpin - 1].line != -1) {
568 ihp->line = pa->pa_bridgeih[swizpin - 1].line;
569 ihp->line |= line;
570 return 0;
571 }
572 }
573 /*
574 * No explicit PCI mapping found. This is not fatal,
575 * we'll try the ISA (or possibly EISA) mappings next.
576 */
577 }
578#endif
579
580 /*
581 * Section 6.2.4, `Miscellaneous Functions', says that 255 means
582 * `unknown' or `no connection' on a PC. We assume that a device with
583 * `no connection' either doesn't have an interrupt (in which case the
584 * pin number should be 0, and would have been noticed above), or
585 * wasn't configured by the BIOS (in which case we punt, since there's
586 * no real way we can know how the interrupt lines are mapped in the
587 * hardware).
588 *
589 * XXX
590 * Since IRQ 0 is only used by the clock, and we can't actually be sure
591 * that the BIOS did its job, we also recognize that as meaning that
592 * the BIOS has not configured the device.
593 */
594 if (line == 0 || line == X86_PCI_INTERRUPT_LINE_NO_CONNECTION0xff)
8
Assuming 'line' is not equal to 0
9
Assuming 'line' is not equal to X86_PCI_INTERRUPT_LINE_NO_CONNECTION
10
Taking false branch
595 goto bad;
596
597 if (line >= NUM_LEGACY_IRQS16) {
11
Assuming 'line' is < NUM_LEGACY_IRQS
12
Taking false branch
598 printf("pci_intr_map: bad interrupt line %d\n", line);
599 goto bad;
600 }
601 if (line == 2) {
13
Assuming 'line' is equal to 2
14
Taking true branch
602 printf("pci_intr_map: changed line 2 to line 9\n");
603 line = 9;
604 }
605
606#if NIOAPIC1 > 0
607 if (mp_busses != NULL((void *)0)) {
15
Assuming 'mp_busses' is not equal to NULL
16
Taking true branch
608 if (mip == NULL((void *)0) && mp_isa_bus) {
17
The left operand of '==' is a garbage value
609 for (mip = mp_isa_bus->mb_intrs; mip != NULL((void *)0);
610 mip = mip->next) {
611 if (mip->bus_pin == line) {
612 ihp->line = mip->ioapic_ih | line;
613 return 0;
614 }
615 }
616 }
617#if NEISA > 0
618 if (mip == NULL((void *)0) && mp_eisa_bus) {
619 for (mip = mp_eisa_bus->mb_intrs; mip != NULL((void *)0);
620 mip = mip->next) {
621 if (mip->bus_pin == line) {
622 ihp->line = mip->ioapic_ih | line;
623 return 0;
624 }
625 }
626 }
627#endif
628 if (mip == NULL((void *)0)) {
629 printf("pci_intr_map: "
630 "bus %d dev %d func %d pin %d; line %d\n",
631 bus, dev, func, pin, line);
632 printf("pci_intr_map: no MP mapping found\n");
633 }
634 }
635#endif
636
637 return 0;
638
639bad:
640 ihp->line = -1;
641 return 1;
642}
643
644const char *
645pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih)
646{
647 static char irqstr[64];
648
649 if (ih.line == 0)
650 panic("pci_intr_string: bogus handle 0x%x", ih.line);
651
652 if (ih.line & APIC_INT_VIA_MSG0x20000000)
653 return ("msi");
654 if (ih.line & APIC_INT_VIA_MSGX0x40000000)
655 return ("msix");
656
657#if NIOAPIC1 > 0
658 if (ih.line & APIC_INT_VIA_APIC0x10000000)
659 snprintf(irqstr, sizeof(irqstr), "apic %d int %d",
660 APIC_IRQ_APIC(ih.line)((ih.line & 0x00ff0000) >> 16), APIC_IRQ_PIN(ih.line)((ih.line & 0x0000ff00) >> 8));
661 else
662 snprintf(irqstr, sizeof(irqstr), "irq %d",
663 pci_intr_line(pc, ih)((ih.line) & 0xff));
664#else
665 snprintf(irqstr, sizeof(irqstr), "irq %d", pci_intr_line(pc, ih)((ih.line) & 0xff));
666#endif
667 return (irqstr);
668}
669
670#include "acpiprt.h"
671#if NACPIPRT1 > 0
672void acpiprt_route_interrupt(int bus, int dev, int pin);
673#endif
674
675void *
676pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level,
677 int (*func)(void *), void *arg, const char *what)
678{
679 return pci_intr_establish_cpu(pc, ih, level, NULL((void *)0), func, arg, what);
680}
681
682void *
683pci_intr_establish_cpu(pci_chipset_tag_t pc, pci_intr_handle_t ih,
684 int level, struct cpu_info *ci,
685 int (*func)(void *), void *arg, const char *what)
686{
687 int pin, irq;
688 int bus, dev;
689 pcitag_t tag = ih.tag;
690 struct pic *pic;
691
692 if (ih.line & APIC_INT_VIA_MSG0x20000000) {
693 return intr_establish(-1, &msi_pic, tag, IST_PULSE1, level,
694 ci, func, arg, what);
695 }
696 if (ih.line & APIC_INT_VIA_MSGX0x40000000) {
697 return intr_establish(-1, &msix_pic, tag, IST_PULSE1, level,
698 ci, func, arg, what);
699 }
700
701 pci_decompose_tag(pc, ih.tag, &bus, &dev, NULL((void *)0));
702#if NACPIPRT1 > 0
703 acpiprt_route_interrupt(bus, dev, ih.pin);
704#endif
705
706 pic = &i8259_pic;
707 pin = irq = ih.line;
708
709#if NIOAPIC1 > 0
710 if (ih.line & APIC_INT_VIA_APIC0x10000000) {
711 pic = (struct pic *)ioapic_find(APIC_IRQ_APIC(ih.line)((ih.line & 0x00ff0000) >> 16));
712 if (pic == NULL((void *)0)) {
713 printf("pci_intr_establish: bad ioapic %d\n",
714 APIC_IRQ_APIC(ih.line)((ih.line & 0x00ff0000) >> 16));
715 return NULL((void *)0);
716 }
717 pin = APIC_IRQ_PIN(ih.line)((ih.line & 0x0000ff00) >> 8);
718 irq = APIC_IRQ_LEGACY_IRQ(ih.line)((ih.line) & 0xff);
719 if (irq < 0 || irq >= NUM_LEGACY_IRQS16)
720 irq = -1;
721 }
722#endif
723
724 return intr_establish(irq, pic, pin, IST_LEVEL3, level, ci,
725 func, arg, what);
726}
727
728void
729pci_intr_disestablish(pci_chipset_tag_t pc, void *cookie)
730{
731 intr_disestablish(cookie);
732}
733
734struct extent *pciio_ex;
735struct extent *pcimem_ex;
736struct extent *pcibus_ex;
737
738void
739pci_init_extents(void)
740{
741 bios_memmap_t *bmp;
742 u_int64_t size;
743
744 if (pciio_ex == NULL((void *)0)) {
745 /*
746 * We only have 64K of addressable I/O space.
747 * However, since BARs may contain garbage, we cover
748 * the full 32-bit address space defined by PCI of
749 * which we only make the first 64K available.
750 */
751 pciio_ex = extent_create("pciio", 0, 0xffffffff, M_DEVBUF2,
752 NULL((void *)0), 0, EX_NOWAIT0x0000 | EX_FILLED0x0100);
753 if (pciio_ex == NULL((void *)0))
754 return;
755 extent_free(pciio_ex, 0, 0x10000, EX_NOWAIT0x0000);
756 }
757
758 if (pcimem_ex == NULL((void *)0)) {
759 /*
760 * Cover the 36-bit address space addressable by PAE
761 * here. As long as vendors continue to support
762 * 32-bit operating systems, we should never see BARs
763 * outside that region.
764 *
765 * Dell 13G servers have important devices outside the
766 * 36-bit address space. Until we can extract the address
767 * ranges from ACPI, expand the allowed range to suit.
768 */
769 pcimem_ex = extent_create("pcimem", 0, 0xffffffffffffffffUL,
770 M_DEVBUF2, NULL((void *)0), 0, EX_NOWAIT0x0000);
771 if (pcimem_ex == NULL((void *)0))
772 return;
773 extent_alloc_region(pcimem_ex, 0x40000000000UL,
774 0xfffffc0000000000UL, EX_NOWAIT0x0000);
775
776 for (bmp = bios_memmap; bmp->type != BIOS_MAP_END0x00; bmp++) {
777 /*
778 * Ignore address space beyond 4G.
779 */
780 if (bmp->addr >= 0x100000000ULL)
781 continue;
782 size = bmp->size;
783 if (bmp->addr + size >= 0x100000000ULL)
784 size = 0x100000000ULL - bmp->addr;
785
786 /* Ignore zero-sized regions. */
787 if (size == 0)
788 continue;
789
790 if (extent_alloc_region(pcimem_ex, bmp->addr, size,
791 EX_NOWAIT0x0000))
792 printf("memory map conflict 0x%llx/0x%llx\n",
793 bmp->addr, bmp->size);
794 }
795
796 /* Take out the video buffer area and BIOS areas. */
797 extent_alloc_region(pcimem_ex, IOM_BEGIN0x0a0000, IOM_SIZE(0x100000 - 0x0a0000),
798 EX_CONFLICTOK0x0080 | EX_NOWAIT0x0000);
799 }
800
801 if (pcibus_ex == NULL((void *)0)) {
802 pcibus_ex = extent_create("pcibus", 0, 0xff, M_DEVBUF2,
803 NULL((void *)0), 0, EX_NOWAIT0x0000);
804 }
805}
806
807int
808pci_probe_device_hook(pci_chipset_tag_t pc, struct pci_attach_args *pa)
809{
810#if NACPIDMAR1 > 0
811 acpidmar_pci_hook(pc, pa);
812#endif
813 return 0;
814}
815
816#if NACPI1 > 0
817void acpi_pci_match(struct device *, struct pci_attach_args *);
818pcireg_t acpi_pci_min_powerstate(pci_chipset_tag_t, pcitag_t);
819void acpi_pci_set_powerstate(pci_chipset_tag_t, pcitag_t, int, int);
820#endif
821
822void
823pci_dev_postattach(struct device *dev, struct pci_attach_args *pa)
824{
825#if NACPI1 > 0
826 acpi_pci_match(dev, pa);
827#endif
828}
829
830pcireg_t
831pci_min_powerstate(pci_chipset_tag_t pc, pcitag_t tag)
832{
833#if NACPI1 > 0
834 return acpi_pci_min_powerstate(pc, tag);
835#else
836 return pci_get_powerstate(pc, tag);
837#endif
838}
839
840void
841pci_set_powerstate_md(pci_chipset_tag_t pc, pcitag_t tag, int state, int pre)
842{
843#if NACPI1 > 0
844 acpi_pci_set_powerstate(pc, tag, state, pre);
845#endif
846}