]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/scram.c
scram: acpi scram for qemu fix
[plan9front.git] / sys / src / cmd / scram.c
1 #include <u.h>
2 #include </386/include/ureg.h>
3 #include <libc.h>
4 #include <aml.h>
5
6 int fd, iofd;
7 struct Ureg u;
8 ulong PM1A_CNT_BLK, PM1B_CNT_BLK, SLP_TYPa, SLP_TYPb;
9
10 typedef struct Tbl Tbl;
11 struct Tbl {
12         uchar   sig[4];
13         uchar   len[4];
14         uchar   rev;
15         uchar   csum;
16         uchar   oemid[6];
17         uchar   oemtid[8];
18         uchar   oemrev[4];
19         uchar   cid[4];
20         uchar   crev[4];
21         uchar   data[];
22 };
23
24 void*
25 amlalloc(int n){
26         return mallocz(n, 1);
27 }
28
29 void
30 amlfree(void *p){
31         free(p);
32 }
33
34 static ulong
35 get32(uchar *p){
36         return p[3]<<24 | p[2]<<16 | p[1]<<8 | p[0];
37 }
38
39 void
40 apm(void)
41 {
42         seek(fd, 0, 0);
43         if(write(fd, &u, sizeof u) < 0)
44                 sysfatal("write: %r");
45         seek(fd, 0, 0);
46         if(read(fd, &u, sizeof u) < 0)
47                 sysfatal("read: %r");
48         if(u.flags & 1)
49                 sysfatal("apm: %lux", (u.ax>>8) & 0xFF);
50 }
51
52 int
53 loadacpi(void)
54 {
55         void *r, **rr;
56         Tbl *t;
57         int n;
58         ulong l;
59
60         amlinit();
61         for(;;){
62                 t = malloc(sizeof(*t));
63                 if((n = readn(fd, t, sizeof(*t))) <= 0)
64                         break;
65                 if(n != sizeof(*t))
66                         return -1;
67                 l = get32(t->len);
68                 if(l < sizeof(*t))
69                         return -1;
70                 t = realloc(t, l);
71                 l -= sizeof(*t);
72                 if(readn(fd, t->data, l) != l)
73                         return -1;
74                 if(memcmp("DSDT", t->sig, 4) == 0)
75                         amlload(t->data, l);
76                 else if(memcmp("SSDT", t->sig, 4) == 0)
77                         amlload(t->data, l);
78                 else if(memcmp("FACP", t->sig, 4) == 0){
79                         PM1A_CNT_BLK = get32(((uchar*)t) + 64);
80                         PM1B_CNT_BLK = get32(((uchar*)t) + 68);
81                 }
82         }
83         if(PM1A_CNT_BLK == 0)
84                 return -1;
85         if(amleval(amlwalk(amlroot, "_S5"), "", &r) < 0)
86                 return -1;
87         if(amltag(r) != 'p' || amllen(r) < 2)
88                 return -1;
89         rr = amlval(r);
90         SLP_TYPa = (amlint(rr[1]) & 0xFF) << 10;
91         SLP_TYPb = ((amlint(rr[1]) >> 8) & 0xFF) << 10;
92         return 0;
93 }
94
95 void
96 outw(long addr, short val)
97 {
98         uchar buf[2];
99         
100         buf[0] = val;
101         buf[1] = val >> 8;
102         pwrite(iofd, buf, 2, addr);
103 }
104
105 void
106 main()
107 {
108         if((fd = open("/dev/apm", ORDWR)) < 0)
109                 if((fd = open("#P/apm", ORDWR)) < 0)
110                         goto tryacpi;
111
112         u.ax = 0x530E;
113         u.bx = 0x0000;
114         u.cx = 0x0102;
115         apm();
116         u.ax = 0x5307;
117         u.bx = 0x0001;
118         u.cx = 0x0003;
119         apm();
120         
121 tryacpi:
122         if((fd = open("/dev/acpitbls", OREAD)) < 0)
123                 if((fd = open("#P/acpitbls", OREAD)) < 0)
124                         goto fail;
125         if((iofd = open("/dev/iow", OWRITE)) < 0)
126                 if((iofd = open("#P/iow", OWRITE)) < 0)
127                         goto fail;
128         if(loadacpi() < 0)
129                 goto fail;
130         outw(PM1A_CNT_BLK, SLP_TYPa | 0x2000);
131         if(PM1B_CNT_BLK != 0)
132                 outw(PM1B_CNT_BLK, SLP_TYPb | 0x2000);
133 fail:
134         ;
135 }