diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2006-03-20 12:09:00 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2006-03-20 12:09:00 +0000 |
commit | 932b930ec094e69a94d338e483a3339be3d3fbff (patch) | |
tree | a86cd9479479465e5253609259157ab8a11cb5e8 /sys/arch/i386 | |
parent | 8320803d13e4f1025dd8886d8b7d50f53337dc78 (diff) |
a bit of demagification. this moves the checks for the cpu scaling features
out of machdep and into powernow-k7 and -k8. machdep now just figures out
if its the right type of cpu before calling the powernow code which
figures out if the scaling is supported.
from gwk
Diffstat (limited to 'sys/arch/i386')
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 26 | ||||
-rw-r--r-- | sys/arch/i386/i386/powernow-k7.c | 87 | ||||
-rw-r--r-- | sys/arch/i386/i386/powernow-k8.c | 49 |
3 files changed, 71 insertions, 91 deletions
diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 2ffa73fe2bb..c2ea26e000f 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.349 2006/03/16 22:23:26 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.350 2006/03/20 12:08:59 dlg Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -1411,28 +1411,22 @@ amd_family6_setup(struct cpu_info *ci) extern void sse2_pagezero(void *, size_t); extern void i686_pagezero(void *, size_t); #if !defined(MULTIPROCESSOR) - u_int regs[4]; + int family = (ci->ci_signature >> 8) & 15; #endif if (cpu_feature & CPUID_SSE2) pagezero = sse2_pagezero; else pagezero = i686_pagezero; + #if !defined(MULTIPROCESSOR) - cpuid(0x80000000, regs); - if (regs[0] > 0x80000007) { - cpuid(0x80000007, regs); - - if (regs[3] & 0x06) { - switch (ci->ci_signature & 0xF00) { - case 0x600: - k7_powernow_init(); - break; - case 0xf00: - k8_powernow_init(); - break; - } - } + switch (family) { + case 6: + k7_powernow_init(); + break; + case 15: + k8_powernow_init(); + break; } #endif #endif diff --git a/sys/arch/i386/i386/powernow-k7.c b/sys/arch/i386/i386/powernow-k7.c index 706384f2005..8e109602803 100644 --- a/sys/arch/i386/i386/powernow-k7.c +++ b/sys/arch/i386/i386/powernow-k7.c @@ -1,4 +1,4 @@ -/* $OpenBSD: powernow-k7.c,v 1.10 2006/03/15 19:56:48 deraadt Exp $ */ +/* $OpenBSD: powernow-k7.c,v 1.11 2006/03/20 12:08:59 dlg Exp $ */ /* * Copyright (c) 2004 Martin Végiard. @@ -67,15 +67,17 @@ #define BIOS_START 0xe0000 #define BIOS_LEN 0x20000 +#define BIOS_STEP 0x16 /* * MSRs and bits used by Powernow technology */ #define MSR_AMDK7_FIDVID_CTL 0xc0010041 #define MSR_AMDK7_FIDVID_STATUS 0xc0010042 +#define AMD_PN_FID_VID 0x06 /* Bitfields used by K7 */ - +#define PN7_PSB_VERSION 0x12 #define PN7_CTR_FID(x) ((x) & 0x1f) #define PN7_CTR_VID(x) (((x) & 0x1f) << 8) #define PN7_CTR_FIDC 0x00010000 @@ -93,8 +95,8 @@ /* * ACPI ctr_val status register to powernow k7 configuration */ -#define ACPI_PN7_CTRL_TO_VID(x) (((x) >> 5) & 0x1f) -#define ACPI_PN7_CTRL_TO_SGTC(x) (((x) >> 10) & 0xffff) +#define PN7_ACPI_CTRL_TO_VID(x) (((x) >> 5) & 0x1f) +#define PN7_ACPI_CTRL_TO_SGTC(x) (((x) >> 10) & 0xffff) #define WRITE_FIDVID(fid, vid, ctrl) \ wrmsr(MSR_AMDK7_FIDVID_CTL, \ @@ -111,31 +113,6 @@ static int k7pnow_fid_to_mult[32] = { 150, 225, 160, 165, 170, 180, -1, -1 }; -/* - * Units are in mV. - */ - -/* - * Mobile VRM (K7) - */ -static int k7pnow_mobile_vid_to_volts[] = { - 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650, - 1600, 1550, 1500, 1450, 1400, 1350, 1300, 0, - 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100, - 1075, 1050, 1025, 1000, 975, 950, 925, 0, -}; - -/* - * Desktop VRM (K7) - */ - -static int k7pnow_desktop_vid_to_volts[] = { - 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650, - 1600, 1550, 1500, 1450, 1400, 1350, 1300, 0, - 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100, - 1075, 1050, 1025, 1000, 975, 950, 925, 0, -}; - #define POWERNOW_MAX_STATES 16 struct k7pnow_state { @@ -150,7 +127,6 @@ struct k7pnow_cpu_state { struct k7pnow_state state_table[POWERNOW_MAX_STATES]; unsigned int n_states; int errata_a0; - int *vid_to_volts; }; struct psb_s { @@ -255,7 +231,7 @@ k7pnow_decode_pst(struct k7pnow_cpu_state * cstate, uint8_t *p, int npst) for (n = 0, i = 0; i < npst; ++i) { state.fid = *p++; state.vid = *p++; - state.freq = 100 * k7pnow_fid_to_mult[state.fid] * cstate->fsb; + state.freq = k7pnow_fid_to_mult[state.fid]/10 * cstate->fsb; if (cstate->errata_a0 && (k7pnow_fid_to_mult[state.fid] % 10) == 5) continue; @@ -293,10 +269,11 @@ k7pnow_states(struct k7pnow_cpu_state *cstate, uint32_t cpusig, * range for the pst tables; 16 byte blocks */ for (p = (u_int8_t *)ISA_HOLE_VADDR(BIOS_START); - p < (u_int8_t *)ISA_HOLE_VADDR(BIOS_START + BIOS_LEN); p+= 16) { + p < (u_int8_t *)ISA_HOLE_VADDR(BIOS_START + BIOS_LEN); p+= + BIOS_STEP) { if (memcmp(p, "AMDK7PNOW!", 10) == 0) { psb = (struct psb_s *)p; - if (psb->version != 0x12) + if (psb->version != PN7_PSB_VERSION) return 0; cstate->sgtc = psb->ttime * cstate->fsb; @@ -310,20 +287,7 @@ k7pnow_states(struct k7pnow_cpu_state *cstate, uint32_t cpusig, if (cpusig == pst->signature && fid == pst->fid && vid == pst->vid) { - switch (pst->signature) { - case 0x760: - case 0x761: - case 0x762: - case 0x770: - case 0x771: - case 0x780: - case 0x781: - case 0x7a0: - break; - default: - return 0; - } - + if (abs(cstate->fsb - pst->fsb) > 5) continue; cstate->n_states = pst->n_states; @@ -357,6 +321,14 @@ k7_powernow_init(void) if (!cstate) return; + cpuid(0x80000000, regs); + if (regs[0] < 0x80000007) + return; + + cpuid(0x80000007, regs); + if (!(regs[3] & AMD_PN_FID_VID)) + return; + cpuid(0x80000001, regs); if ((regs[0] & 0xfff) == 0x760) cstate->errata_a0 = TRUE; @@ -368,32 +340,31 @@ k7_powernow_init(void) startvid = PN7_STA_SVID(status); currentfid = PN7_STA_CFID(status); - CPU_CLOCKUPDATE(); - cstate->fsb = pentium_base_tsc / 100000 / k7pnow_fid_to_mult[currentfid]; + cstate->fsb = pentium_mhz / (k7pnow_fid_to_mult[currentfid]/10); /* * If start FID is different to max FID, then it is a * mobile processor. If not, it is a low powered desktop * processor. */ if (maxfid != currentfid) { - cstate->vid_to_volts = k7pnow_mobile_vid_to_volts; techname = "PowerNow! K7"; } else { - cstate->vid_to_volts = k7pnow_desktop_vid_to_volts; techname = "Cool`n'Quiet K7"; } if (k7pnow_states(cstate, ci->ci_signature, maxfid, startvid)) { if (cstate->n_states) { - printf("%s: AMD %s: available states ", - ci->ci_dev.dv_xname, techname); - for (i = 0; i < cstate->n_states; i++) { - state = &cstate->state_table[i]; - printf("%c%d", i==0 ? '(' : ',', - ((state->freq / 100000)+1)*100); + printf("%s: %s %d Mhz: speeds:", + ci->ci_dev.dv_xname, techname, pentium_mhz); + for(i = cstate->n_states; i > 0; i--) { + state = &cstate->state_table[i-1]; + printf(" %d", state->freq); } - printf(")\n"); + printf(" Mhz\n"); + k7pnow_current_state[cpu_number()] = cstate; cpu_setperf = k7_powernow_setperf; + return; } } + free(cstate, M_DEVBUF); } diff --git a/sys/arch/i386/i386/powernow-k8.c b/sys/arch/i386/i386/powernow-k8.c index dd8231eebad..ce41f86bb21 100644 --- a/sys/arch/i386/i386/powernow-k8.c +++ b/sys/arch/i386/i386/powernow-k8.c @@ -1,4 +1,4 @@ -/* $OpenBSD: powernow-k8.c,v 1.7 2006/03/16 02:39:57 dlg Exp $ */ +/* $OpenBSD: powernow-k8.c,v 1.8 2006/03/20 12:08:59 dlg Exp $ */ /* * Copyright (c) 2004 Martin Végiard. @@ -66,12 +66,14 @@ #define BIOS_START 0xe0000 #define BIOS_LEN 0x20000 +#define BIOS_STEP 16 /* * MSRs and bits used by Powernow technology */ #define MSR_AMDK7_FIDVID_CTL 0xc0010041 #define MSR_AMDK7_FIDVID_STATUS 0xc0010042 +#define AMD_PN_FID_VID 0x06 /* Bitfields used by K8 */ @@ -88,29 +90,30 @@ #define PN8_STA_MVID(x) (((x) >> 48) & 0x1f) /* Reserved1 to powernow k8 configuration */ +#define PN8_PSB_VERSION 0x14 #define PN8_PSB_TO_RVO(x) ((x) & 0x03) #define PN8_PSB_TO_IRT(x) (((x) >> 2) & 0x03) #define PN8_PSB_TO_MVS(x) (((x) >> 4) & 0x03) #define PN8_PSB_TO_BATT(x) (((x) >> 6) & 0x03) /* ACPI ctr_val status register to powernow k8 configuration */ -#define ACPI_PN8_CTRL_TO_FID(x) ((x) & 0x3f) -#define ACPI_PN8_CTRL_TO_VID(x) (((x) >> 6) & 0x1f) -#define ACPI_PN8_CTRL_TO_VST(x) (((x) >> 11) & 0x1f) -#define ACPI_PN8_CTRL_TO_MVS(x) (((x) >> 18) & 0x03) -#define ACPI_PN8_CTRL_TO_PLL(x) (((x) >> 20) & 0x7f) -#define ACPI_PN8_CTRL_TO_RVO(x) (((x) >> 28) & 0x03) -#define ACPI_PN8_CTRL_TO_IRT(x) (((x) >> 30) & 0x03) - +#define PN8_ACPI_CTRL_TO_FID(x) ((x) & 0x3f) +#define PN8_ACPI_CTRL_TO_VID(x) (((x) >> 6) & 0x1f) +#define PN8_ACPI_CTRL_TO_VST(x) (((x) >> 11) & 0x1f) +#define PN8_ACPI_CTRL_TO_MVS(x) (((x) >> 18) & 0x03) +#define PN8_ACPI_CTRL_TO_PLL(x) (((x) >> 20) & 0x7f) +#define PN8_ACPI_CTRL_TO_RVO(x) (((x) >> 28) & 0x03) +#define PN8_ACPI_CTRL_TO_IRT(x) (((x) >> 30) & 0x03) + +#define PN8_PLL_LOCK(x) ((x) * 1000/5) #define WRITE_FIDVID(fid, vid, ctrl) \ wrmsr(MSR_AMDK7_FIDVID_CTL, \ (((ctrl) << 32) | (1ULL << 16) | ((vid) << 8) | (fid))) +#define COUNT_OFF_IRT(irt) DELAY(10 * (1 << (irt))) +#define COUNT_OFF_VST(vst) DELAY(20 * (vst)) -#define COUNT_OFF_IRT(irt) DELAY(10 * (1 << (irt))) -#define COUNT_OFF_VST(vst) DELAY(20 * (vst)) - -#define FID_TO_VCO_FID(fid) \ +#define FID_TO_VCO_FID(fid) \ (((fid) < 8) ? (8 + ((fid) << 1)) : (fid)) #define POWERNOW_MAX_STATES 16 @@ -251,7 +254,8 @@ k8_powernow_setperf(int level) val = FID_TO_VCO_FID(cfid) + 2; } else val = cfid - 2; - WRITE_FIDVID(val, cvid, (uint64_t)cstate->pll * 1000 / 5); + WRITE_FIDVID(val, cvid, (uint64_t) + PN8_PLL_LOCK(cstate->pll)); if (k8pnow_read_pending_wait(&status)) return 1; @@ -261,7 +265,7 @@ k8_powernow_setperf(int level) vco_cfid = FID_TO_VCO_FID(cfid); } - WRITE_FIDVID(fid, cvid, (uint64_t) cstate->pll * 1000 / 5); + WRITE_FIDVID(fid, cvid, (uint64_t) PN8_PLL_LOCK(cstate->pll)); if (k8pnow_read_pending_wait(&status)) return 1; cfid = PN8_STA_CFID(status); @@ -328,10 +332,11 @@ k8pnow_states(struct k8pnow_cpu_state *cstate, uint32_t cpusig, int i; for (p = (u_int8_t *)ISA_HOLE_VADDR(BIOS_START); - p < (u_int8_t *)ISA_HOLE_VADDR(BIOS_START + BIOS_LEN); p += 16) { + p < (u_int8_t *)ISA_HOLE_VADDR(BIOS_START + BIOS_LEN); p += + BIOS_STEP) { if (memcmp(p, "AMDK7PNOW!", 10) == 0) { psb = (struct psb_s *)p; - if (psb->version != 0x14) + if (psb->version != PN8_PSB_VERSION) return 0; cstate->vst = psb->ttime; @@ -369,11 +374,21 @@ k8_powernow_init(void) struct k8pnow_state *state; struct cpu_info * ci; char * techname = NULL; + u_int32_t regs[4]; + ci = curcpu(); if (k8pnow_current_state) return; + cpuid(0x80000000, regs); + if (regs[0] < 0x80000007) + return; + + cpuid(0x80000007, regs); + if (!(regs[3] & AMD_PN_FID_VID)) + return; + cstate = malloc(sizeof(struct k8pnow_cpu_state), M_DEVBUF, M_NOWAIT); if (!cstate) return; |