shithub: riscv

Download patch

ref: 25319382697878e01b9949afb33fcc6f4c4e6e1d
parent: 728cb9011f9612e969ec8747aa1de2a30959c38a
author: mia soweli <inbox@tachibana-labs.org>
date: Sun Jun 4 09:52:05 EDT 2023

scram: → /rc/bin/scram

no need for scram to be a c program and duplicate the acpi shutdown code.
try writing power off to /dev/pmctl or fall back to the new -H flag
for aux/acpi.

--- a/rc/bin/fshalt
+++ b/rc/bin/fshalt
@@ -3,7 +3,6 @@
 #	and optionally reboot
 rfork en
 reboot=no
-scram=no
 bootf=()
 if(~ $1 -r){
 	reboot=yes
@@ -35,12 +34,6 @@
 
 # for scram, don't scram other systems
 bind -b '#P' /dev >[2]/dev/null
-if(! ~ $reboot yes){
-	if(test -e '#P'/apm)
-		scram=yes
-	if(test -e '#P'/acpitbls -a -e '#P'/iow)
-		scram=yes
-}
 
 # halting (binaries we run can't be on the fs we're halting)
 ramfs
@@ -52,7 +45,6 @@
 cp /bin/rc /tmp
 cp /bin/sed /tmp
 cp /bin/sleep /tmp
-cp /bin/scram /tmp
 cp /bin/test /tmp
 if(~ $#bootf 1){
 	if(! cp $bootf /tmp/bootf)
@@ -59,6 +51,12 @@
 		exit 'failed to copy kernel'
 	bootf=/bin/bootf
 }
+if not {
+	mkdir /tmp/aux
+	cp /bin/aux/acpi /tmp/aux
+	cp /bin/scram /tmp
+}
+
 bind /tmp /rc
 bind /tmp /bin
 
@@ -86,10 +84,7 @@
 		echo reboot $bootf >'#c/reboot'
 	}
 	if not {
-		if (test -e /dev/pmctl)
-			echo power off >>/dev/pmctl
-		if (~ $scram yes)
-			scram
+		scram
 		echo 'It''s now safe to turn off your computer'
 	}
 }
--- /dev/null
+++ b/rc/bin/scram
@@ -1,0 +1,5 @@
+#!/bin/rc
+if(test -e /dev/pmctl)
+	echo power off >>/dev/pmctl
+
+aux/acpi -H
--- a/sys/man/8/fshalt
+++ b/sys/man/8/fshalt
@@ -49,14 +49,18 @@
 .IR cons (3)).
 .PP
 .I Scram
-shuts down the machine it is invoked on.
+shuts down the machine it is invoked on by writing
+.I power off
+to
+.BR /dev/pmctl .
 .SH SOURCE
 .B /rc/bin/fshalt
 .br
 .B /rc/bin/reboot
 .br
-.B /sys/src/cmd/scram.c
+.B /rc/bin/scram
 .SH SEE ALSO
+.IR acpi (8),
 .IR cons (3),
 .IR reboot (8)
 .SH BUGS
@@ -65,7 +69,12 @@
 .IR fshalt .
 
 .I Scram
-is limited to the PC and requires APM or ACPI.
+falls back to trying
+.I aux/acpi
+if writing to
+.B /dev/pmctl
+fails.
+
 .SH HISTORY
 .I Scram
 first appeared in 9front (May, 2011).
--- a/sys/src/cmd/scram.c
+++ /dev/null
@@ -1,183 +1,0 @@
-#include <u.h>
-#include </386/include/ureg.h>
-#include <libc.h>
-#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)
-		return;
-	write(ctl, "wired 0", 7);
-	close(ctl);
-}
-
-void
-main(void)
-{
-	int n;
-
-	wirecpu0();
-
-	if((fd = open("/dev/apm", ORDWR)) < 0)
-		if((fd = open("#P/apm", ORDWR)) < 0)
-			goto tryacpi;
-
-	u.ax = 0x530E;
-	u.bx = 0x0000;
-	u.cx = 0x0102;
-	apm();
-	u.ax = 0x5307;
-	u.bx = 0x0001;
-	u.cx = 0x0003;
-	apm();
-	
-tryacpi:
-	if((fd = open("/dev/acpitbls", OREAD)) < 0)
-		if((fd = open("#P/acpitbls", OREAD)) < 0)
-			goto fail;
-	if((iofd = open("/dev/iow", OWRITE)) < 0)
-		if((iofd = open("#P/iow", OWRITE)) < 0)
-			goto fail;
-	if(loadacpi() < 0)
-		goto fail;
-
-	/* 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 */
-	}
-	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 */
-	}
-
-	outw(PM1a_CNT_BLK, ((SLP_TYPa << 10) & SLP_TM) | SLP_EN);
-	outw(PM1b_CNT_BLK, ((SLP_TYPb << 10) & SLP_TM) | SLP_EN);
-	sleep(100);
-
-	/*
-	 * The SetSystemSleeping() example from the ACPI spec 
-	 * writes the same value in both registers. But Linux/BSD
-	 * write distinct values from the _Sx package (like the
-	 * code above). The _S5 package on a HP DC5700 is
-	 * Package(0x2){0x0, 0x7} and writing SLP_TYPa of 0 to
-	 * 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);
-	sleep(100);
-
-fail:
-	exits("scram");
-}