summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/i386')
-rw-r--r--sys/arch/i386/i386/machdep.c26
-rw-r--r--sys/arch/i386/i386/powernow-k7.c87
-rw-r--r--sys/arch/i386/i386/powernow-k8.c49
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;