]> xenbits.xensource.com Git - seabios.git/commitdiff
resume: Don't attempt to use generic reboot mechanisms on QEMU
authorKevin O'Connor <kevin@koconnor.net>
Fri, 3 Mar 2017 15:48:45 +0000 (10:48 -0500)
committerGerd Hoffmann <kraxel@redhat.com>
Tue, 14 Mar 2017 10:20:34 +0000 (11:20 +0100)
On QEMU it's necessary to manually reset the BIOS memory region
between 0xc0000-0x100000 on a reboot.  After this manual memory reset
is completed, it's not valid to use the generic reset mechanisms.
Rename qemu_prep_reset() to qemu_reboot() and change the function to
immediately reboot after the code memcpy.

This fixes a bug that could cause code corruption on reboots - calling
the udelay() function (as invoked by i8042_reboot and/or pci_reboot)
was not valid after the BIOS was memcpy'd.

Reported-by: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Tested-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
(cherry picked from commit c68aff57ce317d9f2d69d20eba893a10d964f316)

src/fw/shadow.c
src/hw/pci.c
src/hw/pci.h
src/resume.c
src/util.h

index cd02d3abff5e1dd2a56a832dcb6041d75614dd09..c80b266ba3d370fc6ab2c1d46a2243527d022ef7 100644 (file)
@@ -167,7 +167,7 @@ make_bios_readonly(void)
 }
 
 void
-qemu_prep_reset(void)
+qemu_reboot(void)
 {
     if (!CONFIG_QEMU || runningOnXen())
         return;
@@ -187,4 +187,16 @@ qemu_prep_reset(void)
     memcpy(hrp + 4, hrp + 4 + BIOS_SRC_OFFSET, cend - (hrp + 4));
     barrier();
     HaveRunPost = 0;
+    barrier();
+
+    // Request a QEMU system reset.  Do the reset in this function as
+    // the BIOS code was overwritten above and not all BIOS
+    // functionality may be available.
+
+    // Attempt PCI style reset
+    outb(0x02, PORT_PCI_REBOOT);
+    outb(0x06, PORT_PCI_REBOOT);
+
+    // Next try triple faulting the CPU to force a reset
+    asm volatile("int3");
 }
index 506ee563e7a1dc472b71ee827bf567d43cb85905..8e3d617935754697217875f2bcf4e8921409927b 100644 (file)
@@ -12,7 +12,6 @@
 #include "x86.h" // outl
 
 #define PORT_PCI_CMD           0x0cf8
-#define PORT_PCI_REBOOT        0x0cf9
 #define PORT_PCI_DATA          0x0cfc
 
 void pci_config_writel(u16 bdf, u32 addr, u32 val)
index bf50430349672c93d4c0a66f05dfb9df91cb325d..ee6e19686a81728831893e566b2e9c36c6b4e44c 100644 (file)
@@ -3,6 +3,8 @@
 
 #include "types.h" // u32
 
+#define PORT_PCI_REBOOT        0x0cf9
+
 static inline u8 pci_bdf_to_bus(u16 bdf) {
     return bdf >> 8;
 }
index 99fa34faedd11686c742aa6eb27f87cc132d638b..fb0b8a89e614aad40bca6ce2f3efe10abb2fbf72 100644 (file)
@@ -125,8 +125,8 @@ tryReboot(void)
 {
     dprintf(1, "Attempting a hard reboot\n");
 
-    // Setup for reset on qemu.
-    qemu_prep_reset();
+    // Use a QEMU specific reboot on QEMU
+    qemu_reboot();
 
     // Reboot using ACPI RESET_REG
     acpi_reboot();
index 557eb8b0d085beb6b3900fb2c7cbc0a1dda5bfb2..1dfe46381bac4bbea62e9cd3e9e3eb5734fcf098 100644 (file)
@@ -122,7 +122,7 @@ void pirtable_setup(void);
 // fw/shadow.c
 void make_bios_writable(void);
 void make_bios_readonly(void);
-void qemu_prep_reset(void);
+void qemu_reboot(void);
 
 // fw/smbios.c
 void smbios_legacy_setup(void);