|
Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com |
From: Markus Hennecke (markus-hennecke
markus-hennecke.de)
Date: Fri Feb 01 2008 - 12:24:45 CST
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Thu, 31 Jan 2008, gwk
gwk.ca wrote:
> Hi I believe you are correct about the macros I have rolled them into the
> following diff however I dont think its correct to panic, the way I see
> it the current state not being among the news ones we get, e.g. machine
> can't support maximum frequency on battery power. Please give this a try
> its amd64 only and I have only compiled, not tested.
That works here. I forgot that there are machines out there reporting
different state tables while on battery or ac, so you are right, a panic
is not appropriate to handle a non existent state.
I did a quick transfer from your patch to the i386 powernow-k8.c, which
is basically the same as the amd64 version, seems to work fine here,
too:
Index: powernow-k8.c
===================================================================
RCS file: /var/cvs/src/sys/arch/i386/i386/powernow-k8.c,v
retrieving revision 1.23
diff -u -p -r1.23 powernow-k8.c
--- powernow-k8.c 31 May 2007 17:49:16 -0000 1.23
+++ powernow-k8.c 1 Feb 2008 16:14:39 -0000

-88,6 +88,9 
#define PN8_ACPI_CTRL_TO_RVO(x) (((x) >> 28) & 0x03)
#define PN8_ACPI_CTRL_TO_IRT(x) (((x) >> 30) & 0x03)
+#define PN8_PSS_CFID(x) ((x) & 0x3f)
+#define PN8_PSS_CVID(x) (((x) >> 6) & 0x1f)
+
#define PN8_PLL_LOCK(x) ((x) * 1000/5)
#define WRITE_FIDVID(fid, vid, ctrl) \
wrmsr(MSR_AMDK7_FIDVID_CTL, \

-138,11 +141,13 
struct pst_s {
struct k8pnow_cpu_state *k8pnow_current_state = NULL;
extern int setperf_prio;
+extern int perflevel;
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,
unsigned int);
+void k8pnow_transition(struct k8pnow_cpu_state *, int);
#if NACPICPU > 0
int k8pnow_acpi_init(struct k8pnow_cpu_state *, uint64_t);

-170,10 +175,23 
void
k8_powernow_setperf(int level)
{
unsigned int i;
+ struct k8pnow_cpu_state *cstate;
+
+ cstate = k8pnow_current_state;
+
+ i = ((level * cstate->n_states) + 1) / 101;
+ if (i >= cstate->n_states)
+ i = cstate->n_states - 1;
+
+ k8pnow_transition(cstate, i);
+}
+
+void
+k8pnow_transition(struct k8pnow_cpu_state *cstate, int level)
+{
uint64_t status;
int cfid, cvid, fid = 0, vid = 0, rvo;
u_int val;
- struct k8pnow_cpu_state *cstate;
/*
* We dont do a k8pnow_read_pending_wait here, need to ensure that the

-182,16 +200,11 
k8_powernow_setperf(int level)
status = rdmsr(MSR_AMDK7_FIDVID_STATUS);
if (PN8_STA_PENDING(status))
return;
+
cfid = PN8_STA_CFID(status);
cvid = PN8_STA_CVID(status);
-
- cstate = k8pnow_current_state;
-
- 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;
+ fid = cstate->state_table[level].fid;
+ vid = cstate->state_table[level].vid;
if (fid == cfid && vid == cvid)
return;

-264,7 +277,7 
k8_powernow_setperf(int level)
}
if (cfid == fid || cvid == vid)
- cpuspeed = cstate->state_table[i].freq;
+ cpuspeed = cstate->state_table[level].freq;
}
/*

-357,7 +370,9 
k8pnow_acpi_states(struct k8pnow_cpu_sta
k = -1;
for (n = 0; n < cstate->n_states; n++) {
- if (status == pss[n].pss_status)
+ if ((PN8_STA_CFID(status) == PN8_PSS_CFID(pss[n].pss_status))
+ && (PN8_STA_CVID(status) ==
+ PN8_PSS_CVID(pss[n].pss_status)))
k = n;
ctrl = pss[n].pss_ctrl;
state.fid = PN8_ACPI_CTRL_TO_FID(ctrl);

-381,22 +396,43 
k8pnow_acpi_states(struct k8pnow_cpu_sta
void
k8pnow_acpi_pss_changed(struct acpicpu_pss * pss, int npss)
{
- int curs;
- struct k8pnow_cpu_state * cstate;
+ int curs, needtran;
+ struct k8pnow_cpu_state *cstate, *nstate;
uint32_t ctrl;
uint64_t status;
status = rdmsr(MSR_AMDK7_FIDVID_STATUS);
cstate = k8pnow_current_state;
- curs = k8pnow_acpi_states(cstate, pss, npss, status);
+ nstate = malloc(sizeof(struct k8pnow_cpu_state), M_DEVBUF, M_NOWAIT);
+ if (!nstate)
+ return;
+
+ curs = k8pnow_acpi_states(nstate, pss, npss, status);
+ needtran = 0;
+
+ if (curs < 0) {
+ /* Our current operating state is not among the ones found in
+ * the new PSS */
+ curs = ((perflevel * npss) + 1) / 101;
+ if (curs >= npss)
+ curs = npss - 1;
+ needtran = 1;
+ }
+
ctrl = pss[curs].pss_ctrl;
- cstate->vst = PN8_ACPI_CTRL_TO_VST(ctrl);
- cstate->mvs = PN8_ACPI_CTRL_TO_MVS(ctrl);
- cstate->pll = PN8_ACPI_CTRL_TO_PLL(ctrl);
- cstate->irt = PN8_ACPI_CTRL_TO_IRT(ctrl);
- cstate->low = 0;
- cstate->n_states = npss;
+ nstate->vst = PN8_ACPI_CTRL_TO_VST(ctrl);
+ nstate->mvs = PN8_ACPI_CTRL_TO_MVS(ctrl);
+ nstate->pll = PN8_ACPI_CTRL_TO_PLL(ctrl);
+ nstate->irt = PN8_ACPI_CTRL_TO_IRT(ctrl);
+ nstate->low = 0;
+ nstate->n_states = npss;
+
+ if (needtran)
+ k8pnow_transition(nstate, curs);
+
+ free(cstate, M_DEVBUF);
+ k8pnow_current_state = nstate;
}
int
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]