return;
// QEMU doesn't map 0xc0000-0xfffff back to the original rom on a
// reset, so do that manually before invoking a hard reset.
+ void *cstart = VSYMBOL(code32flat_start), *cend = VSYMBOL(code32flat_end);
+ void *hrp = &HaveRunPost;
+ if (readl(hrp + BIOS_SRC_OFFSET)) {
+ // Some old versions of KVM don't store a pristine copy of the
+ // BIOS in high memory. Try to shutdown the machine instead.
+ dprintf(1, "Unable to hard-reboot machine - attempting shutdown.\n");
+ apm_shutdown();
+ }
+ // Copy the BIOS making sure to only reset HaveRunPost at end
make_bios_writable();
- memcpy(VSYMBOL(code32flat_start), VSYMBOL(code32flat_start) + BIOS_SRC_OFFSET
- , SYMBOL(code32flat_end) - SYMBOL(code32flat_start));
+ memcpy(cstart, cstart + BIOS_SRC_OFFSET, hrp - cstart);
+ memcpy(hrp + 4, hrp + 4 + BIOS_SRC_OFFSET, cend - (hrp + 4));
+ barrier();
+ HaveRunPost = 0;
}
farcall16big(&br);
}
-u8 HaveAttemptedReboot VARLOW;
-
// Attempt to invoke a hard-reboot.
static void
tryReboot(void)
{
- if (HaveAttemptedReboot) {
- // Hard reboot has failed - try to shutdown machine.
- dprintf(1, "Unable to hard-reboot machine - attempting shutdown.\n");
- apm_shutdown();
- }
- HaveAttemptedReboot = 1;
-
dprintf(1, "Attempting a hard reboot\n");
// Setup for reset on qemu.