On Mon, 2013-02-18 at 17:37 -0500, Kevin O'Connor wrote: > On Mon, Feb 18, 2013 at 09:12:46PM +0000, David Woodhouse wrote: > > The i440fx data sheet (ยง3.0) appears to say that the default values are > > loaded on a *hard* reset, not a soft reset. And a reset invoked by the > > keyboard controller (as SeaBIOS does) is a *soft* reset. The only way to > > do a *hard* reset from software that's mentioned in the datasheet is the > > PMC turbo/reset control register (port 0x93). And that, presumably, is > > chipset-dependent and not something we can easily use from the reset > > vector without doing a bunch of hardware probing. > > The ACPI v2 spec describes a "hard" reset register. SeaBIOS could > extract it from the FADT and then use it. Of course, we'd probably > want to update the QEMU ACPI tables to implement ACPI v2 then.
Yeah, that makes me somewhat happier about the SeaBIOS side of it being hardware-specific. That way the code at the reset vector only has to cope with a single 8-bit write to memory, IO or config space. Laszlo has hooked up the RCR on the PIIX3 already, so something like this ought to make it reset the PAM setup *only* if reset via that... diff --git a/hw/piix_pci.c b/hw/piix_pci.c index 6c77e49..f4420bd 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -77,6 +77,7 @@ typedef struct PIIX3State { /* Reset Control Register contents */ uint8_t rcr; + uint8_t rcr_hard_reset; /* IO memory region for Reset Control Register (RCR_IOPORT) */ MemoryRegion rcr_mem; @@ -84,6 +85,7 @@ typedef struct PIIX3State { struct PCII440FXState { PCIDevice dev; + PIIX3State *piix3; MemoryRegion *system_memory; MemoryRegion *pci_address_space; MemoryRegion *ram_memory; @@ -171,6 +173,29 @@ static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id) return 0; } +static void i440fx_reset(DeviceState *ds) +{ + PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, ds); + PCII440FXState *d = DO_UPCAST(PCII440FXState, dev, dev); + uint8_t *pci_conf = d->dev.config; + + if (!d->piix3->rcr_hard_reset) + return; + + pci_conf[0x59] = 0x00; // Reset PAM setup + pci_conf[0x5a] = 0x00; + pci_conf[0x5b] = 0x00; + pci_conf[0x5c] = 0x00; + pci_conf[0x5d] = 0x00; + pci_conf[0x5e] = 0x00; + pci_conf[0x5f] = 0x00; + pci_conf[0x72] = 0x02; // And SMM + + i440fx_update_memory_mappings(d); + + d->piix3->rcr_hard_reset = 0; +} + static int i440fx_post_load(void *opaque, int version_id) { PCII440FXState *d = opaque; @@ -297,6 +322,7 @@ static PCIBus *i440fx_common_init(const char *device_name, pci_bus_set_route_irq_fn(b, piix3_route_intx_pin_to_irq); } piix3->pic = pic; + f->piix3 = piix3; *isa_bus = DO_UPCAST(ISABus, qbus, qdev_get_child_bus(&piix3->dev.qdev, "isa.0")); @@ -521,6 +547,8 @@ static void rcr_write(void *opaque, hwaddr addr, uint64_t val, unsigned len) PIIX3State *d = opaque; if (val & 4) { + if (val & 2) + d->rcr_hard_reset = 1; qemu_system_reset_request(); return; } @@ -615,6 +643,7 @@ static void i440fx_class_init(ObjectClass *klass, void *data) dc->desc = "Host bridge"; dc->no_user = 1; dc->vmsd = &vmstate_i440fx; + dc->reset = i440fx_reset; } static const TypeInfo i440fx_info = { -- dwmw2
smime.p7s
Description: S/MIME cryptographic signature