patch: power off
Tetsuya Isaki <[email protected]> Sun, 23 Mar 2014 19:16:11 +0900
| Newsgroups | gmane.os.netbsd.ports.x68k |
|---|---|
| Message-ID | <x7ppldz0d0.wl%[email protected]> |
Hi, Current x68k kernel supports software power-off (by sysmon(4)), but in fact, the kernel does not turn off the power. Power off is happened in IPLROM after software reset. So, I wrote a patch that the kernel does power off itself. Any comments? I have tested only on XM6i because my X68030 has failed. I'm happy if someone could test it on the real machine. # By the way, if you are using my x68k-pxhtc-yyyymmdd.diff patch # on XM6i, you can use these patches at the same time, by rewriting # WITH_PXHTC to 1 in following patch. --- Tetsuya Isaki <[email protected] / [email protected]> Index: sys/arch/x68k/x68k/locore.s =================================================================== RCS file: /cvsroot/src/sys/arch/x68k/x68k/locore.s,v retrieving revision 1.117 diff -u -r1.117 locore.s --- sys/arch/x68k/x68k/locore.s 22 Mar 2014 21:49:18 -0000 1.117 +++ sys/arch/x68k/x68k/locore.s 23 Mar 2014 10:01:35 -0000 @@ -898,7 +898,14 @@ * is turned off. We have conveniently mapped the last page of physical * memory this way. */ +ENTRY_NOPROFILE(dopoweroff) + movql #1,%d1 | shutdown + bra Ldoboot_main + ENTRY_NOPROFILE(doboot) + movql #0,%d1 | reboot + +Ldoboot_main: movw #PSL_HIGHIPL,%sr | cut off any interrupts subal %a1,%a1 | a1 = 0 @@ -915,18 +922,43 @@ movc %d0,%cacr | disable on-chip cache(s) | ok, turn off MMU.. -Ldoreboot: #if defined(M68040) || defined(M68060) tstl %d2 | 68040? jne LmotommuF | no, skip movc %a1,%cacr | caches off .long 0x4e7b9003 | movc a1(=0),tc ; disable MMU - jra Ldoreboot1 + jra Ldoboot1 LmotommuF: #endif clrl %sp@ pmove %sp@,%tc | disable MMU -Ldoreboot1: + +Ldoboot1: + /* Reset the stack pointer after MMU disabled */ + subal %a5,%a5 | XXX firstpa=0 because PA==VA + ASRELOC(tmpstk, %a0) + movl %a0,%sp + + tstl %d1 | %d1 = shutdown or reboot + beq Ldoreboot + + leal 0xe8e00f,%a0 | write a power-off sequence + movb #0x00,%a0@ | to system port + movb #0x0f,%a0@ + movb #0x0f,%a0@ + + movl #1000000,%sp@- | wait a bit +#define WITH_PXHTC 0 +#if WITH_PXHTC /* with pxhtc patch, delay is a pointer to function */ + RELOC(delay, %a0) + moval %a0@,%a0 + jsr %a0@ +#else /* without pxhtc patch, delay is local label */ + bsr _delay +#endif + /* PASSTHROUGH */ | passthrough even if came back + +Ldoreboot: moveml 0x00ff0000,#0x0101 | get RESET vectors in ROM | (d0: ssp, a0: pc) moveml #0x0101,%a1@ | put them at 0x0000 (for Xellent30) Index: sys/arch/x68k/x68k/machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/x68k/x68k/machdep.c,v retrieving revision 1.188 diff -u -r1.188 machdep.c --- sys/arch/x68k/x68k/machdep.c 22 Mar 2014 21:49:18 -0000 1.188 +++ sys/arch/x68k/x68k/machdep.c 23 Mar 2014 10:01:36 -0000 @@ -108,6 +108,7 @@ #include <arch/x68k/dev/intiovar.h> extern void doboot(void) __attribute__((__noreturn__)); +extern void dopoweroff(void) __attribute__((__noreturn__)); /* the following is used externally (sysctl_hw) */ char machine[] = MACHINE; /* from <machine/param.h> */ @@ -523,10 +524,9 @@ * c) otherwise * Reboot */ - if (((howto & RB_POWERDOWN) == RB_POWERDOWN) && power_switch_is_off) - doboot(); - else if (/*((howto & RB_POWERDOWN) == RB_POWERDOWN) ||*/ - ((howto & RB_HALT) == RB_HALT)) { + if (((howto & RB_POWERDOWN) == RB_POWERDOWN) && power_switch_is_off) { + dopoweroff(); + } else if ((howto & RB_HALT) == RB_HALT) { printf("System halted. Hit any key to reboot.\n\n"); (void)cngetc(); }