+#include <aml.h>
+
+int fd, iofd;
+struct Ureg u;
+ulong PM1a_CNT_BLK, PM1b_CNT_BLK, SLP_TYPa, SLP_TYPb;
+ulong GPE0_BLK, GPE1_BLK, GPE0_BLK_LEN, GPE1_BLK_LEN;
+enum {
+ SLP_EN = 0x2000,
+ SLP_TM = 0x1c00,
+};
+
+typedef struct Tbl Tbl;
+struct Tbl {
+ uchar sig[4];
+ uchar len[4];
+ uchar rev;
+ uchar csum;
+ uchar oemid[6];
+ uchar oemtid[8];
+ uchar oemrev[4];
+ uchar cid[4];
+ uchar crev[4];
+ uchar data[];
+};
+
+enum {
+ Tblsz = 4+4+1+1+6+8+4+4+4,
+};
+
+static ulong
+get32(uchar *p){
+ return p[3]<<24 | p[2]<<16 | p[1]<<8 | p[0];
+}
+
+void
+apm(void)
+{
+ seek(fd, 0, 0);
+ if(write(fd, &u, sizeof u) < 0)
+ sysfatal("write: %r");
+ seek(fd, 0, 0);
+ if(read(fd, &u, sizeof u) < 0)
+ sysfatal("read: %r");
+ if(u.flags & 1)
+ sysfatal("apm: %lux", (u.ax>>8) & 0xFF);
+}
+
+int
+loadacpi(void)
+{
+ void *r, **rr;
+ ulong l;
+ Tbl *t;
+ int n;
+
+ amlinit();
+ for(;;){
+ t = malloc(sizeof(*t));
+ if((n = readn(fd, t, Tblsz)) <= 0)
+ break;
+ if(n != Tblsz)
+ return -1;
+ l = get32(t->len);
+ if(l < Tblsz)
+ return -1;
+ l -= Tblsz;
+ t = realloc(t, sizeof(*t) + l);
+ if(readn(fd, t->data, l) != l)
+ return -1;
+ if(memcmp("DSDT", t->sig, 4) == 0){
+ amlintmask = (~0ULL) >> (t->rev <= 1)*32;
+ amlload(t->data, l);
+ }
+ else if(memcmp("SSDT", t->sig, 4) == 0)
+ amlload(t->data, l);
+ else if(memcmp("FACP", t->sig, 4) == 0){
+ PM1a_CNT_BLK = get32(((uchar*)t) + 64);
+ PM1b_CNT_BLK = get32(((uchar*)t) + 68);
+ GPE0_BLK = get32(((uchar*)t) + 80);
+ GPE1_BLK = get32(((uchar*)t) + 84);
+ GPE0_BLK_LEN = *(((uchar*)t) + 92);
+ GPE1_BLK_LEN = *(((uchar*)t) + 93);
+ }
+ }
+ if(amleval(amlwalk(amlroot, "_S5"), "", &r) < 0)
+ return -1;
+ if(amltag(r) != 'p' || amllen(r) < 2)
+ return -1;
+ rr = amlval(r);
+ SLP_TYPa = amlint(rr[0]);
+ SLP_TYPb = amlint(rr[1]);
+ return 0;
+}
+
+void
+outw(long addr, ushort val)
+{
+ uchar buf[2];
+
+ if(addr == 0)
+ return;
+ buf[0] = val;
+ buf[1] = val >> 8;
+ pwrite(iofd, buf, 2, addr);
+}
+
+void
+wirecpu0(void)
+{
+ char buf[128];
+ int ctl;
+
+ snprint(buf, sizeof(buf), "/proc/%d/ctl", getpid());
+ if((ctl = open(buf, OWRITE)) < 0){
+ snprint(buf, sizeof(buf), "#p/%d/ctl", getpid());
+ if((ctl = open(buf, OWRITE)) < 0)
+ return;
+ }
+ write(ctl, "wired 0", 7);
+ close(ctl);
+}