From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:39359) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TsgwC-0007T4-DY for qemu-devel@nongnu.org; Tue, 08 Jan 2013 16:42:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Tsgw9-0000wc-2U for qemu-devel@nongnu.org; Tue, 08 Jan 2013 16:42:24 -0500 Received: from mx1.redhat.com ([209.132.183.28]:63062) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tsgw8-0000wO-Pd for qemu-devel@nongnu.org; Tue, 08 Jan 2013 16:42:20 -0500 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r08LgKLJ029384 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 8 Jan 2013 16:42:20 -0500 From: Laszlo Ersek Date: Tue, 8 Jan 2013 22:44:12 +0100 Message-Id: <1357681452-24963-1-git-send-email-lersek@redhat.com> Subject: [Qemu-devel] [RFC PATCH] PIIX: reset the VM when the Reset Control Register's RCPU bit gets set List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, akong@redhat.com, lersek@redhat.com >>From : Traditional PCI config space access is achieved by writing a 32 bit value to io port 0xcf8 to identify the bus, device, function and config register. Port 0xcfc then contains the register in question. But if you write the appropriate pair of magic values to 0xcf9, the machine will reboot. Spectacular! And not standardised in any way (certainly not part of the PCI spec), so different chipsets may have different requirements. Booo. In the PIIX4 spec, IO port 0xcf9 is specified as the Reset Control Register. Therefore let's handle single byte writes to offset 1 in the [0xcf8, 0xcfb] range separately, and interpret the RCPU bit in the value. (Based on "docs/memory.txt", overlapping regions seem to serve a different purpose.) The SRST bit alone could be stateful. However we don't distinguish between soft & hard reset, hence the SRST bit is neither checked nor saved. RHBZ reference: 890459 Signed-off-by: Laszlo Ersek --- hw/piix_pci.c | 22 +++++++++++++++++++++- 1 files changed, 21 insertions(+), 1 deletions(-) diff --git a/hw/piix_pci.c b/hw/piix_pci.c index 3d79c73..89d694c 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -31,6 +31,7 @@ #include "qemu/range.h" #include "xen.h" #include "pam.h" +#include "sysemu/sysemu.h" /* * I440FX chipset data sheet. @@ -180,11 +181,30 @@ static const VMStateDescription vmstate_i440fx = { } }; +static void i440fx_host_config_write(void *opaque, hwaddr addr, + uint64_t val, unsigned len) +{ + if (addr == 1 && len == 1) { + if (val & 4) { + qemu_system_reset_request(); + } + return; + } + pci_host_conf_le_ops.write(opaque, addr, val, len); +} + +static MemoryRegionOps i440fx_host_conf_ops = { + .read = NULL, + .write = i440fx_host_config_write, + .endianness = DEVICE_LITTLE_ENDIAN +}; + static int i440fx_pcihost_initfn(SysBusDevice *dev) { PCIHostState *s = PCI_HOST_BRIDGE(dev); - memory_region_init_io(&s->conf_mem, &pci_host_conf_le_ops, s, + i440fx_host_conf_ops.read = pci_host_conf_le_ops.read; + memory_region_init_io(&s->conf_mem, &i440fx_host_conf_ops, s, "pci-conf-idx", 4); sysbus_add_io(dev, 0xcf8, &s->conf_mem); sysbus_init_ioports(&s->busdev, 0xcf8, 4); -- 1.7.1