Patchwork ICH9 LPC: Reset Control Register, basic implementation

login
register
mail settings
Submitter Laszlo Ersek
Date Feb. 20, 2013, 1:51 a.m.
Message ID <1361325084-31018-1-git-send-email-lersek@redhat.com>
Download mbox | patch
Permalink /patch/221938/
State New
Headers show

Comments

Laszlo Ersek - Feb. 20, 2013, 1:51 a.m.
This commit does the same for the ICH9 LPC as commit 1ec4ba74 for the
PIIX3. For the present we're ignoring the Full Reset (FULL_RST) and System
Reset (SYS_RST) bits; the guest can read them back but that's it.

Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
 Tested retention of RCR contents and reset functionality in a pc-q35-1.4 VM
 with a Fedora 18 Live CD; plus info mtree:

 I/O
 0000000000000000-000000000000ffff (prio 0, RW): io
   0000000000000cf8-0000000000000cfb (prio 0, RW): pci-conf-idx
   0000000000000cf9-0000000000000cf9 (prio 1, RW): lpc-reset-control

 hw/ich9.h     |   11 +++++++++++
 hw/lpc_ich9.c |   57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+), 0 deletions(-)
Laszlo Ersek - Feb. 26, 2013, 9:53 p.m.
On 02/20/13 02:51, Laszlo Ersek wrote:
> This commit does the same for the ICH9 LPC as commit 1ec4ba74 for the
> PIIX3. For the present we're ignoring the Full Reset (FULL_RST) and System
> Reset (SYS_RST) bits; the guest can read them back but that's it.
> 
> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
> ---
>  Tested retention of RCR contents and reset functionality in a pc-q35-1.4 VM
>  with a Fedora 18 Live CD; plus info mtree:
> 
>  I/O
>  0000000000000000-000000000000ffff (prio 0, RW): io
>    0000000000000cf8-0000000000000cfb (prio 0, RW): pci-conf-idx
>    0000000000000cf9-0000000000000cf9 (prio 1, RW): lpc-reset-control
> 
>  hw/ich9.h     |   11 +++++++++++
>  hw/lpc_ich9.c |   57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 68 insertions(+), 0 deletions(-)

Ping...

Laszlo
Michael S. Tsirkin - Feb. 26, 2013, 10:30 p.m.
On Tue, Feb 26, 2013 at 10:53:27PM +0100, Laszlo Ersek wrote:
> On 02/20/13 02:51, Laszlo Ersek wrote:
> > This commit does the same for the ICH9 LPC as commit 1ec4ba74 for the
> > PIIX3. For the present we're ignoring the Full Reset (FULL_RST) and System
> > Reset (SYS_RST) bits; the guest can read them back but that's it.
> > 
> > Signed-off-by: Laszlo Ersek <lersek@redhat.com>
> > ---
> >  Tested retention of RCR contents and reset functionality in a pc-q35-1.4 VM
> >  with a Fedora 18 Live CD; plus info mtree:
> > 
> >  I/O
> >  0000000000000000-000000000000ffff (prio 0, RW): io
> >    0000000000000cf8-0000000000000cfb (prio 0, RW): pci-conf-idx
> >    0000000000000cf9-0000000000000cf9 (prio 1, RW): lpc-reset-control
> > 
> >  hw/ich9.h     |   11 +++++++++++
> >  hw/lpc_ich9.c |   57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 68 insertions(+), 0 deletions(-)
> 
> Ping...
> 
> Laszlo

Applied.

Patch

