diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2010-09-15 21:48:16 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2010-09-15 21:48:16 -0400 |
commit | 244caf86f11f5f65d166d91704f64cb673167abc (patch) | |
tree | eb0f32c8469d15625ad34ebc3c4fec6068a767e9 | |
parent | 5bd01de26257849f36d361018c3ec17aa29b0218 (diff) |
Try to hard-reboot on rerun of post even on emulators.
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.
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | src/apm.c | 14 | ||||
-rw-r--r-- | src/post.c | 16 | ||||
-rw-r--r-- | src/shadow.c | 13 | ||||
-rw-r--r-- | src/util.h | 4 |
5 files changed, 40 insertions, 13 deletions
@@ -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 @@ -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); @@ -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); +} @@ -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); |