From patchwork Tue Feb 19 14:40:22 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Woodhouse X-Patchwork-Id: 221711 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 129862C0291 for ; Wed, 20 Feb 2013 01:43:11 +1100 (EST) Received: from localhost ([::1]:39874 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U7oPU-0003Gg-HV for incoming@patchwork.ozlabs.org; Tue, 19 Feb 2013 09:43:08 -0500 Received: from eggs.gnu.org ([208.118.235.92]:57575) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U7oOS-00036D-Tq for qemu-devel@nongnu.org; Tue, 19 Feb 2013 09:42:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1U7oMy-0006qb-Rz for qemu-devel@nongnu.org; Tue, 19 Feb 2013 09:42:04 -0500 Received: from bombadil.infradead.org ([2001:4830:2446:ff00:4687:fcff:fea6:5117]:57354) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U7oMy-0006qO-LW for qemu-devel@nongnu.org; Tue, 19 Feb 2013 09:40:32 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:225:64ff:fee8:e9df]) by bombadil.infradead.org with esmtpsa (Exim 4.76 #1 (Red Hat Linux)) id 1U7oMw-0001kE-6q; Tue, 19 Feb 2013 14:40:30 +0000 Message-ID: <1361284822.13482.209.camel@i7.infradead.org> From: David Woodhouse To: Paolo Bonzini Date: Tue, 19 Feb 2013 14:40:22 +0000 In-Reply-To: <51237094.9060700@redhat.com> References: <1361274026.13482.192.camel@i7.infradead.org> <51237094.9060700@redhat.com> X-Mailer: Evolution 3.6.3 (3.6.3-2.fc18) Mime-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 2001:4830:2446:ff00:4687:fcff:fea6:5117 Cc: qemu-devel@nongnu.org Subject: Re: [Qemu-devel] [RFC PATCH] Distinguish between reset types X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 = {