work in progress. - correct error in converting flags to trigger values. §5.2.12.5, 5-50 (acpi 5.0) - provide a new structure to store acpi-private configuration information. - get the values to program into pm1actl and pm1bctl to go to sleep from \_Sn_. - properly probe the power button, including evaluting _STA for present & decoding, and if so, run _INI if it exists Reference: /n/atom/patch/applied2013/acpicfg Date: Tue Oct 22 08:08:50 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/nix/k10/acpi.c Tue Oct 22 08:08:45 2013 +++ /sys/src/nix/k10/acpi.c Tue Oct 22 08:08:46 2013 @@ -35,6 +35,7 @@ static int ntblmap; /* successfully mapped tables */ static Tbl *tblmap[64]; Fadt fadt; + Acpicfg acpicfg; static int checksum(void *v, int n) @@ -292,7 +293,7 @@ int flagstotrigger(int bustype, int flags) { - switch((flags>>3) & 3){ + switch((flags>>2) & 3){ case 1: return TMedge; case 3: @@ -648,6 +649,7 @@ /* add identity mapped legacy isa interrupts */ for(i=0; i<16; i++) addirq(i, BusISA, 0, i, 0); + DBG("acpiinit: %d maches\n", nmach); } @@ -959,6 +961,100 @@ print("\n"); } +int +checkpnpid(void *dot, char *pnpid) +{ + char *id; + void *p, *x; + + if(dot == nil) + return -1; + id = nil; + if((x = amlwalk(dot, "_HID")) != nil) + if((p = amlval(x)) != nil) + id = eisaid(p); + if(id == nil) + return -1; + return strcmp(id, pnpid); +} + +enum { + Present = 1<<0, + Decode = 1<<1, + Funct = 1<<3, + Staok = Present | Funct, +}; + +int +staok(void *dot) +{ + int b; + void *p, *x; + + if((x = amlwalk(dot, "_STA")) == nil) + return 0; + if(amleval(x, "", &p) != 0) + return 0; + b = amlint(p); + return b & Staok; +} + +static int +evalini(void *dot) +{ + int b; + void *p, *x; + + b = staok(dot); + if((b & Present) == 0) + return -1; + if((x = amlwalk(dot, "_INI")) != nil){ + if(amleval(x, "", &p) == 0) + print("eval _INI → %V\n", p); + } + return 0; +} + +int +cfgpwerb(void) +{ + void *dot; + + dot = amlwalk(amlroot, "\\_SB_.PWRB"); + if(checkpnpid(dot, "PNP0C0C") != 0) + return 0; +// print("PWRB %V\n", dot); + if(evalini(dot) == -1){ + print("PWRB evalini fails\n"); + return 0; + } + return 1; +} + +static void +cfgsleep(void) +{ + char buf[16]; + uint *t, i; + void **v; + + /* default soft off values */ + t = acpicfg.sval[5]; + t[0] = 7; + t[1] = 0; + + /* look for the proper ones */ + for(i = 0; i < 6; i++){ + t = acpicfg.sval[i]; + snprint(buf, sizeof buf, "\\_S%d_", i); + v = amlval(amlwalk(amlroot, buf)); + if(v != nil && amltag(v) == 'p' && amllen(v) == 4){ + t[0] = amlint(v[0]); + t[1] = amlint(v[1]); + } + } +} + #define acpiinit(x) mpsinit(x) /* temporary hack */ void acpiinit(int maxmach) @@ -978,6 +1074,9 @@ parsetables(&dat); if(fadt.smicmd != 0) iapcbootarch(); + + cfgpwerb(); + cfgsleep(); /* free the AML interpreter */ amlexit(); --- /sys/src/nix/k10/acpi.h Tue Oct 22 08:08:46 2013 +++ /sys/src/nix/k10/acpi.h Tue Oct 22 08:08:47 2013 @@ -2,6 +2,8 @@ typedef struct Gas Gas; typedef struct Tbl Tbl; +typedef struct Acpicfg Acpicfg; + /* * Header for ACPI description tables */ @@ -87,6 +89,11 @@ }; #pragma varargck type "G" Gas* +struct Acpicfg { + uint sval[6][2]; /* p1a.ctl, p1b.ctl */ +}; + Tbl* acpigettbl(void*); extern Fadt fadt; +extern Acpicfg acpicfg;