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@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 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@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);