[SeaBIOS] [PATCH 07/11] Try to hard-reboot on rerun of post even on emulators.

Kevin O'Connor kevin at koconnor.net
Thu Sep 16 04:37:57 CEST 2010


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     |    6 +++---
 src/apm.c    |   14 ++++++++++----
 src/post.c   |   16 +++++++++++-----
 src/shadow.c |   13 +++++++++++++
 src/util.h   |    4 +++-
 5 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/Makefile b/Makefile
index f62c1cc..9d412f1 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 # SeaBIOS build system
 #
-# Copyright (C) 2008,2009  Kevin O'Connor <kevin at koconnor.net>
+# Copyright (C) 2008-2010  Kevin O'Connor <kevin at 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
diff --git a/src/apm.c b/src/apm.c
index 1b151e9..2029ae2 100644
--- 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);
diff --git a/src/post.c b/src/post.c
index f50312e..f1ab6be 100644
--- a/src/post.c
+++ b/src/post.c
@@ -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();
diff --git a/src/shadow.c b/src/shadow.c
index 391257b..ed530e0 100644
--- a/src/shadow.c
+++ b/src/shadow.c
@@ -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);
+}
diff --git a/src/util.h b/src/util.h
index 3d68d45..d2003c1 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,6 +1,6 @@
 // Basic x86 asm functions and function defs.
 //
-// Copyright (C) 2008,2009  Kevin O'Connor <kevin at koconnor.net>
+// Copyright (C) 2008-2010  Kevin O'Connor <kevin at 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);
-- 
1.7.2.3




More information about the SeaBIOS mailing list