Bug Summary

File:dev/pci/amas.c
Warning:line 255, column 2
Value stored to 'elimit' is never read

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 amas.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/dev/pci/amas.c
1/* $OpenBSD: amas.c,v 1.6 2020/01/04 01:34:24 jsg Exp $ */
2
3/*
4 * Copyright (c) 2009 Ariane van der Steldt <ariane@stack.nl>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/*
20 * Device: amas (AMD memory access/address switch).
21 *
22 * Driver for the amd athlon/opteron 64 address map.
23 * This device is integrated in 64-bit Athlon and Opteron cpus
24 * and contains mappings for memory to processor nodes.
25 */
26
27#include <dev/pci/amas.h>
28
29#include <sys/param.h>
30#include <sys/systm.h>
31#include <sys/device.h>
32
33#include <dev/pci/pcivar.h>
34#include <dev/pci/pcireg.h>
35#include <dev/pci/pcidevs.h>
36
37int amas_match(struct device*, void*, void*);
38void amas_attach(struct device*, struct device*, void*);
39
40/*
41 * Amas device layout:
42 *
43 * - base/limit registers (on 0x0f, 0x10, 0x11)
44 * - extended base/limit registers (on 0x10)
45 *
46 * 0x0f, 0x10 support up to 8 nodes
47 * 0x11 supports up to 1 nodes
48 *
49 * base/limit registers use bits [31..16] to indicate address [39..24]
50 * extended base/limit registers use bits [7..0] to indicate address [47..40]
51 * base/limit addresses need to be shifted <<24 for memory address
52 * extended base/limit addresses need to be shifted <<40 for memory address
53 */
54
55#define AMAS_REG_BASE(node)(0x0040 + 0x08 * (node)) (0x0040 + 0x08 * (node))
56#define AMAS_REG_LIMIT(node)(0x0044 + 0x08 * (node)) (0x0044 + 0x08 * (node))
57#define AMAS_REG_EXTBASE(node)(0x0140 + 0x08 * (node)) (0x0140 + 0x08 * (node))
58#define AMAS_REG_EXTLIMIT(node)(0x0144 + 0x08 * (node)) (0x0144 + 0x08 * (node))
59
60#define AMAS_REG_BL_ADDR(reg)(((reg) >> 16) & 0xffff) (((reg) >> 16) & 0xffff)
61#define AMAS_REG_EBL_ADDR(ereg)((ereg) & 0xff) ((ereg) & 0xff)
62
63#define AMAS_REG_BL_SHIFT(24) (24)
64#define AMAS_REG_EBL_SHIFT(40) (40)
65
66#define AMAS_REG_BL_PGSHIFT((24) - 12) (AMAS_REG_BL_SHIFT(24) - PAGE_SHIFT12)
67#define AMAS_REG_EBL_PGSHIFT((40) - 12) (AMAS_REG_EBL_SHIFT(40) - PAGE_SHIFT12)
68
69/*
70 * Convert an address in amas to a page number.
71 *
72 * The device uses an inclusive mapping, where the upper bound address
73 * must be all 1's after shifting.
74 * The device driver uses C-style array indices, hence the +1 in the _LIMIT
75 * macro.
76 */
77#define AMAS_ADDR2PAGE_BASE(base, ebase)(((base) << ((24) - 12)) | ((ebase) << ((40) - 12
)))
\
78 (((base) << AMAS_REG_BL_PGSHIFT((24) - 12)) | ((ebase) << AMAS_REG_EBL_PGSHIFT((40) - 12)))
79#define AMAS_ADDR2PAGE_LIMIT(base, ebase)(((base + 1) << ((24) - 12)) | ((ebase) << ((40) -
12)))
\
80 (((base + 1) << AMAS_REG_BL_PGSHIFT((24) - 12)) | ((ebase) << AMAS_REG_EBL_PGSHIFT((40) - 12)))
81
82/*
83 * Node and interleave description.
84 * - base contains node selection [10..8] (on 0x0f, 0x10)
85 * - limit contains node selection bitmask [10..8] (on 0x0f, 0x10)
86 * - limit contains destination node [2..0] (on 0x0f, 0x10)
87 */
88#define AMAS_DST_NODE(base, limit)((limit) & 0x07) ((limit) & 0x07)
89#define AMAS_INTL_ENABLE(base, limit)(((base) >> 8) & 0x07) (((base) >> 8) & 0x07)
90#define AMAS_INTL_SELECTOR(base, limit)(((limit) >> 8) & 0x07) (((limit) >> 8) & 0x07)
91
92/*
93 * Defines for family.
94 * Corresponds to the amas_feature[] constant below.
95 */
96#define AMAS_FAM_0Fh(0) (0)
97#define AMAS_FAM_10h(1) (1)
98#define AMAS_FAM_11h(2) (2)
99
100/*
101 * Feature tests.
102 *
103 * 0x11 supports at max 1 node, 0x0f and 0x10 support up to 8 nodes.
104 * 0x11 has extended address registers.
105 * 0x0f, 0x10 can interleave memory.
106 */
107struct amas_feature_t {
108 int maxnodes;
109 int can_intl;
110 int has_extended_bl;
111};
112static const struct amas_feature_t amas_feature[] = {
113 /* Family 0x0f */
114 { 8, 1, 0 },
115 /* Family 0x10 */
116 { 8, 1, 1 },
117 /* Family 0x11 */
118 { 1, 0, 0 },
119};
120
121/* Probe code. */
122struct cfattach amas_ca = {
123 sizeof(struct amas_softc),
124 amas_match,
125 amas_attach
126};
127
128struct cfdriver amas_cd = {
129 NULL((void *)0),
130 "amas",
131 DV_DULL
132};
133
134const struct pci_matchid amas_devices[] = {
135 { PCI_VENDOR_AMD0x1022, PCI_PRODUCT_AMD_0F_ADDR0x1101 },
136 { PCI_VENDOR_AMD0x1022, PCI_PRODUCT_AMD_10_ADDR0x1201 },
137 { PCI_VENDOR_AMD0x1022, PCI_PRODUCT_AMD_11_ADDR0x1301 },
138};
139
140int
141amas_match(struct device *parent, void *match, void *aux)
142{
143 struct pci_attach_args* pa = aux;
144
145 if (pci_matchbyid(pa, amas_devices, nitems(amas_devices)(sizeof((amas_devices)) / sizeof((amas_devices)[0]))))
146 return 2; /* override pchb */
147 return 0;
148}
149
150void
151amas_attach(struct device *parent, struct device *self, void *aux)
152{
153 struct pci_attach_args *pa = aux;
154 struct amas_softc *amas = (struct amas_softc*)self;
155#ifdef DEBUG
156 paddr_t start_pg, end_pg;
157 int nodes, i;
158#endif /* DEBUG */
159
160 amas->pa_tag = pa->pa_tag;
161 amas->pa_pc = pa->pa_pc;
162
163 switch (PCI_PRODUCT(pa->pa_id)(((pa->pa_id) >> 16) & 0xffff)) {
164 case PCI_PRODUCT_AMD_0F_ADDR0x1101:
165 amas->family = AMAS_FAM_0Fh(0);
166 break;
167 case PCI_PRODUCT_AMD_10_ADDR0x1201:
168 amas->family = AMAS_FAM_10h(1);
169 break;
170 case PCI_PRODUCT_AMD_11_ADDR0x1301:
171 amas->family = AMAS_FAM_11h(2);
172 break;
173 }
174
175#ifdef DEBUG
176 nodes = amas_intl_nodes(amas);
177
178 printf(":");
179 if (nodes != 0) {
180 printf(" interleaved");
181 } else {
182 for (i = 0; i < AMAS_MAX_NODES(8); i++) {
183 amas_get_pagerange(amas, i, &start_pg, &end_pg);
184
185 if (!(start_pg == 0 && end_pg == 0))
186 printf(" [%#lx, %#lx]", start_pg, end_pg);
187 }
188 }
189#endif /* DEBUG */
190 printf("\n");
191
192 return;
193}
194
195/*
196 * Returns the number of nodes across which the memory is interleaved.
197 * Returns 0 if the memory is not interleaved.
198 */
199int
200amas_intl_nodes(struct amas_softc *amas)
201{
202 pcireg_t base_reg, limit_reg;
203 int mask;
204
205 if (!amas_feature[amas->family].can_intl)
206 return 0;
207
208 /*
209 * Use node 0 on amas device to find interleave information.
210 * Node 0 is always present.
211 */
212
213 base_reg = pci_conf_read(amas->pa_pc, amas->pa_tag, AMAS_REG_BASE(0)(0x0040 + 0x08 * (0)));
214 limit_reg = pci_conf_read(amas->pa_pc, amas->pa_tag, AMAS_REG_LIMIT(0)(0x0044 + 0x08 * (0)));
215 mask = AMAS_INTL_ENABLE(base_reg, limit_reg)(((base_reg) >> 8) & 0x07);
216
217 return mask == 0 ? 0 : mask + 1;
218}
219
220/*
221 * Returns the range of memory that is contained on the given node.
222 * If the memory is interleaved, the result is undefined.
223 *
224 * The range is written in {start,end}_pg_idx.
225 * Note that these are page numbers and that these use array indices:
226 * pages are in this range if start <= pg_no < end.
227 *
228 * This device supports at most 8 nodes.
229 */
230void
231amas_get_pagerange(struct amas_softc *amas, int node,
232 paddr_t *start_pg_idx, paddr_t *end_pg_idx)
233{
234 pcireg_t base, ebase, limit, elimit;
235 paddr_t base_addr, ebase_addr, limit_addr, elimit_addr;
236
237 /* Sanity check: max AMAS_MAX_NODES supported. */
238 KASSERT(node >= 0 && node < AMAS_MAX_NODES)((node >= 0 && node < (8)) ? (void)0 : __assert
("diagnostic ", "/usr/src/sys/dev/pci/amas.c", 238, "node >= 0 && node < AMAS_MAX_NODES"
))
;
239
240 if (node >= amas_feature[amas->family].maxnodes) {
241 /* Unsupported node: bail out early. */
242 *start_pg_idx = 0;
243 *end_pg_idx = 0;
244 return;
245 }
246
247 base = pci_conf_read(amas->pa_pc, amas->pa_tag,
248 AMAS_REG_BASE(node)(0x0040 + 0x08 * (node)));
249 limit = pci_conf_read(amas->pa_pc, amas->pa_tag,
250 AMAS_REG_LIMIT(node)(0x0044 + 0x08 * (node)));
251 base_addr = AMAS_REG_BL_ADDR(base)(((base) >> 16) & 0xffff);
252 limit_addr = AMAS_REG_BL_ADDR(limit)(((limit) >> 16) & 0xffff);
253
254 ebase = 0;
255 elimit = 0;
Value stored to 'elimit' is never read
256 ebase_addr = 0;
257 elimit_addr = 0;
258#if 0 /* Needs extended pci registers. */
259 if (amas_feature[amas->family].has_extended_bl) {
260 ebase = pci_conf_read(amas->pa_pc, amas->pa_tag,
261 AMAS_REG_EXTBASE(node)(0x0140 + 0x08 * (node)));
262 elimit = pci_conf_read(amas->pa_pc, amas->pa_tag,
263 AMAS_REG_EXTLIMIT(node)(0x0144 + 0x08 * (node)));
264 ebase_addr = AMAS_REG_EBL_ADDR(ebase)((ebase) & 0xff);
265 elimit_addr = AMAS_REG_EBL_ADDR(elimit)((elimit) & 0xff);
266 }
267#endif /* 0 */
268
269 if (ebase_addr > elimit_addr ||
270 (ebase_addr == elimit_addr && base_addr >= limit_addr)) {
271 /* no memory present */
272 *start_pg_idx = 0;
273 *end_pg_idx = 0;
274 return;
275 }
276
277 /* Guaranteed by spec. */
278 KASSERT(node == AMAS_DST_NODE(base, limit))((node == ((limit) & 0x07)) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/dev/pci/amas.c", 278, "node == AMAS_DST_NODE(base, limit)"
))
;
279
280 *start_pg_idx = AMAS_ADDR2PAGE_BASE(base_addr, ebase_addr)(((base_addr) << ((24) - 12)) | ((ebase_addr) << (
(40) - 12)))
;
281 *end_pg_idx = AMAS_ADDR2PAGE_LIMIT(limit_addr, elimit_addr)(((limit_addr + 1) << ((24) - 12)) | ((elimit_addr) <<
((40) - 12)))
;
282 return;
283}