summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/9/pc/main.c61
-rw-r--r--sys/src/9/pc/rebootcode.s11
-rw-r--r--sys/src/9/pc64/main.c49
-rw-r--r--sys/src/9/pc64/rebootcode.s13
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