Port-x68k archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: patch: power off
> 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?
Basically looks good, but I have some dumb comments. (see below)
> I have tested only on XM6i because my X68030 has failed. I'm
> happy if someone could test it on the real machine.
Powerdown after turning the power switch off just works on my X68030.
> +ENTRY_NOPROFILE(dopoweroff)
> + movql #1,%d1 | shutdown
> + bra Ldoboot_main
> +
> ENTRY_NOPROFILE(doboot)
> + movql #0,%d1 | reboot
> +
> +Ldoboot_main:
It would be better to make doboot() take "howto" arg rather than
having different entry points. (patch attached)
> +#else /* without pxhtc patch, delay is local label */
> + bsr _delay
_ASM_LABEL(_delay) is more explicit for a function call.
> - 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();
> }
I wonder if the system port for powerdown can be accessed even before
the MMU is turned off.
If so, we can prepare a "poweroff" function and call it in cpu_reboot()
before calling doboot() like macppc does:
http://nxr.netbsd.org/xref/src/sys/arch/macppc/macppc/machdep.c?r=1.164#202
---
Index: x68k/locore.s
===================================================================
RCS file: /cvsroot/src/sys/arch/x68k/x68k/locore.s,v
retrieving revision 1.117
diff -u -p -d -r1.117 locore.s
--- x68k/locore.s 22 Mar 2014 21:49:18 -0000 1.117
+++ x68k/locore.s 23 Mar 2014 15:20:45 -0000
@@ -899,6 +899,7 @@ L_delay:
* memory this way.
*/
ENTRY_NOPROFILE(doboot)
+ movl %sp@(4),%d1 | save "howto" arg
movw #PSL_HIGHIPL,%sr | cut off any interrupts
subal %a1,%a1 | a1 = 0
@@ -915,18 +916,44 @@ Ldoboot0:
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
+
+ andl #0x800,%d1
+ tstl %d1 | if ((howto & RB_POWERDOWN) == 0)
+ beq Ldoreboot | then reboot
+
+ 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 _ASM_LABEL(_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: x68k/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x68k/x68k/machdep.c,v
retrieving revision 1.188
diff -u -p -d -r1.188 machdep.c
--- x68k/machdep.c 22 Mar 2014 21:49:18 -0000 1.188
+++ x68k/machdep.c 23 Mar 2014 15:20:45 -0000
@@ -107,7 +107,7 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v
#include <machine/autoconf.h>
#include <arch/x68k/dev/intiovar.h>
-extern void doboot(void) __attribute__((__noreturn__));
+extern void doboot(int) __attribute__((__noreturn__));
/* the following is used externally (sysctl_hw) */
char machine[] = MACHINE; /* from <machine/param.h> */
@@ -517,23 +517,22 @@ cpu_reboot(int howto, char *bootstr)
* Power cannot be removed; simply halt the system (b)
* Power switch state is checked in shutdown hook
* a2: the power switch is off
- * Remove the power; the simplest way is go back to ROM eg. reboot
+ * Remove power by power-off sequence via system port in doboot()
* b) RB_HALT
* call cngetc
* 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) {
+ doboot(RB_POWERDOWN);
+ } else if ((howto & RB_HALT) == RB_HALT) {
printf("System halted. Hit any key to reboot.\n\n");
(void)cngetc();
}
printf("rebooting...\n");
DELAY(1000000);
- doboot();
+ doboot(RB_AUTOBOOT);
/* NOTREACHED */
}
---
Izumi Tsutsui
Home |
Main Index |
Thread Index |
Old Index