From: mia soweli <inbox@tachibana-labs.org>
To: 9front@9front.org
Subject: [9front] [PATCH] aux/acpi: support new ACPI 2.0 info for shutdown
Date: Sat, 20 May 2023 23:17:52 +0000 [thread overview]
Message-ID: <0A824F1759768F458414C771AB20B43D@tachibana-labs.org> (raw)
this involves a horrible mess, because the registers can be
in system memory, as io ports, on the embedded controller,
so we must engage aml io mapping.
---
diff f72335db09b994351eed11ec537b329903b6731a daeb5b0ab6d6342dd7d4a25ee6380f67082cfbed
--- a/sys/src/cmd/aux/acpi.c
+++ b/sys/src/cmd/aux/acpi.c
@@ -9,6 +9,7 @@
typedef struct Bat Bat;
typedef struct Tbl Tbl;
typedef struct Therm Therm;
+typedef struct FACP FACP;
struct Batstat {
int rate;
@@ -45,6 +46,31 @@
void *tmp;
};
+struct FACP {
+ int ok;
+
+ uvlong pm1a;
+ int pm1aspace;
+ int pm1awid;
+
+ uvlong pm1b;
+ int pm1bspace;
+ int pm1bwid;
+
+ uvlong gpe0;
+ ulong gpe0len;
+ int gpe0space;
+ int gpe0wid;
+
+ uvlong gpe1;
+ ulong gpe1len;
+ int gpe1space;
+ int gpe1wid;
+
+ ulong slpa;
+ ulong slpb;
+};
+
enum {
Tblsz = 4+4+1+1+6+8+4+4+4,
@@ -56,12 +82,11 @@
SLP_TM = 0x1c00,
};
-static ulong PM1a_CNT_BLK, PM1b_CNT_BLK, SLP_TYPa, SLP_TYPb;
-static ulong GPE0_BLK, GPE1_BLK, GPE0_BLK_LEN, GPE1_BLK_LEN;
-static int ec, mem, iofd[5], nbats, ntherms, facp;
+static int ec, mem, iofd[5], nbats, ntherms;
static char *uid = "pm", *units[] = {"mW", "mA"};
static Therm therms[16];
static Bat bats[4];
+static FACP facp;
static int
enumec(void *dot, void *)
@@ -240,25 +265,54 @@
close(ctl);
}
+static ulong
+get32(uchar *p)
+{
+ return p[3]<<24 | p[2]<<16 | p[1]<<8 | p[0];
+}
+
+static uvlong
+get64(uchar *p)
+{
+ return ((uvlong)p[7]<<56) | ((uvlong)p[6]<<48)
+ | ((uvlong)p[5]<<40) | ((uvlong)p[4]<<32)
+ | ((uvlong)p[3]<<24) | ((uvlong)p[2]<<16)
+ | ((uvlong)p[1]<<8) | ((uvlong)p[0]);
+}
+
static void
-outw(long addr, ushort val)
+put64(uchar *p, uvlong i)
{
- uchar buf[2];
+ p[0] = i; p[1] = i >> 8;
+ p[2] = i >> 16; p[3] = i >> 24;
+ p[4] = i >> 32; p[5] = i >> 40;
+ p[6] = i >> 48; p[7] = i >> 56;
+}
- if(addr == 0)
- return;
- buf[0] = val;
- buf[1] = val >> 8;
- pwrite(iofd[2], buf, 2, addr);
+static int
+wid2len(int wid)
+{
+ if(wid == 1)
+ return 1;
+ if(wid == 2)
+ return 2;
+ if(wid == 3)
+ return 4;
+ if(wid == 4)
+ return 8;
+
+ return 0;
}
static void
poweroff(void)
{
- int n;
+ int n, w;
void *tts, *pts;
+ Amlio ioa, iob;
+ uchar buf[8];
- if(facp == 0){
+ if(facp.ok == 0){
werrstr("no FACP");
return;
}
@@ -276,17 +330,40 @@
amleval(tts, "i", 5, nil);
/* disable GPEs */
- for(n = 0; GPE0_BLK > 0 && n < GPE0_BLK_LEN/2; n += 2){
- outw(GPE0_BLK + GPE0_BLK_LEN/2 + n, 0); /* EN */
- outw(GPE0_BLK + n, 0xffff); /* STS */
+ ioa.space = facp.gpe0space;
+ iob.space = facp.gpe1space;
+ ioa.off = facp.gpe0;
+ iob.off = facp.gpe1;
+ amlmapio(&ioa);
+ amlmapio(&iob);
+
+ w = wid2len(facp.gpe0wid);
+ for(n = 0; facp.gpe0 > 0 && n < facp.gpe0len/2; n += facp.gpe0wid){
+ memset(buf, 0, w); (*ioa.write)(&ioa, buf, w, facp.gpe0len/2 + n);
+ memset(buf, 0xff, w); (*ioa.write)(&ioa, buf, w, n);
}
- for(n = 0; GPE1_BLK > 0 && n < GPE1_BLK_LEN/2; n += 2){
- outw(GPE1_BLK + GPE1_BLK_LEN/2 + n, 0); /* EN */
- outw(GPE1_BLK + n, 0xffff); /* STS */
+
+ w = wid2len(facp.gpe1wid);
+ for(n = 0; facp.gpe1 > 0 && n < facp.gpe1len/2; n += facp.gpe1wid){
+ memset(buf, 0, w); (*iob.write)(&iob, buf, w, facp.gpe1len/2 + n);
+ memset(buf, 0xff, w); (*iob.write)(&iob, buf, w, n);
}
- outw(PM1a_CNT_BLK, ((SLP_TYPa << 10) & SLP_TM) | SLP_EN);
- outw(PM1b_CNT_BLK, ((SLP_TYPb << 10) & SLP_TM) | SLP_EN);
+ ioa.space = facp.pm1aspace;
+ iob.space = facp.pm1bspace;
+ ioa.off = facp.pm1a;
+ iob.off = facp.pm1b;
+ amlmapio(&ioa);
+ amlmapio(&iob);
+
+ w = wid2len(facp.pm1awid);
+ put64(buf, ((facp.slpa << 10) & SLP_TM) | SLP_EN);
+ (*ioa.write)(&ioa, buf, w, 0);
+
+ w = wid2len(facp.pm1bwid);
+ put64(buf, ((facp.slpb << 10) & SLP_TM) | SLP_EN);
+ (*iob.write)(&iob, buf, w, 0);
+
sleep(100);
/*
@@ -298,9 +375,15 @@
* PM1a_CNT_BLK seems to have no effect but 0x7 seems
* to work fine. So trying the following as a last effort.
*/
- SLP_TYPa |= SLP_TYPb;
- outw(PM1a_CNT_BLK, ((SLP_TYPa << 10) & SLP_TM) | SLP_EN);
- outw(PM1b_CNT_BLK, ((SLP_TYPa << 10) & SLP_TM) | SLP_EN);
+
+ facp.slpa |= facp.slpb;
+
+ w = wid2len(facp.pm1awid);
+ put64(buf, ((facp.slpa << 10) & SLP_TM) | SLP_EN);
+ (*ioa.write)(&ioa, buf, w, 0);
+ w = wid2len(facp.pm1bwid);
+ put64(buf, ((facp.slpa << 10) & SLP_TM) | SLP_EN);
+ (*iob.write)(&iob, buf, w, 0);
sleep(100);
werrstr("acpi failed");
@@ -371,12 +454,8 @@
.write = fswrite,
};
-static ulong
-get32(uchar *p)
-{
- return p[3]<<24 | p[2]<<16 | p[1]<<8 | p[0];
-}
+
void
threadmain(int argc, char **argv)
{
@@ -442,19 +521,58 @@
}else if(memcmp("SSDT", t->sig, 4) == 0){
amlload(t->data, l);
}else if(memcmp("FACP", t->sig, 4) == 0){
- facp = 1;
- 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);
+ facp.ok = 1;
+ if(t->rev >= 2) {
+ /* try the 64 bit pointers from ACPI 2.0 */
+ facp.pm1aspace = *(((uchar*)t) + 172);
+ facp.pm1awid = *(((uchar*)t) + 175);
+ facp.pm1a = get64(((uchar*)t) + 176);
+
+ facp.pm1bspace = *(((uchar*)t) + 184);
+ facp.pm1bwid = *(((uchar*)t) + 187);
+ facp.pm1b = get64(((uchar*)t) + 188);
+
+ facp.gpe0space = *(((uchar*)t) + 220);
+ facp.gpe0wid = *(((uchar*)t) + 223);
+ facp.gpe0 = get64(((uchar*)t) + 224);
+
+ facp.gpe1space = *(((uchar*)t) + 232);
+ facp.gpe1wid = *(((uchar*)t) + 235);
+ facp.gpe1 = get64(((uchar*)t) + 236);
+ }
+
+ /* fall back to ACPI 1.0 io port method */
+ if(!facp.pm1a) {
+ facp.pm1aspace = IoSpace;
+ facp.pm1awid = 2;
+ facp.pm1a = get32(((uchar*)t) + 64);
+ }
+
+ if(!facp.pm1b) {
+ facp.pm1bspace = IoSpace;
+ facp.pm1bwid = 2;
+ facp.pm1b = get32(((uchar*)t) + 68);
+ }
+
+ if(!facp.gpe0) {
+ facp.gpe0space = IoSpace;
+ facp.gpe0wid = 2;
+ facp.gpe0 = get32(((uchar*)t) + 80);
+ facp.gpe0len = *(((uchar*)t) + 92);
+ }
+
+ if(!facp.gpe1) {
+ facp.gpe1space = IoSpace;
+ facp.gpe1wid = 2;
+ facp.gpe1 = get32(((uchar*)t) + 84);
+ facp.gpe1len = *(((uchar*)t) + 93);
+ }
}
}
if(amleval(amlwalk(amlroot, "_S5"), "", &r) >= 0 && amltag(r) == 'p' && amllen(r) >= 2){
rr = amlval(r);
- SLP_TYPa = amlint(rr[0]);
- SLP_TYPb = amlint(rr[1]);
+ facp.slpa = amlint(rr[0]);
+ facp.slpb = amlint(rr[1]);
}
close(fd);
reply other threads:[~2023-05-21 13:54 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=0A824F1759768F458414C771AB20B43D@tachibana-labs.org \
--to=inbox@tachibana-labs.org \
--cc=9front@9front.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).