summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2010-09-15 21:48:16 -0400
committerKevin O'Connor <kevin@koconnor.net>2010-09-15 21:48:16 -0400
commit244caf86f11f5f65d166d91704f64cb673167abc (patch)
treeeb0f32c8469d15625ad34ebc3c4fec6068a767e9
parent5bd01de26257849f36d361018c3ec17aa29b0218 (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--Makefile6
-rw-r--r--src/apm.c14
-rw-r--r--src/post.c16
-rw-r--r--src/shadow.c13
-rw-r--r--src/util.h4
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);