diff 728cb9011f9612e969ec8747aa1de2a30959c38a uncommitted --- 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 @@ -33,14 +32,8 @@ h=`{ls /srv/hjfs*cmd >[2]/dev/null} s=`{awk '/^sd./ && /nvme/ {print substr($1,3,1)}' <'#S/sdctl' >[2]/dev/null} -# for scram, don't scram other systems +# don't halt 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,11 @@ exit 'failed to copy kernel' bootf=/bin/bootf } +if not { + mkdir /tmp/aux + cp /bin/aux/acpi /tmp/aux +} + bind /tmp /rc bind /tmp /bin @@ -88,8 +85,8 @@ if not { if (test -e /dev/pmctl) echo power off >>/dev/pmctl - if (~ $scram yes) - scram + + aux/acpi -H echo 'It''s now safe to turn off your computer' } } --- a/sys/man/8/fshalt +++ b/sys/man/8/fshalt @@ -1,6 +1,6 @@ .TH FSHALT 8 .SH NAME -fshalt, scram, reboot \- halt any local file systems and optionally shut down or reboot the system +fshalt, reboot \- halt any local file systems and optionally shut down or reboot the system .SH SYNOPSIS .B fshalt [ @@ -14,8 +14,6 @@ [ .I kernelpath ] -.br -.B scram .SH DESCRIPTION .I Fshalt syncs and halts all local @@ -30,9 +28,7 @@ optionally starting .IR kernelpath . Else it will try to shut down the machine through -.I /dev/pmctl -(if available) or invoke -.IR scram . +.IR /dev/pmctl . The halting and rebooting is done by copying all necessary commands into a .IR ramfs (4) @@ -48,24 +44,22 @@ kernel directly instead of returning to the system rom. (see .IR cons (3)). .PP -.I Scram -shuts down the machine it is invoked on. .SH SOURCE .B /rc/bin/fshalt .br .B /rc/bin/reboot -.br -.B /sys/src/cmd/scram.c .SH SEE ALSO +.IR acpi (8), .IR cons (3), .IR reboot (8) .SH BUGS -On standalone machines, it will be impossible to do anything if scram fails -after invoking bare +On standalone machines, it will be impossible to do anything if +power off fails after invoking bare .IR fshalt . -.I Scram -is limited to the PC and requires APM or ACPI. -.SH HISTORY -.I Scram -first appeared in 9front (May, 2011). +.I Fshalt +falls back to trying +.I aux/acpi +if writing to +.B /dev/pmctl +fails. binary files /dev/null b/sys/src/cmd/aux/6.acpi differ binary files /dev/null b/sys/src/cmd/aux/acpi.6 differ --- a/sys/src/cmd/scram.c +++ /dev/null @@ -1,183 +1,0 @@ -#include -#include -#include -#include - -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"); -}