@@ -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 = {