Try to hard-reboot on rerun of post even on emulators.
authorKevin O'Connor <kevin@koconnor.net>
Thu, 16 Sep 2010 01:48:16 +0000 (21:48 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Thu, 16 Sep 2010 01:48:16 +0000 (21:48 -0400)
Extend the hard-reboot logic to qemu and kvm.  On qemu, a reboot will
not reset the memory settings for 0xc0000-0xfffff, so copy that memory
area manually before rebooting.  Unfortunately, kvm does not keep a
pristine copy of the BIOS at 0xffff0000, so detect that case and
shutdown the machine.

Makefile
src/apm.c
src/post.c
src/shadow.c
src/util.h

index f62c1ccf766a0f19d89a4b442d60feedebe3c91b..9d412f1cd1b6c968e37973ca2e0939827e03c625 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 # SeaBIOS build system
 #
-# Copyright (C) 2008,2009  Kevin O'Connor <kevin@koconnor.net>
+# Copyright (C) 2008-2010  Kevin O'Connor <kevin@koconnor.net>
 #
 # This file may be distributed under the terms of the GNU LGPLv3 license.
 
@@ -15,8 +15,8 @@ SRCBOTH=misc.c pmm.c stacks.c output.c util.c block.c floppy.c ata.c mouse.c \
         kbd.c pci.c serial.c clock.c pic.c cdrom.c ps2port.c smp.c resume.c \
         pnpbios.c pirtable.c vgahooks.c ramdisk.c pcibios.c blockcmd.c \
         usb.c usb-uhci.c usb-ohci.c usb-ehci.c usb-hid.c usb-msc.c \
-        virtio-ring.c virtio-pci.c virtio-blk.c
-SRC16=$(SRCBOTH) system.c disk.c apm.c font.c
+        virtio-ring.c virtio-pci.c virtio-blk.c apm.c
+SRC16=$(SRCBOTH) system.c disk.c font.c
 SRC32FLAT=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \
       acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c mtrr.c \
       lzmadecode.c bootsplash.c jpeg.c usb-hub.c paravirt.c dev-i440fx.c
index 1b151e902f3c69613697417f952406c6349ae191..2029ae2487519d68ae4e1d4c44bc4c929a008cf5 100644 (file)
--- a/src/apm.c
+++ b/src/apm.c
@@ -105,6 +105,15 @@ handle_155306(struct bregs *regs)
     set_success(regs);
 }
 
+void
+apm_shutdown(void)
+{
+    irq_disable();
+    out_str("Shutdown");
+    for (;;)
+        hlt();
+}
+
 // APM Set Power State
 static void
 handle_155307(struct bregs *regs)
@@ -121,10 +130,7 @@ handle_155307(struct bregs *regs)
         out_str("Suspend");
         break;
     case 3:
-        irq_disable();
-        out_str("Shutdown");
-        for (;;)
-            hlt();
+        apm_shutdown();
         break;
     }
     set_success(regs);
index f50312ec2a2cefbe1714b07871acbc95b4cc8df8..f1ab6befaad02377ded1776cae3867d6fa0e4d97 100644 (file)
@@ -244,12 +244,21 @@ post(void)
     memmap_finalize();
 }
 
+static int HaveRunPost;
+
 // Attempt to invoke a hard-reboot.
 static void
 tryReboot(void)
 {
     dprintf(1, "Attempting a hard reboot\n");
 
+    // Setup for reset on qemu.
+    if (! CONFIG_COREBOOT) {
+        qemu_prep_reset();
+        if (HaveRunPost)
+            apm_shutdown();
+    }
+
     // Try keyboard controller reboot.
     i8042_reboot();
 
@@ -262,8 +271,6 @@ tryReboot(void)
     panic("Could not reboot");
 }
 
-static int HaveRunPost;
-
 // 32-bit entry point.
 void VISIBLE32FLAT
 _start(void)
@@ -273,15 +280,14 @@ _start(void)
     debug_serial_setup();
     dprintf(1, "Start bios (version %s)\n", VERSION);
 
-    if (CONFIG_COREBOOT && HaveRunPost)
+    if (HaveRunPost)
         // This is a soft reboot - invoke a hard reboot.
         tryReboot();
 
     // Allow writes to modify bios area (0xf0000)
     make_bios_writable();
 
-    if (CONFIG_COREBOOT)
-        HaveRunPost = 1;
+    HaveRunPost = 1;
 
     // Perform main setup code.
     post();
index 391257bfcf65cbfa107c0e17bcd707c25ffe09bf..ed530e0296548d768111db923601d0f53f27e96d 100644 (file)
@@ -136,3 +136,16 @@ make_bios_readonly(void)
         dprintf(1, "Unable to lock ram - bridge not found\n");
     }
 }
+
+void
+qemu_prep_reset(void)
+{
+    if (CONFIG_COREBOOT)
+        return;
+    // QEMU doesn't map 0xc0000-0xfffff back to the original rom on a
+    // reset, so do that manually before invoking a hard reset.
+    make_bios_writable();
+    extern u8 code32flat_start[], code32flat_end[];
+    memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET
+           , code32flat_end - code32flat_start);
+}
index 3d68d455e10e84f69c7acdfd0478f821b45041f1..d2003c162cdff4d01b51131c9a2a92de8308387d 100644 (file)
@@ -1,6 +1,6 @@
 // Basic x86 asm functions and function defs.
 //
-// Copyright (C) 2008,2009  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2008-2010  Kevin O'Connor <kevin@koconnor.net>
 //
 // This file may be distributed under the terms of the GNU LGPLv3 license.
 #ifndef __UTIL_H
@@ -327,6 +327,7 @@ void useRTC(void);
 void releaseRTC(void);
 
 // apm.c
+void apm_shutdown(void);
 void handle_1553(struct bregs *regs);
 
 // pcibios.c
@@ -338,6 +339,7 @@ void make_bios_writable(void);
 void make_bios_readonly(void);
 void make_bios_writable_intel(u16 bdf, u32 pam0);
 void make_bios_readonly_intel(u16 bdf, u32 pam0);
+void qemu_prep_reset(void);
 
 // smm.c
 void smm_save_and_copy(void);