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: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
7feb640cf3
commit
0e98b436ec
11
hw/ich9.h
11
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"
|
||||
|
@ -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 }
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user