qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC PATCH] Distinguish between reset types


From: David Woodhouse
Subject: Re: [Qemu-devel] [RFC PATCH] Distinguish between reset types
Date: Tue, 19 Feb 2013 14:40:22 +0000

On Tue, 2013-02-19 at 13:31 +0100, Paolo Bonzini wrote:
> So you can make the hard reset line a qemu_irq (output in PIIX, input in
> i440FX) using qdev_init_gpio_in/out.  The input side in the i440FX then
> can reset the PAM registers while the output side can pulse it before
> calling qemu_system_reset_request() if RCR bit 1 is set.  Then you can
> connect it using qdev_connect_gpio_out/qdev_get_gpio_in in
> i440fx_common_init.

Like this? I've still left i440fx_reset() hooked up as dc->reset, and
conditionally do the full reset based on a flag in the state. If I
actually *do* the reset directly from i440fx_handle_reset() rather than
just setting the flag there, it might happen too early?

diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 6c77e49..0c8f613 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -71,6 +71,7 @@ typedef struct PIIX3State {
     uint64_t pic_levels;
 
     qemu_irq *pic;
+    qemu_irq reset_out;
 
     /* This member isn't used. Just for save/load compatibility */
     int32_t pci_irq_levels_vmstate[PIIX_NUM_PIRQS];
@@ -92,6 +93,7 @@ struct PCII440FXState {
     PAMMemoryRegion pam_regions[13];
     MemoryRegion smram_region;
     uint8_t smm_enabled;
+    uint8_t hard_reset;
 };
 
 
@@ -171,6 +173,42 @@ 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;
+
+    /* We only reset the PAM configuration if it was a *hard* reset,
+     * triggered from the RCR on the PIIX3 (or from the TRCR on the
+     * i440FX itself, but we don't implement that yet and software
+     * is advised not to use it when there's a PIIX). */
+    if (!d->hard_reset)
+        return;
+
+    d->hard_reset = 0;
+
+    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);
+}
+
+static void i440fx_handle_reset(void *opaque, int n, int level)
+{
+    PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, opaque);
+    PCII440FXState *d = DO_UPCAST(PCII440FXState, dev, dev);
+
+    if (level)
+        d->hard_reset = 1;
+}
+
 static int i440fx_post_load(void *opaque, int version_id)
 {
     PCII440FXState *d = opaque;
@@ -216,6 +254,8 @@ static int i440fx_initfn(PCIDevice *dev)
 
     d->dev.config[I440FX_SMRAM] = 0x02;
 
+    qdev_init_gpio_in(&d->dev.qdev, i440fx_handle_reset, 1);
+
     cpu_smm_register(&i440fx_set_smm, d);
     return 0;
 }
@@ -297,6 +337,8 @@ 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;
+    qdev_connect_gpio_out(&piix3->dev.qdev, 0,
+                          qdev_get_gpio_in(&f->dev.qdev, 0));
     *isa_bus = DO_UPCAST(ISABus, qbus,
                          qdev_get_child_bus(&piix3->dev.qdev, "isa.0"));
 
@@ -521,6 +563,8 @@ static void rcr_write(void *opaque, hwaddr addr, uint64_t 
val, unsigned len)
     PIIX3State *d = opaque;
 
     if (val & 4) {
+        if (val & 2)
+            qemu_irq_pulse(d->reset_out);
         qemu_system_reset_request();
         return;
     }
@@ -550,6 +594,7 @@ static int piix3_initfn(PCIDevice *dev)
     memory_region_add_subregion_overlap(pci_address_space_io(dev), RCR_IOPORT,
                                         &d->rcr_mem, 1);
 
+    qdev_init_gpio_out(&dev->qdev, &d->reset_out, 1);
     qemu_register_reset(piix3_reset, d);
     return 0;
 }
@@ -615,6 +660,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

Attachment: smime.p7s
Description: S/MIME cryptographic signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]