diff options
| -rw-r--r-- | sys/src/9/pc/main.c | 61 | ||||
| -rw-r--r-- | sys/src/9/pc/rebootcode.s | 11 | ||||
| -rw-r--r-- | sys/src/9/pc64/main.c | 49 | ||||
| -rw-r--r-- | sys/src/9/pc64/rebootcode.s | 13 |
4 files changed, 88 insertions, 46 deletions
diff --git a/sys/src/9/pc/main.c b/sys/src/9/pc/main.c index b60329776..61db6f113 100644 --- a/sys/src/9/pc/main.c +++ b/sys/src/9/pc/main.c @@ -701,34 +701,13 @@ procsave(Proc *p) mmuflushtlb(PADDR(m->pdb)); } -void -reboot(void *entry, void *code, ulong size) +static void +rebootjump(uintptr entry, uintptr code, ulong size) { - void (*f)(ulong, ulong, ulong); + void (*f)(uintptr, uintptr, ulong); ulong *pdb; - writeconf(); - vmxshutdown(); - - /* - * the boot processor is cpu0. execute this function on it - * so that the new kernel has the same cpu0. this only matters - * because the hardware has a notion of which processor was the - * boot processor and we look at it at start up. - */ - if (m->machno != 0) { - procwired(up, 0); - sched(); - } - cpushutdown(); - splhi(); - - /* turn off buffered serial console */ - serialoq = nil; - - /* shutdown devices */ - chandevshutdown(); arch->introff(); /* @@ -745,7 +724,8 @@ reboot(void *entry, void *code, ulong size) /* off we go - never to return */ coherence(); - (*f)((ulong)entry & ~0xF0000000UL, PADDR(code), size); + (*f)(entry, code, size); + for(;;); } @@ -753,5 +733,36 @@ void exit(int) { cpushutdown(); + if(m->machno) + rebootjump(0, 0, 0); arch->reset(); } + +void +reboot(void *entry, void *code, ulong size) +{ + writeconf(); + vmxshutdown(); + + /* + * the boot processor is cpu0. execute this function on it + * so that the new kernel has the same cpu0. this only matters + * because the hardware has a notion of which processor was the + * boot processor and we look at it at start up. + */ + if (m->machno != 0) { + procwired(up, 0); + sched(); + } + cpushutdown(); + delay(1000); + splhi(); + + /* turn off buffered serial console */ + serialoq = nil; + + /* shutdown devices */ + chandevshutdown(); + + rebootjump((ulong)entry & ~0xF0000000UL, PADDR(code), size); +} diff --git a/sys/src/9/pc/rebootcode.s b/sys/src/9/pc/rebootcode.s index c7d0b1991..0b4a28481 100644 --- a/sys/src/9/pc/rebootcode.s +++ b/sys/src/9/pc/rebootcode.s @@ -20,6 +20,13 @@ TEXT main(SB),$0 MOVL $0, DX MOVL DX, CR3 + /* stack below entry point */ + MOVL AX, SP + + /* park cpu for zero entry point */ + ORL AX, AX + JZ _idle + /* * the source and destination may overlap. * determine whether to copy forward or backwards @@ -52,3 +59,7 @@ _back: _startkernel: ORL AX, AX /* NOP: avoid link bug */ JMP* AX + +_idle: + HLT + JMP _idle diff --git a/sys/src/9/pc64/main.c b/sys/src/9/pc64/main.c index fc1bfeb92..dd9e2d8f2 100644 --- a/sys/src/9/pc64/main.c +++ b/sys/src/9/pc64/main.c @@ -336,18 +336,45 @@ main() schedinit(); } +static void +rebootjump(uintptr entry, uintptr code, ulong size) +{ + void (*f)(uintptr, uintptr, ulong); + + splhi(); + arch->introff(); + + /* + * This allows the reboot code to turn off the page mapping + */ + *mmuwalk(m->pml4, 0, 3, 0) = *mmuwalk(m->pml4, KZERO, 3, 0); + *mmuwalk(m->pml4, 0, 2, 0) = *mmuwalk(m->pml4, KZERO, 2, 0); + mmuflushtlb(); + + /* setup reboot trampoline function */ + f = (void*)REBOOTADDR; + memmove(f, rebootcode, sizeof(rebootcode)); + + /* off we go - never to return */ + coherence(); + (*f)(entry, code, size); + + for(;;); +} + + void exit(int) { cpushutdown(); + if(m->machno) + rebootjump(0, 0, 0); arch->reset(); } void reboot(void *entry, void *code, ulong size) { - void (*f)(uintptr, uintptr, ulong); - writeconf(); vmxshutdown(); @@ -362,7 +389,7 @@ reboot(void *entry, void *code, ulong size) sched(); } cpushutdown(); - + delay(1000); splhi(); /* turn off buffered serial console */ @@ -370,22 +397,8 @@ reboot(void *entry, void *code, ulong size) /* shutdown devices */ chandevshutdown(); - arch->introff(); - - /* - * This allows the reboot code to turn off the page mapping - */ - *mmuwalk(m->pml4, 0, 3, 0) = *mmuwalk(m->pml4, KZERO, 3, 0); - *mmuwalk(m->pml4, 0, 2, 0) = *mmuwalk(m->pml4, KZERO, 2, 0); - mmuflushtlb(); - - /* setup reboot trampoline function */ - f = (void*)REBOOTADDR; - memmove(f, rebootcode, sizeof(rebootcode)); - /* off we go - never to return */ - coherence(); - (*f)((uintptr)entry & ~0xF0000000UL, (uintptr)PADDR(code), size); + rebootjump((uintptr)entry & ~0xF0000000UL, PADDR(code), size); } /* diff --git a/sys/src/9/pc64/rebootcode.s b/sys/src/9/pc64/rebootcode.s index 7b6d150f1..91c3c788d 100644 --- a/sys/src/9/pc64/rebootcode.s +++ b/sys/src/9/pc64/rebootcode.s @@ -20,9 +20,6 @@ TEXT main(SB), 1, $-4 MOVL $_gdtptr64p<>(SB), AX MOVL (AX), GDTR - /* move stack below destination */ - MOVL DI, SP - /* load CS with 32bit code segment */ PUSHQ $SELECTOR(3, SELGDT, 0) PUSHQ $_warp32<>(SB) @@ -61,6 +58,12 @@ TEXT _warp32<>(SB), 1, $-4 MOVL BX, CX /* byte count */ MOVL DI, AX /* save entry point */ + MOVL AX, SP /* move stack below entry */ + + /* park cpu for zero entry point */ + ORL AX, AX + JZ _idle + /* * the source and destination may overlap. @@ -90,6 +93,10 @@ _back: REP; MOVSB JMP _startkernel +_idle: + HLT + JMP _idle + TEXT _gdt<>(SB), 1, $-4 /* null descriptor */ LONG $0 |
