diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2017-03-03 10:48:45 -0500 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2017-03-13 11:47:36 -0400 |
commit | c68aff57ce317d9f2d69d20eba893a10d964f316 (patch) | |
tree | 6f1cdb6c241ea0d65363e7bf9352555121cd60e8 /src/fw | |
parent | 1415d46dc87fd8bf1d6acd97c1ad60e893f62523 (diff) | |
download | seabios-hppa-c68aff57ce317d9f2d69d20eba893a10d964f316.zip seabios-hppa-c68aff57ce317d9f2d69d20eba893a10d964f316.tar.gz seabios-hppa-c68aff57ce317d9f2d69d20eba893a10d964f316.tar.bz2 |
resume: Don't attempt to use generic reboot mechanisms on QEMU
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>
Diffstat (limited to 'src/fw')
-rw-r--r-- | src/fw/shadow.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/src/fw/shadow.c b/src/fw/shadow.c index cd02d3a..c80b266 100644 --- a/src/fw/shadow.c +++ b/src/fw/shadow.c @@ -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"); } |