Unix Technical Forum

Re: acpicpu needs wide testing

This is a discussion on Re: acpicpu needs wide testing within the mailing.openbsd.tech forums, part of the OpenBSD category; --> And now with actual applies action... Sorry for the previous one; try this one instead. Index: acpicpu.c ================================================== ================= ...


Go Back   Unix Technical Forum > Unix Operating Systems > OpenBSD > mailing.openbsd.tech

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-18-2008, 09:34 AM
Marco Peereboom
 
Posts: n/a
Default Re: acpicpu needs wide testing

And now with actual applies action...

Sorry for the previous one; try this one instead.

Index: acpicpu.c
================================================== =================
RCS file: /cvs/src/sys/dev/acpi/acpicpu.c,v
retrieving revision 1.40
diff -u -p -u -p -r1.40 acpicpu.c
--- acpicpu.c 29 Dec 2007 02:55:44 -0000 1.40
+++ acpicpu.c 30 Dec 2007 17:46:02 -0000
@@ -94,9 +94,16 @@ struct acpicpu_softc {
struct aml_node *sc_devnode;

int sc_pss_len;
+ int sc_ppc;
+ int sc_level;
struct acpicpu_pss *sc_pss;

struct acpicpu_pct sc_pct;
+ /* save compensation for pct access for lying bios' */
+ u_int32_t sc_pct_stat_as;
+ u_int32_t sc_pct_ctrl_as;
+ u_int32_t sc_pct_stat_len;
+ u_int32_t sc_pct_ctrl_len;
/*
* XXX: _PPC Change listener
* PPC changes can occur when for example a machine is disconnected
@@ -110,6 +117,7 @@ struct acpicpu_softc {

void acpicpu_set_throttle(struct acpicpu_softc *, int);
void acpicpu_add_cstatepkg(struct aml_value *, void *);
+int acpicpu_getppc(struct acpicpu_softc *);
int acpicpu_getpct(struct acpicpu_softc *);
int acpicpu_getpss(struct acpicpu_softc *);
struct acpi_cstate *acpicpu_add_cstate(struct acpicpu_softc *, int, int, int,
@@ -236,6 +244,7 @@ acpicpu_attach(struct device *parent, st
struct aml_value res;
int i;
struct acpi_cstate *cx;
+ u_int32_t status = 0;

sc->sc_acpi = (struct acpi_softc *)parent;
sc->sc_devnode = aa->aaa_node;
@@ -286,7 +295,6 @@ acpicpu_attach(struct device *parent, st
sc->sc_pblk_addr + 5);
}
if (acpicpu_getpss(sc)) {
- /* XXX not the right test but has to do for now */
sc->sc_flags |= FLAGS_NOPSS;
} else {
#ifdef ACPI_DEBUG
@@ -301,6 +309,13 @@ acpicpu_attach(struct device *parent, st
}
dnprintf(20, "\n");
#endif
+ if (sc->sc_pss_len == 0) {
+ /* this should never happen */
+ printf("%s: invalid _PSS length\n");
+ sc->sc_flags |= FLAGS_NOPSS;
+ }
+
+ acpicpu_getppc(sc);
if (acpicpu_getpct(sc))
sc->sc_flags |= FLAGS_NOPCT;
else {
@@ -313,6 +328,14 @@ acpicpu_attach(struct device *parent, st
aml_register_notify(sc->sc_devnode, NULL,
acpicpu_notify, sc, ACPIDEV_NOPOLL);

+ acpi_gasio(sc->sc_acpi, ACPI_IOREAD,
+ sc->sc_pct.pct_status.grd_gas.address_space_id,
+ sc->sc_pct.pct_status.grd_gas.address,
+ sc->sc_pct_stat_as, sc->sc_pct_stat_as, &status);
+ sc->sc_level = (100 / sc->sc_pss_len) *
+ (sc->sc_pss_len - status);
+ dnprintf(20, "%s: cpu index %d, percentage %d\n",
+ DEVNAME(sc), status, sc->sc_level);
if (setperf_prio < 30) {
cpu_setperf = acpicpu_setperf;
setperf_prio = 30;
@@ -371,19 +394,30 @@ acpicpu_attach(struct device *parent, st
}

int
-acpicpu_getpct(struct acpicpu_softc *sc)
+acpicpu_getppc(struct acpicpu_softc *sc)
{
struct aml_value res;
- int rv = 1;
+
+ sc->sc_ppc = 0;

if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_PPC", 0, NULL, &res)) {
dnprintf(10, "%s: no _PPC\n", DEVNAME(sc));
return (1);
}

- dnprintf(10, "_PPC: %d\n", aml_val2int(&res));
+ sc->sc_ppc = aml_val2int(&res);
+ dnprintf(10, "%s: _PPC: %d\n", DEVNAME(sc), sc->sc_ppc);
aml_freevalue(&res);

+ return (0);
+}
+
+int
+acpicpu_getpct(struct acpicpu_softc *sc)
+{
+ struct aml_value res;
+ int rv = 1;
+
if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_PCT", 0, NULL, &res)) {
dnprintf(20, "%s: no _PCT\n", DEVNAME(sc));
return (1);
@@ -429,6 +463,21 @@ acpicpu_getpct(struct acpicpu_softc *sc)
sc->sc_pct.pct_status.grd_gas.access_size,
sc->sc_pct.pct_status.grd_gas.address);

+ /* if not set assume single 32 bit access */
+ sc->sc_pct_stat_as = sc->sc_pct.pct_status.grd_gas.register_bit_width
+ / 8;
+ if (sc->sc_pct_stat_as == 0)
+ sc->sc_pct_stat_as = 4;
+ sc->sc_pct_ctrl_as = sc->sc_pct.pct_ctrl.grd_gas.register_bit_width / 8;
+ if (sc->sc_pct_ctrl_as == 0)
+ sc->sc_pct_ctrl_as = 4;
+ sc->sc_pct_stat_len = sc->sc_pct.pct_status.grd_gas.access_size;
+ if (sc->sc_pct_stat_len == 0)
+ sc->sc_pct_stat_len = sc->sc_pct_stat_as;
+ sc->sc_pct_ctrl_len = sc->sc_pct.pct_ctrl.grd_gas.access_size;
+ if (sc->sc_pct_ctrl_len == 0)
+ sc->sc_pct_ctrl_len = sc->sc_pct_ctrl_as;
+
rv = 0;
ffh:
aml_freevalue(&res);
@@ -504,10 +553,14 @@ acpicpu_notify(struct aml_node *node, in

switch (notify_type) {
case 0x80: /* _PPC changed, retrieve new values */
- acpicpu_getpct(sc);
+ acpicpu_getppc(sc);
acpicpu_getpss(sc);
if (sc->sc_notify)
sc->sc_notify(sc->sc_pss, sc->sc_pss_len);
+
+ /* reset performance to current percentage */
+ /* XXX will fail for amd64 for now */
+ acpicpu_setperf(sc->sc_level);
break;
default:
printf("%s: unhandled cpu event %x\n", DEVNAME(sc),
@@ -532,8 +585,7 @@ acpicpu_setperf(int level)
{
struct acpicpu_softc *sc;
struct acpicpu_pss *pss = NULL;
- int idx;
- u_int32_t stat_as, ctrl_as, stat_len, ctrl_len;
+ int idx, len;
u_int32_t status = 0;

sc = acpicpu_sc[cpu_number()];
@@ -551,54 +603,44 @@ acpicpu_setperf(int level)
* XXX this should be handled more gracefully and it needs to also do
* the duty cycle method instead of pss exclusively
*/
- if (sc->sc_pss_len == 0) {
- dnprintf(10, "%s: acpicpu no _PSS\n", sc->sc_devnode->name);
+ if (sc->sc_flags & FLAGS_NOPSS || sc->sc_flags & FLAGS_NOPCT) {
+ dnprintf(10, "%s: acpicpu no _PSS or _PCT\n", sc->sc_devnode->name);
return;
}

- idx = (sc->sc_pss_len - 1) - (level / (100 / sc->sc_pss_len));
+ if (sc->sc_ppc)
+ len = sc->sc_ppc;
+ else
+ len = sc->sc_pss_len;
+ idx = (len - 1) - (level / (100 / len));
if (idx < 0)
- idx = 0; /* compensate */
- if (idx > sc->sc_pss_len) {
- /* XXX should never happen */
- printf("%s: acpicpu setperf index out of range\n",
- sc->sc_devnode->name);
- return;
- }
+ idx = 0;

- dnprintf(10, "%s: acpicpu setperf index %d\n",
- sc->sc_devnode->name, idx);
+ if (sc->sc_ppc)
+ idx += sc->sc_pss_len - sc->sc_ppc;

- pss = &sc->sc_pss[idx];
+ if (idx > sc->sc_pss_len)
+ idx = sc->sc_pss_len - 1;

- /* if not set assume single 32 bit access */
- stat_as = sc->sc_pct.pct_status.grd_gas.register_bit_width / 8;
- if (stat_as == 0)
- stat_as = 4;
- ctrl_as = sc->sc_pct.pct_ctrl.grd_gas.register_bit_width / 8;
- if (ctrl_as == 0)
- ctrl_as = 4;
- stat_len = sc->sc_pct.pct_status.grd_gas.access_size;
- if (stat_len == 0)
- stat_len = stat_as;
- ctrl_len = sc->sc_pct.pct_ctrl.grd_gas.access_size;
- if (ctrl_len == 0)
- ctrl_len = ctrl_as;
+ dnprintf(10, "%s: acpicpu setperf index %d pss_len %d ppc %d\n",
+ sc->sc_devnode->name, idx, sc->sc_pss_len, sc->sc_ppc);
+
+ pss = &sc->sc_pss[idx];

#ifdef ACPI_DEBUG
/* keep this for now since we will need this for debug in the field */
printf("0 status: %x %llx %u %u ctrl: %x %llx %u %u\n",
sc->sc_pct.pct_status.grd_gas.address_space_id,
sc->sc_pct.pct_status.grd_gas.address,
- stat_as, stat_len,
+ sc->sc_pct_stat_as, sc->sc_pct_stat_len,
sc->sc_pct.pct_ctrl.grd_gas.address_space_id,
sc->sc_pct.pct_ctrl.grd_gas.address,
- ctrl_as, ctrl_len);
+ sc->sc_pct_ctrl_as, sc->sc_pct_ctrl_len);
#endif
acpi_gasio(sc->sc_acpi, ACPI_IOREAD,
sc->sc_pct.pct_status.grd_gas.address_space_id,
- sc->sc_pct.pct_status.grd_gas.address, stat_as, stat_len,
- &status);
+ sc->sc_pct.pct_status.grd_gas.address, sc->sc_pct_stat_as,
+ sc->sc_pct_stat_len, &status);
dnprintf(20, "1 status: %u <- %u\n", status, pss->pss_status);

/* Are we already at the requested frequency? */
@@ -607,20 +649,21 @@ acpicpu_setperf(int level)

acpi_gasio(sc->sc_acpi, ACPI_IOWRITE,
sc->sc_pct.pct_ctrl.grd_gas.address_space_id,
- sc->sc_pct.pct_ctrl.grd_gas.address, ctrl_as, ctrl_len,
- &pss->pss_ctrl);
+ sc->sc_pct.pct_ctrl.grd_gas.address, sc->sc_pct_ctrl_as,
+ sc->sc_pct_ctrl_len, &pss->pss_ctrl);
dnprintf(20, "pss_ctrl: %x\n", pss->pss_ctrl);

acpi_gasio(sc->sc_acpi, ACPI_IOREAD,
sc->sc_pct.pct_status.grd_gas.address_space_id,
- sc->sc_pct.pct_status.grd_gas.address, stat_as, stat_as,
- &status);
+ sc->sc_pct.pct_status.grd_gas.address, sc->sc_pct_stat_as,
+ sc->sc_pct_stat_as, &status);
dnprintf(20, "2 status: %d\n", status);

/* Did the transition succeed? */
- if (status == pss->pss_status)
+ if (status == pss->pss_status) {
cpuspeed = pss->pss_core_freq;
- else
+ sc->sc_level = level;
+ } else
printf("%s: acpicpu setperf failed to alter frequency\n",
sc->sc_devnode->name);
}

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 03:08 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com