diff --git a/src/system/boot/platform/bios_ia32/smp.cpp b/src/system/boot/platform/bios_ia32/smp.cpp index fc2b766167..105bc7e945 100644 --- a/src/system/boot/platform/bios_ia32/smp.cpp +++ b/src/system/boot/platform/bios_ia32/smp.cpp @@ -565,6 +565,13 @@ dprintf("wait for delivery\n"); while ((apic_read(APIC_INTR_COMMAND_1) & APIC_DELIVERY_STATUS) != 0) asm volatile ("pause;"); } + + // Wait for the trampoline code to clear the final stack location. + // This serves as a notification for us that it has loaded the address + // and it is safe for us to overwrite it to trampoline the next CPU. + tempStack++; + while (*tempStack != 0) + spin(1000); } TRACE(("done trampolining\n")); diff --git a/src/system/boot/platform/bios_ia32/smp_trampoline.S b/src/system/boot/platform/bios_ia32/smp_trampoline.S index 480f453b57..33a5ced675 100644 --- a/src/system/boot/platform/bios_ia32/smp_trampoline.S +++ b/src/system/boot/platform/bios_ia32/smp_trampoline.S @@ -47,6 +47,11 @@ trampoline_32: movl %eax,%cr3 # set the page dir popl %eax # get the final stack location + + // Clear the final stack location to notify the startup code that + // we loaded the address and it is now safe to be overwritten. + pushl $0x00000000 + movl %eax,%esp // load an address for an indirect jump