summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
authorGordon Willem Klok <gwk@cvs.openbsd.org>2007-04-24 17:12:27 +0000
committerGordon Willem Klok <gwk@cvs.openbsd.org>2007-04-24 17:12:27 +0000
commitc9843ae6d7a2e956a7aaa3a7e62483f7674f673d (patch)
tree3e97632678f3d90c279fb3e4a501940619cd45bb /sys/arch/i386
parented696c241c57a73bfd2578d4cdbe8ffcebd3a1a1 (diff)
Choose the state for a request performance level based on calculations
involving the number of states and not the frequencies of the states, which can lead to strange distributions of the states over the hw.setperf range (0-100). Tested by many. ok canacar, tedu
Diffstat (limited to 'sys/arch/i386')
-rw-r--r--sys/arch/i386/i386/est.c14
-rw-r--r--sys/arch/i386/i386/powernow-k7.c37
-rw-r--r--sys/arch/i386/i386/powernow-k8.c30
3 files changed, 32 insertions, 49 deletions
diff --git a/sys/arch/i386/i386/est.c b/sys/arch/i386/i386/est.c
index 3ed13d6bcf0..2c6b2fab25d 100644
--- a/sys/arch/i386/i386/est.c
+++ b/sys/arch/i386/i386/est.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: est.c,v 1.27 2006/12/22 01:34:46 dim Exp $ */
+/* $OpenBSD: est.c,v 1.28 2007/04/24 17:12:26 gwk Exp $ */
/*
* Copyright (c) 2003 Michael Eriksson.
* All rights reserved.
@@ -1076,19 +1076,17 @@ est_init(const char *cpu_device, int vendor)
void
est_setperf(int level)
{
- int low, high, i, fq;
+ int i;
uint64_t msr;
if (est_fqlist == NULL)
return;
- low = MSR2MHZ(est_fqlist->table[est_fqlist->n - 1], bus_clock);
- high = MSR2MHZ(est_fqlist->table[0], bus_clock);
- fq = low + (high - low) * level / 100;
+ i = ((level * est_fqlist->n) + 1) / 101;
+ if (i >= est_fqlist->n)
+ i = est_fqlist->n - 1;
+ i = est_fqlist->n - 1 - i;
- for (i = est_fqlist->n - 1; i > 0; i--)
- if (MSR2MHZ(est_fqlist->table[i], bus_clock) >= fq)
- break;
msr = rdmsr(MSR_PERF_CTL);
msr &= ~0xffffULL;
msr |= est_fqlist->table[i];
diff --git a/sys/arch/i386/i386/powernow-k7.c b/sys/arch/i386/i386/powernow-k7.c
index 2c8f7102a86..ca5f4068451 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.30 2006/12/20 17:50:40 gwk Exp $ */
+/* $OpenBSD: powernow-k7.c,v 1.31 2007/04/24 17:12:26 gwk Exp $ */
/*
* Copyright (c) 2004 Martin Végiard.
@@ -129,9 +129,6 @@ struct pst_s {
struct k7pnow_cpu_state *k7pnow_current_state;
extern int setperf_prio;
-/*
- * Prototypes
- */
int k7pnow_decode_pst(struct k7pnow_cpu_state *, uint8_t *, int);
int k7pnow_states(struct k7pnow_cpu_state *, uint32_t, unsigned int,
unsigned int);
@@ -139,23 +136,18 @@ int k7pnow_states(struct k7pnow_cpu_state *, uint32_t, unsigned int,
void
k7_powernow_setperf(int level)
{
- unsigned int i, low, high, freq;
+ unsigned int i;
int cvid, cfid, vid = 0, fid = 0;
uint64_t status, ctl;
struct k7pnow_cpu_state * cstate;
cstate = k7pnow_current_state;
- high = cstate->state_table[cstate->n_states - 1].freq;
- low = cstate->state_table[0].freq;
- freq = low + (high - low) * level / 100;
-
- for (i = 0; i < cstate->n_states; i++) {
- if (cstate->state_table[i].freq >= freq) {
- fid = cstate->state_table[i].fid;
- vid = cstate->state_table[i].vid;
- break;
- }
- }
+
+ i = ((level * cstate->n_states) + 1) / 101;
+ if (i >= cstate->n_states)
+ i = cstate->n_states - 1;
+ fid = cstate->state_table[i].fid;
+ vid = cstate->state_table[i].vid;
if (fid == 0 || vid == 0)
return;
@@ -269,7 +261,7 @@ k7pnow_states(struct k7pnow_cpu_state *cstate, uint32_t cpusig,
if (cpusig == pst->signature && fid == pst->fid
&& vid == pst->vid) {
-
+
if (abs(cstate->fsb - pst->fsb) > 5)
continue;
cstate->n_states = pst->n_states;
@@ -277,7 +269,8 @@ k7pnow_states(struct k7pnow_cpu_state *cstate, uint32_t cpusig,
p + sizeof(struct pst_s),
cstate->n_states));
}
- p += sizeof(struct pst_s) + (2 * pst->n_states);
+ p += sizeof(struct pst_s) +
+ (2 * pst->n_states);
}
}
}
@@ -317,7 +310,7 @@ k7_powernow_init(void)
if (!cstate)
return;
- cstate->flags = cstate->n_states = 0;
+ cstate->flags = cstate->n_states = 0;
if (ci->ci_signature == AMD_ERRATA_A0_CPUSIG)
cstate->flags |= PN7_FLAG_ERRATA_A0;
@@ -330,7 +323,7 @@ k7_powernow_init(void)
/* if the base CPUID signature fails to match try, the extended one */
if (!k7pnow_states(cstate, ci->ci_signature, maxfid, startvid))
- k7pnow_states(cstate, regs[0], maxfid, startvid);
+ k7pnow_states(cstate, regs[0], maxfid, startvid);
if (cstate->n_states) {
if (cstate->flags & PN7_FLAG_DESKTOP_VRM)
techname = "Cool'n'Quiet K7";
@@ -342,8 +335,8 @@ k7_powernow_init(void)
state = &cstate->state_table[i-1];
printf(" %d", state->freq);
}
- printf(" MHz\n");
-
+ printf(" MHz\n");
+
k7pnow_current_state = cstate;
cpu_setperf = k7_powernow_setperf;
setperf_prio = 1;
diff --git a/sys/arch/i386/i386/powernow-k8.c b/sys/arch/i386/i386/powernow-k8.c
index a37ce8705bc..a59fb1810de 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.21 2006/12/20 17:50:40 gwk Exp $ */
+/* $OpenBSD: powernow-k8.c,v 1.22 2007/04/24 17:12:26 gwk Exp $ */
/*
* Copyright (c) 2004 Martin Végiard.
@@ -132,9 +132,6 @@ struct pst_s {
struct k8pnow_cpu_state *k8pnow_current_state = NULL;
extern int setperf_prio;
-/*
- * Prototypes
- */
int k8pnow_read_pending_wait(uint64_t *);
int k8pnow_decode_pst(struct k8pnow_cpu_state *, uint8_t *);
int k8pnow_states(struct k8pnow_cpu_state *, uint32_t, unsigned int,
@@ -158,7 +155,7 @@ k8pnow_read_pending_wait(uint64_t *status)
void
k8_powernow_setperf(int level)
{
- unsigned int i, low, high, freq;
+ unsigned int i;
uint64_t status;
int cfid, cvid, fid = 0, vid = 0, rvo;
u_int val;
@@ -175,18 +172,12 @@ k8_powernow_setperf(int level)
cvid = PN8_STA_CVID(status);
cstate = k8pnow_current_state;
- low = cstate->state_table[0].freq;
- high = cstate->state_table[cstate->n_states-1].freq;
- freq = low + (high - low) * level / 100;
-
- for (i = 0; i < cstate->n_states; i++) {
- if (cstate->state_table[i].freq >= freq) {
- fid = cstate->state_table[i].fid;
- vid = cstate->state_table[i].vid;
- break;
- }
- }
+ i = ((level * cstate->n_states) + 1) / 101;
+ if (i >= cstate->n_states)
+ i = cstate->n_states - 1;
+ fid = cstate->state_table[i].fid;
+ vid = cstate->state_table[i].vid;
if (fid == cfid && vid == cvid)
return;
@@ -329,7 +320,8 @@ k8pnow_states(struct k8pnow_cpu_state *cstate, uint32_t cpusig,
return (k8pnow_decode_pst(cstate,
p+= sizeof (struct pst_s)));
}
- p += sizeof(struct pst_s) + 2 * cstate->n_states;
+ p += sizeof(struct pst_s) + 2
+ * cstate->n_states;
}
}
}
@@ -360,11 +352,11 @@ k8_powernow_init(void)
cpuid(0x80000000, regs);
if (regs[0] < 0x80000007)
return;
-
+
cpuid(0x80000007, regs);
if (!(regs[3] & AMD_PN_FID_VID))
return;
-
+
/* Extended CPUID signature value */
cpuid(0x80000001, regs);