The HaveRunPost flag controls whether post or reboot handling is entered on a reset signal. The flag needs to be set before any other global variable because an external reboot signal could occur at any time. (If any global variable is modified prior to setting HaveRunPost then the code might enter post with global variables in a dirty state.)
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/fw/csm.c | 1 + src/fw/shadow.c | 2 ++ src/fw/xen.c | 1 + src/post.c | 20 ++++++++++++++++---- src/util.h | 1 + 5 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/src/fw/csm.c b/src/fw/csm.c index 7cadd12..b01f181 100644 --- a/src/fw/csm.c +++ b/src/fw/csm.c @@ -289,6 +289,7 @@ handle_csm(struct bregs *regs)
dprintf(3, "handle_csm regs %p AX=%04x\n", regs, regs->ax);
+ code_mutable_preinit(); pic_irqmask_write(PICMask);
switch(regs->ax) { diff --git a/src/fw/shadow.c b/src/fw/shadow.c index 4486884..bdb5c5b 100644 --- a/src/fw/shadow.c +++ b/src/fw/shadow.c @@ -123,12 +123,14 @@ make_bios_writable(void) if (vendor == PCI_VENDOR_ID_INTEL && device == PCI_DEVICE_ID_INTEL_82441) { make_bios_writable_intel(bdf, I440FX_PAM0); + code_mutable_preinit(); ShadowBDF = bdf; return; } if (vendor == PCI_VENDOR_ID_INTEL && device == PCI_DEVICE_ID_INTEL_Q35_MCH) { make_bios_writable_intel(bdf, Q35_HOST_BRIDGE_PAM0); + code_mutable_preinit(); ShadowBDF = bdf; return; } diff --git a/src/fw/xen.c b/src/fw/xen.c index 3f19ef2..a215b9e 100644 --- a/src/fw/xen.c +++ b/src/fw/xen.c @@ -71,6 +71,7 @@ void xen_preinit(void) signature, base); if (strcmp(signature, "XenVMMXenVMM") == 0) { /* Set debug_io_port first, so the following messages work. */ + code_mutable_preinit(); DebugOutputPort = 0xe9; debug_banner(); dprintf(1, "\nFound Xen hypervisor signature at %x\n", base); diff --git a/src/post.c b/src/post.c index 49c22b8..e5fa4be 100644 --- a/src/post.c +++ b/src/post.c @@ -41,10 +41,6 @@ ivt_init(void) { dprintf(3, "init ivt\n");
- // Setup reset-vector entry point (controls legacy reboots). - HaveRunPost = 1; - rtc_write(CMOS_RESET_CODE, 0); - // Initialize all vectors to the default handler. int i; for (i=0; i<256; i++) @@ -304,10 +300,26 @@ reloc_preinit(void *f, void *arg) func(arg); }
+// Runs after all code is present and prior to any modifications +void +code_mutable_preinit(void) +{ + if (HaveRunPost) + // Already run + return; + // Setup reset-vector entry point (controls legacy reboots). + rtc_write(CMOS_RESET_CODE, 0); + barrier(); + HaveRunPost = 1; + barrier(); +} + // Setup for code relocation and then relocate. void VISIBLE32INIT dopost(void) { + code_mutable_preinit(); + // Detect ram and setup internal malloc. qemu_preinit(); coreboot_preinit(); diff --git a/src/util.h b/src/util.h index 76db57f..43f2199 100644 --- a/src/util.h +++ b/src/util.h @@ -223,6 +223,7 @@ void device_hardware_setup(void); void prepareboot(void); void startBoot(void); void reloc_preinit(void *f, void *arg); +void code_mutable_preinit(void);
// serial.c void serial_setup(void);