Commit 0e98b436 authored by Laszlo Ersek's avatar Laszlo Ersek Committed by Michael S. Tsirkin
Browse files

ICH9 LPC: Reset Control Register, basic implementation



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: default avatarLaszlo Ersek <lersek@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 7feb640c
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -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"
+57 −0
Original line number Diff line number Diff line
@@ -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 }
    }
};