From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=DATE_IN_PAST_12_24, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.4 Received: (qmail 32093 invoked from network); 21 May 2023 13:54:48 -0000 Received: from 9front.inri.net (168.235.81.73) by inbox.vuxu.org with ESMTPUTF8; 21 May 2023 13:54:48 -0000 Received: from one.net.tachibana-labs.org ([78.141.198.89]) by 9front; Sun May 21 09:51:46 -0400 2023 Received: from kijetesantakalu (cpc99362-croy26-2-0-cust24.19-2.cable.virginm.net [80.195.49.25]) by one.net.tachibana-labs.org (OpenSMTPD) with ESMTPSA id 659a731d (TLSv1.2:ECDHE-RSA-CHACHA20-POLY1305:256:NO) for <9front@9front.org>; Sun, 21 May 2023 13:51:34 +0000 (UTC) Message-ID: <0A824F1759768F458414C771AB20B43D@tachibana-labs.org> From: mia soweli Date: Sat, 20 May 2023 23:17:52 +0000 To: 9front@9front.org MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: WEB2.0 software session generator Subject: [9front] [PATCH] aux/acpi: support new ACPI 2.0 info for shutdown Reply-To: 9front@9front.org Precedence: bulk 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);