diff --git a/hw/ich9.h b/hw/ich9.h
index d4509bb..dbc4495 100644
--- a/hw/ich9.h
+++ b/hw/ich9.h
@@ -49,6 +49,15 @@  typedef struct ICH9LPCState {
     /* 10.1 Chipset Configuration registers(Memory Space)
      which is pointed by RCBA */
     uint8_t chip_config[ICH9_CC_SIZE];
+
+    /*
+     * 13.7.5 RST_CNT---Reset Control Register (LPC I/F---D31:F0)
+     *
+     * register contents and IO memory region
+     */
+    uint8_t rst_cnt;
+    MemoryRegion rst_cnt_mem;
+
     /* isa bus */
     ISABus *isa_bus;
     MemoryRegion rbca_mem;
@@ -103,6 +112,8 @@  typedef struct ICH9LPCState {
 
 #define ICH9_D2P_A2_REVISION                    0x92
 
+/* D31:F0 LPC Processor Interface */
+#define ICH9_RST_CNT_IOPORT                     0xCF9
 
 /* D31:F1 LPC controller */
 #define ICH9_A2_LPC                             "ICH9 A2 LPC"
diff --git a/hw/lpc_ich9.c b/hw/lpc_ich9.c
index e25689b..eceb052 100644
--- a/hw/lpc_ich9.c
+++ b/hw/lpc_ich9.c
@@ -466,6 +466,7 @@  static void ich9_lpc_reset(DeviceState *qdev)
     ich9_lpc_rcba_update(lpc, rbca_old);
 
     lpc->sci_level = 0;
+    lpc->rst_cnt = 0;
 }
 
 static const MemoryRegionOps rbca_mmio_ops = {
@@ -498,6 +499,32 @@  static void ich9_lpc_machine_ready(Notifier *n, void *opaque)
     }
 }
 
+/* reset control */
+static void ich9_rst_cnt_write(void *opaque, hwaddr addr, uint64_t val,
+                               unsigned len)
+{
+    ICH9LPCState *lpc = opaque;
+
+    if (val & 4) {
+        qemu_system_reset_request();
+        return;
+    }
+    lpc->rst_cnt = val & 0xA; /* keep FULL_RST (bit 3) and SYS_RST (bit 1) */
+}
+
+static uint64_t ich9_rst_cnt_read(void *opaque, hwaddr addr, unsigned len)
+{
+    ICH9LPCState *lpc = opaque;
+
+    return lpc->rst_cnt;
+}
+
+static const MemoryRegionOps ich9_rst_cnt_ops = {
+    .read = ich9_rst_cnt_read,
+    .write = ich9_rst_cnt_write,
+    .endianness = DEVICE_LITTLE_ENDIAN
+};
+
 static int ich9_lpc_initfn(PCIDevice *d)
 {
     ICH9LPCState *lpc = ICH9_LPC_DEVICE(d);
@@ -519,9 +546,32 @@  static int ich9_lpc_initfn(PCIDevice *d)
     lpc->machine_ready.notify = ich9_lpc_machine_ready;
     qemu_add_machine_init_done_notifier(&lpc->machine_ready);
 
+    memory_region_init_io(&lpc->rst_cnt_mem, &ich9_rst_cnt_ops, lpc,
+                          "lpc-reset-control", 1);
+    memory_region_add_subregion_overlap(pci_address_space_io(d),
+                                        ICH9_RST_CNT_IOPORT, &lpc->rst_cnt_mem,
+                                        1);
+
     return 0;
 }
 
+static bool ich9_rst_cnt_needed(void *opaque)
+{
+    ICH9LPCState *lpc = opaque;
+
+    return (lpc->rst_cnt != 0);
+}
+
+static const VMStateDescription vmstate_ich9_rst_cnt = {
+    .name = "ICH9LPC/rst_cnt",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT8(rst_cnt, ICH9LPCState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_ich9_lpc = {
     .name = "ICH9LPC",
     .version_id = 1,
@@ -535,6 +585,13 @@  static const VMStateDescription vmstate_ich9_lpc = {
         VMSTATE_UINT8_ARRAY(chip_config, ICH9LPCState, ICH9_CC_SIZE),
         VMSTATE_UINT32(sci_level, ICH9LPCState),
         VMSTATE_END_OF_LIST()
+    },
+    .subsections = (VMStateSubsection[]) {
+        {
+            .vmsd = &vmstate_ich9_rst_cnt,
+            .needed = ich9_rst_cnt_needed
+        },
+        { 0 }
     }
 };