Bug Summary

File:arch/amd64/amd64/powernow-k8.c
Warning:line 445, column 10
Although the value stored to 'p' is used in the enclosing expression, the value is never actually read from 'p'

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 powernow-k8.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/amd64/powernow-k8.c
1/* $OpenBSD: powernow-k8.c,v 1.28 2018/01/14 00:33:09 bluhm Exp $ */
2/*
3 * Copyright (c) 2004 Martin Végiard.
4 * Copyright (c) 2004-2005 Bruno Ducrot
5 * Copyright (c) 2004 FUKUDA Nobuhiko <nfukuda@spa.is.uec.ac.jp>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27/* AMD POWERNOW K8 driver */
28
29#include <sys/param.h>
30#include <sys/systm.h>
31#include <sys/malloc.h>
32#include <sys/sysctl.h>
33
34#include <dev/isa/isareg.h>
35#include <amd64/include/isa_machdep.h>
36
37#include <machine/cpu.h>
38#include <machine/cpufunc.h>
39#include <machine/bus.h>
40
41#include "acpicpu.h"
42
43#if NACPICPU1 > 0
44#include <dev/acpi/acpidev.h>
45#endif
46
47#define BIOS_START0xe0000 0xe0000
48#define BIOS_LEN0x20000 0x20000
49
50extern int setperf_prio;
51extern int perflevel;
52
53/*
54 * MSRs and bits used by PowerNow technology
55 */
56#define MSR_AMDK7_FIDVID_CTL0xc0010041 0xc0010041
57#define MSR_AMDK7_FIDVID_STATUS0xc0010042 0xc0010042
58
59/* Bitfields used by K8 */
60
61#define PN8_CTR_FID(x)((x) & 0x3f) ((x) & 0x3f)
62#define PN8_CTR_VID(x)(((x) & 0x1f) << 8) (((x) & 0x1f) << 8)
63#define PN8_CTR_PENDING(x)(((x) & 1) << 32) (((x) & 1) << 32)
64
65#define PN8_STA_CFID(x)((x) & 0x3f) ((x) & 0x3f)
66#define PN8_STA_SFID(x)(((x) >> 8) & 0x3f) (((x) >> 8) & 0x3f)
67#define PN8_STA_MFID(x)(((x) >> 16) & 0x3f) (((x) >> 16) & 0x3f)
68#define PN8_STA_PENDING(x)(((x) >> 31) & 0x01) (((x) >> 31) & 0x01)
69#define PN8_STA_CVID(x)(((x) >> 32) & 0x1f) (((x) >> 32) & 0x1f)
70#define PN8_STA_SVID(x)(((x) >> 40) & 0x1f) (((x) >> 40) & 0x1f)
71#define PN8_STA_MVID(x)(((x) >> 48) & 0x1f) (((x) >> 48) & 0x1f)
72
73/* Reserved1 to PowerNow K8 configuration */
74#define PN8_PSB_TO_RVO(x)((x) & 0x03) ((x) & 0x03)
75#define PN8_PSB_TO_IRT(x)(((x) >> 2) & 0x03) (((x) >> 2) & 0x03)
76#define PN8_PSB_TO_MVS(x)(((x) >> 4) & 0x03) (((x) >> 4) & 0x03)
77#define PN8_PSB_TO_BATT(x)(((x) >> 6) & 0x03) (((x) >> 6) & 0x03)
78
79/* ACPI ctr_val status register to PowerNow K8 configuration */
80#define PN8_ACPI_CTRL_TO_FID(x)((x) & 0x3f) ((x) & 0x3f)
81#define PN8_ACPI_CTRL_TO_VID(x)(((x) >> 6) & 0x1f) (((x) >> 6) & 0x1f)
82#define PN8_ACPI_CTRL_TO_VST(x)(((x) >> 11) & 0x1f) (((x) >> 11) & 0x1f)
83#define PN8_ACPI_CTRL_TO_MVS(x)(((x) >> 18) & 0x03) (((x) >> 18) & 0x03)
84#define PN8_ACPI_CTRL_TO_PLL(x)(((x) >> 20) & 0x7f) (((x) >> 20) & 0x7f)
85#define PN8_ACPI_CTRL_TO_RVO(x)(((x) >> 28) & 0x03) (((x) >> 28) & 0x03)
86#define PN8_ACPI_CTRL_TO_IRT(x)(((x) >> 30) & 0x03) (((x) >> 30) & 0x03)
87
88#define PN8_PSS_CFID(x)((x) & 0x3f) ((x) & 0x3f)
89#define PN8_PSS_CVID(x)(((x) >> 6) & 0x1f) (((x) >> 6) & 0x1f)
90
91#define WRITE_FIDVID(fid, vid, ctrl)wrmsr(0xc0010041, (((ctrl) << 32) | (1ULL << 16) |
((vid) << 8) | (fid)))
\
92 wrmsr(MSR_AMDK7_FIDVID_CTL0xc0010041, \
93 (((ctrl) << 32) | (1ULL << 16) | ((vid) << 8) | (fid)))
94
95
96#define COUNT_OFF_IRT(irt)(*delay_func)(10 * (1 << (irt))) DELAY(10 * (1 << (irt)))(*delay_func)(10 * (1 << (irt)))
97#define COUNT_OFF_VST(vst)(*delay_func)(20 * (vst)) DELAY(20 * (vst))(*delay_func)(20 * (vst))
98
99#define FID_TO_VCO_FID(fid)(((fid) < 8) ? (8 + ((fid) << 1)) : (fid)) \
100 (((fid) < 8) ? (8 + ((fid) << 1)) : (fid))
101
102#define POWERNOW_MAX_STATES16 16
103
104struct k8pnow_state {
105 int freq;
106 uint8_t fid;
107 uint8_t vid;
108};
109
110struct k8pnow_cpu_state {
111 struct k8pnow_state state_table[POWERNOW_MAX_STATES16];
112 unsigned int n_states;
113 unsigned int sgtc;
114 unsigned int vst;
115 unsigned int mvs;
116 unsigned int pll;
117 unsigned int rvo;
118 unsigned int irt;
119 int low;
120};
121
122struct psb_s {
123 char signature[10]; /* AMDK7PNOW! */
124 uint8_t version;
125 uint8_t flags;
126 uint16_t ttime; /* Min Settling time */
127 uint8_t reserved;
128 uint8_t n_pst;
129};
130
131struct pst_s {
132 uint32_t cpuid;
133 uint8_t pll;
134 uint8_t fid;
135 uint8_t vid;
136 uint8_t n_states;
137};
138
139struct k8pnow_cpu_state *k8pnow_current_state;
140
141int k8pnow_read_pending_wait(uint64_t *);
142int k8pnow_decode_pst(struct k8pnow_cpu_state *, uint8_t *);
143int k8pnow_states(struct k8pnow_cpu_state *, uint32_t, unsigned int, unsigned int);
144void k8pnow_transition(struct k8pnow_cpu_state *e, int);
145
146#if NACPICPU1 > 0
147int k8pnow_acpi_init(struct k8pnow_cpu_state *, uint64_t);
148void k8pnow_acpi_pss_changed(struct acpicpu_pss *, int);
149int k8pnow_acpi_states(struct k8pnow_cpu_state *, struct acpicpu_pss *, int,
150 uint64_t);
151#endif
152
153int
154k8pnow_read_pending_wait(uint64_t *status)
155{
156 unsigned int i = 100000;
157
158 while (i--) {
159 *status = rdmsr(MSR_AMDK7_FIDVID_STATUS0xc0010042);
160 if (!PN8_STA_PENDING(*status)(((*status) >> 31) & 0x01))
161 return 0;
162
163 }
164 printf("k8pnow_read_pending_wait: change pending stuck.\n");
165 return 1;
166}
167
168void
169k8_powernow_setperf(int level)
170{
171 unsigned int i;
172 struct k8pnow_cpu_state *cstate;
173
174 cstate = k8pnow_current_state;
175
176 i = ((level * cstate->n_states) + 1) / 101;
177 if (i >= cstate->n_states)
178 i = cstate->n_states - 1;
179
180 k8pnow_transition(cstate, i);
181}
182
183void
184k8pnow_transition(struct k8pnow_cpu_state *cstate, int level)
185{
186 uint64_t status;
187 int cfid, cvid, fid = 0, vid = 0;
188 int rvo;
189 u_int val;
190
191 /*
192 * We dont do a k8pnow_read_pending_wait here, need to ensure that the
193 * change pending bit isn't stuck,
194 */
195 status = rdmsr(MSR_AMDK7_FIDVID_STATUS0xc0010042);
196 if (PN8_STA_PENDING(status)(((status) >> 31) & 0x01))
197 return;
198 cfid = PN8_STA_CFID(status)((status) & 0x3f);
199 cvid = PN8_STA_CVID(status)(((status) >> 32) & 0x1f);
200
201 fid = cstate->state_table[level].fid;
202 vid = cstate->state_table[level].vid;
203
204 if (fid == cfid && vid == cvid)
205 return;
206
207 /*
208 * Phase 1: Raise core voltage to requested VID if frequency is
209 * going up.
210 */
211 while (cvid > vid) {
212 val = cvid - (1 << cstate->mvs);
213 WRITE_FIDVID(cfid, (val > 0) ? val : 0, 1ULL)wrmsr(0xc0010041, (((1ULL) << 32) | (1ULL << 16) |
(((val > 0) ? val : 0) << 8) | (cfid)))
;
214 if (k8pnow_read_pending_wait(&status))
215 return;
216 cvid = PN8_STA_CVID(status)(((status) >> 32) & 0x1f);
217 COUNT_OFF_VST(cstate->vst)(*delay_func)(20 * (cstate->vst));
218 }
219
220 /* ... then raise to voltage + RVO (if required) */
221 for (rvo = cstate->rvo; rvo > 0 && cvid > 0; --rvo) {
222 /* XXX It's not clear from spec if we have to do that
223 * in 0.25 step or in MVS. Therefore do it as it's done
224 * under Linux */
225 WRITE_FIDVID(cfid, cvid - 1, 1ULL)wrmsr(0xc0010041, (((1ULL) << 32) | (1ULL << 16) |
((cvid - 1) << 8) | (cfid)))
;
226 if (k8pnow_read_pending_wait(&status))
227 return;
228 cvid = PN8_STA_CVID(status)(((status) >> 32) & 0x1f);
229 COUNT_OFF_VST(cstate->vst)(*delay_func)(20 * (cstate->vst));
230 }
231
232 /* Phase 2: change to requested core frequency */
233 if (cfid != fid) {
234 int vco_fid, vco_cfid;
235
236 vco_fid = FID_TO_VCO_FID(fid)(((fid) < 8) ? (8 + ((fid) << 1)) : (fid));
237 vco_cfid = FID_TO_VCO_FID(cfid)(((cfid) < 8) ? (8 + ((cfid) << 1)) : (cfid));
238
239 while (abs(vco_fid - vco_cfid) > 2) {
240 if (fid > cfid) {
241 if (cfid > 6)
242 val = cfid + 2;
243 else
244 val = FID_TO_VCO_FID(cfid)(((cfid) < 8) ? (8 + ((cfid) << 1)) : (cfid)) + 2;
245 } else
246 val = cfid - 2;
247 WRITE_FIDVID(val, cvid, (uint64_t)cstate->pll * 1000 / 5)wrmsr(0xc0010041, ((((uint64_t)cstate->pll * 1000 / 5) <<
32) | (1ULL << 16) | ((cvid) << 8) | (val)))
;
248
249 if (k8pnow_read_pending_wait(&status))
250 return;
251 cfid = PN8_STA_CFID(status)((status) & 0x3f);
252 COUNT_OFF_IRT(cstate->irt)(*delay_func)(10 * (1 << (cstate->irt)));
253
254 vco_cfid = FID_TO_VCO_FID(cfid)(((cfid) < 8) ? (8 + ((cfid) << 1)) : (cfid));
255 }
256
257 WRITE_FIDVID(fid, cvid, (uint64_t) cstate->pll * 1000 / 5)wrmsr(0xc0010041, ((((uint64_t) cstate->pll * 1000 / 5) <<
32) | (1ULL << 16) | ((cvid) << 8) | (fid)))
;
258 if (k8pnow_read_pending_wait(&status))
259 return;
260 cfid = PN8_STA_CFID(status)((status) & 0x3f);
261 COUNT_OFF_IRT(cstate->irt)(*delay_func)(10 * (1 << (cstate->irt)));
262 }
263
264 /* Phase 3: change to requested voltage */
265 if (cvid != vid) {
266 WRITE_FIDVID(cfid, vid, 1ULL)wrmsr(0xc0010041, (((1ULL) << 32) | (1ULL << 16) |
((vid) << 8) | (cfid)))
;
267 if (k8pnow_read_pending_wait(&status))
268 return;
269 cvid = PN8_STA_CVID(status)(((status) >> 32) & 0x1f);
270 COUNT_OFF_VST(cstate->vst)(*delay_func)(20 * (cstate->vst));
271 }
272
273 if (cfid == fid || cvid == vid)
274 cpuspeed = cstate->state_table[level].freq;
275}
276
277/*
278 * Given a set of pair of fid/vid, and number of performance states,
279 * compute state_table via an insertion sort.
280 */
281int
282k8pnow_decode_pst(struct k8pnow_cpu_state *cstate, uint8_t *p)
283{
284 int i, j, n;
285 struct k8pnow_state state;
286 for (n = 0, i = 0; i < cstate->n_states; i++) {
287 state.fid = *p++;
288 state.vid = *p++;
289
290 /*
291 * The minimum supported frequency per the data sheet is 800MHz
292 * The maximum supported frequency is 5000MHz.
293 */
294 state.freq = 800 + state.fid * 100;
295 j = n;
296 while (j > 0 && cstate->state_table[j - 1].freq > state.freq) {
297 memcpy(&cstate->state_table[j],__builtin_memcpy((&cstate->state_table[j]), (&cstate
->state_table[j - 1]), (sizeof(struct k8pnow_state)))
298 &cstate->state_table[j - 1],__builtin_memcpy((&cstate->state_table[j]), (&cstate
->state_table[j - 1]), (sizeof(struct k8pnow_state)))
299 sizeof(struct k8pnow_state))__builtin_memcpy((&cstate->state_table[j]), (&cstate
->state_table[j - 1]), (sizeof(struct k8pnow_state)))
;
300 --j;
301 }
302 memcpy(&cstate->state_table[j], &state,__builtin_memcpy((&cstate->state_table[j]), (&state
), (sizeof(struct k8pnow_state)))
303 sizeof(struct k8pnow_state))__builtin_memcpy((&cstate->state_table[j]), (&state
), (sizeof(struct k8pnow_state)))
;
304 n++;
305 }
306 return 1;
307}
308
309#if NACPICPU1 > 0
310
311int
312k8pnow_acpi_states(struct k8pnow_cpu_state * cstate, struct acpicpu_pss * pss,
313 int nstates, uint64_t status)
314{
315 struct k8pnow_state state;
316 int j, k, n;
317 uint32_t ctrl;
318
319 k = -1;
320
321 for (n = 0; n < cstate->n_states; n++) {
322 if ((PN8_STA_CFID(status)((status) & 0x3f) == PN8_PSS_CFID(pss[n].pss_status)((pss[n].pss_status) & 0x3f)) &&
323 (PN8_STA_CVID(status)(((status) >> 32) & 0x1f) == PN8_PSS_CVID(pss[n].pss_status)(((pss[n].pss_status) >> 6) & 0x1f)))
324 k = n;
325 ctrl = pss[n].pss_ctrl;
326 state.fid = PN8_ACPI_CTRL_TO_FID(ctrl)((ctrl) & 0x3f);
327 state.vid = PN8_ACPI_CTRL_TO_VID(ctrl)(((ctrl) >> 6) & 0x1f);
328
329 state.freq = pss[n].pss_core_freq;
330 j = n;
331 while (j > 0 && cstate->state_table[j - 1].freq > state.freq) {
332 memcpy(&cstate->state_table[j],__builtin_memcpy((&cstate->state_table[j]), (&cstate
->state_table[j - 1]), (sizeof(struct k8pnow_state)))
333 &cstate->state_table[j - 1],__builtin_memcpy((&cstate->state_table[j]), (&cstate
->state_table[j - 1]), (sizeof(struct k8pnow_state)))
334 sizeof(struct k8pnow_state))__builtin_memcpy((&cstate->state_table[j]), (&cstate
->state_table[j - 1]), (sizeof(struct k8pnow_state)))
;
335 --j;
336 }
337 memcpy(&cstate->state_table[j], &state,__builtin_memcpy((&cstate->state_table[j]), (&state
), (sizeof(struct k8pnow_state)))
338 sizeof(struct k8pnow_state))__builtin_memcpy((&cstate->state_table[j]), (&state
), (sizeof(struct k8pnow_state)))
;
339 }
340
341 return k;
342}
343
344void
345k8pnow_acpi_pss_changed(struct acpicpu_pss * pss, int npss)
346{
347 int curs, needtran;
348 struct k8pnow_cpu_state *cstate, *nstate;
349 uint32_t ctrl;
350 uint64_t status;
351
352 status = rdmsr(MSR_AMDK7_FIDVID_STATUS0xc0010042);
353 cstate = k8pnow_current_state;
354
355 nstate = malloc(sizeof(struct k8pnow_cpu_state), M_DEVBUF2, M_NOWAIT0x0002);
356 if (!nstate)
357 return;
358
359 curs = k8pnow_acpi_states(nstate, pss, npss, status);
360 needtran = 0;
361
362 if (curs < 0) {
363 /* Our current opearting state is not among the ones found the new PSS */
364 curs = ((perflevel * npss) + 1) / 101;
365 if (curs >= npss)
366 curs = npss - 1;
367 needtran = 1;
368 }
369
370 ctrl = pss[curs].pss_ctrl;
371
372 nstate->rvo = PN8_ACPI_CTRL_TO_RVO(ctrl)(((ctrl) >> 28) & 0x03);
373 nstate->vst = PN8_ACPI_CTRL_TO_VST(ctrl)(((ctrl) >> 11) & 0x1f);
374 nstate->mvs = PN8_ACPI_CTRL_TO_MVS(ctrl)(((ctrl) >> 18) & 0x03);
375 nstate->pll = PN8_ACPI_CTRL_TO_PLL(ctrl)(((ctrl) >> 20) & 0x7f);
376 nstate->irt = PN8_ACPI_CTRL_TO_IRT(ctrl)(((ctrl) >> 30) & 0x03);
377 nstate->low = 0;
378 nstate->n_states = npss;
379
380 if (needtran)
381 k8pnow_transition(nstate, curs);
382
383 free(cstate, M_DEVBUF2, sizeof(*cstate));
384 k8pnow_current_state = nstate;
385}
386
387int
388k8pnow_acpi_init(struct k8pnow_cpu_state * cstate, uint64_t status)
389{
390 int curs;
391 uint32_t ctrl;
392 struct acpicpu_pss *pss;
393
394 cstate->n_states = acpicpu_fetch_pss(&pss);
395 if (cstate->n_states == 0)
396 return 0;
397 acpicpu_set_notify(k8pnow_acpi_pss_changed);
398
399 curs = k8pnow_acpi_states(cstate, pss, cstate->n_states, status);
400 ctrl = pss[curs].pss_ctrl;
401
402 cstate->rvo = PN8_ACPI_CTRL_TO_RVO(ctrl)(((ctrl) >> 28) & 0x03);
403 cstate->vst = PN8_ACPI_CTRL_TO_VST(ctrl)(((ctrl) >> 11) & 0x1f);
404 cstate->mvs = PN8_ACPI_CTRL_TO_MVS(ctrl)(((ctrl) >> 18) & 0x03);
405 cstate->pll = PN8_ACPI_CTRL_TO_PLL(ctrl)(((ctrl) >> 20) & 0x7f);
406 cstate->irt = PN8_ACPI_CTRL_TO_IRT(ctrl)(((ctrl) >> 30) & 0x03);
407 cstate->low = 0;
408
409 return 1;
410}
411
412#endif /* NACPICPU */
413
414int
415k8pnow_states(struct k8pnow_cpu_state *cstate, uint32_t cpusig,
416 unsigned int fid, unsigned int vid)
417{
418 struct psb_s *psb;
419 struct pst_s *pst;
420 uint8_t *p;
421 int i;
422
423 for (p = (u_int8_t *)ISA_HOLE_VADDR(BIOS_START)((void *) ((u_long)(0xe0000) - 0x0a0000 + atdevbase));
424 p < (u_int8_t *)ISA_HOLE_VADDR(BIOS_START + BIOS_LEN)((void *) ((u_long)(0xe0000 + 0x20000) - 0x0a0000 + atdevbase
))
; p += 16) {
425 if (memcmp(p, "AMDK7PNOW!", 10)__builtin_memcmp((p), ("AMDK7PNOW!"), (10)) == 0) {
426 psb = (struct psb_s *)p;
427 if (psb->version != 0x14)
428 return 0;
429
430 cstate->vst = psb->ttime;
431 cstate->rvo = PN8_PSB_TO_RVO(psb->reserved)((psb->reserved) & 0x03);
432 cstate->irt = PN8_PSB_TO_IRT(psb->reserved)(((psb->reserved) >> 2) & 0x03);
433 cstate->mvs = PN8_PSB_TO_MVS(psb->reserved)(((psb->reserved) >> 4) & 0x03);
434 cstate->low = PN8_PSB_TO_BATT(psb->reserved)(((psb->reserved) >> 6) & 0x03);
435 p+= sizeof(struct psb_s);
436
437 for(i = 0; i < psb->n_pst; ++i) {
438 pst = (struct pst_s *) p;
439
440 cstate->pll = pst->pll;
441 cstate->n_states = pst->n_states;
442 if (cpusig == pst->cpuid &&
443 pst->fid == fid && pst->vid == vid) {
444 return (k8pnow_decode_pst(cstate,
445 p+= sizeof (struct pst_s)));
Although the value stored to 'p' is used in the enclosing expression, the value is never actually read from 'p'
446 }
447 p += sizeof(struct pst_s) + 2
448 * cstate->n_states;
449 }
450 }
451 }
452
453 return 0;
454
455}
456
457void
458k8_powernow_init(struct cpu_info *ci)
459{
460 uint64_t status;
461 u_int maxfid, maxvid, i;
462 u_int32_t extcpuid, dummy;
463 struct k8pnow_cpu_state *cstate;
464 struct k8pnow_state *state;
465 char * techname = NULL((void *)0);
466
467 if (setperf_prio > 1)
468 return;
469
470 cstate = malloc(sizeof(struct k8pnow_cpu_state), M_DEVBUF2, M_NOWAIT0x0002);
471 if (!cstate)
472 return;
473
474 cstate->n_states = 0;
475 status = rdmsr(MSR_AMDK7_FIDVID_STATUS0xc0010042);
476 maxfid = PN8_STA_MFID(status)(((status) >> 16) & 0x3f);
477 maxvid = PN8_STA_MVID(status)(((status) >> 48) & 0x1f);
478
479 /*
480 * If start FID is different to max FID, then it is a
481 * mobile processor. If not, it is a low powered desktop
482 * processor.
483 */
484 if (PN8_STA_SFID(status)(((status) >> 8) & 0x3f) != PN8_STA_MFID(status)(((status) >> 16) & 0x3f))
485 techname = "PowerNow! K8";
486 else
487 techname = "Cool'n'Quiet K8";
488
489#if NACPICPU1 > 0
490 /* If we have acpi check acpi first */
491 if (!k8pnow_acpi_init(cstate, status))
492#endif
493 {
494 if (!k8pnow_states(cstate, ci->ci_signature, maxfid, maxvid)) {
495 /* Extended CPUID signature value */
496 CPUID(0x80000001, extcpuid, dummy, dummy, dummy)__asm volatile("cpuid" : "=a" (extcpuid), "=b" (dummy), "=c" (
dummy), "=d" (dummy) : "a" (0x80000001))
;
497 k8pnow_states(cstate, extcpuid, maxfid, maxvid);
498 }
499 }
500 if (cstate->n_states) {
501 printf("%s: %s %d MHz: speeds:",
502 ci->ci_dev->dv_xname, techname, cpuspeed);
503 for (i = cstate->n_states; i > 0; i--) {
504 state = &cstate->state_table[i-1];
505 printf(" %d", state->freq);
506 }
507 printf(" MHz\n");
508 k8pnow_current_state = cstate;
509 cpu_setperf = k8_powernow_setperf;
510 setperf_prio = 1;
511 return;
512 }
513 free(cstate, M_DEVBUF2, sizeof(*cstate));
514}