diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/arm_sysctl.c | 64 | ||||
-rw-r--r-- | hw/ide/core.c | 41 | ||||
-rw-r--r-- | hw/xen_disk.c | 2 |
3 files changed, 92 insertions, 15 deletions
diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c index a759430..9225b58 100644 --- a/hw/arm_sysctl.c +++ b/hw/arm_sysctl.c @@ -27,11 +27,14 @@ typedef struct { uint32_t resetlevel; uint32_t proc_id; uint32_t sys_mci; + uint32_t sys_cfgdata; + uint32_t sys_cfgctrl; + uint32_t sys_cfgstat; } arm_sysctl_state; static const VMStateDescription vmstate_arm_sysctl = { .name = "realview_sysctl", - .version_id = 1, + .version_id = 2, .minimum_version_id = 1, .fields = (VMStateField[]) { VMSTATE_UINT32(leds, arm_sysctl_state), @@ -41,6 +44,10 @@ static const VMStateDescription vmstate_arm_sysctl = { VMSTATE_UINT32(flags, arm_sysctl_state), VMSTATE_UINT32(nvflags, arm_sysctl_state), VMSTATE_UINT32(resetlevel, arm_sysctl_state), + VMSTATE_UINT32_V(sys_mci, arm_sysctl_state, 2), + VMSTATE_UINT32_V(sys_cfgdata, arm_sysctl_state, 2), + VMSTATE_UINT32_V(sys_cfgctrl, arm_sysctl_state, 2), + VMSTATE_UINT32_V(sys_cfgstat, arm_sysctl_state, 2), VMSTATE_END_OF_LIST() } }; @@ -53,6 +60,7 @@ static const VMStateDescription vmstate_arm_sysctl = { #define BOARD_ID_EB 0x140 #define BOARD_ID_PBA8 0x178 #define BOARD_ID_PBX 0x182 +#define BOARD_ID_VEXPRESS 0x190 static int board_id(arm_sysctl_state *s) { @@ -104,6 +112,10 @@ static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset) case 0x38: /* NVFLAGS */ return s->nvflags; case 0x40: /* RESETCTL */ + if (board_id(s) == BOARD_ID_VEXPRESS) { + /* reserved: RAZ/WI */ + return 0; + } return s->resetlevel; case 0x44: /* PCICTL */ return 1; @@ -142,7 +154,23 @@ static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset) case 0xcc: /* SYS_TEST_OSC3 */ case 0xd0: /* SYS_TEST_OSC4 */ return 0; + case 0xa0: /* SYS_CFGDATA */ + if (board_id(s) != BOARD_ID_VEXPRESS) { + goto bad_reg; + } + return s->sys_cfgdata; + case 0xa4: /* SYS_CFGCTRL */ + if (board_id(s) != BOARD_ID_VEXPRESS) { + goto bad_reg; + } + return s->sys_cfgctrl; + case 0xa8: /* SYS_CFGSTAT */ + if (board_id(s) != BOARD_ID_VEXPRESS) { + goto bad_reg; + } + return s->sys_cfgstat; default: + bad_reg: printf ("arm_sysctl_read: Bad register offset 0x%x\n", (int)offset); return 0; } @@ -190,6 +218,10 @@ static void arm_sysctl_write(void *opaque, target_phys_addr_t offset, s->nvflags &= ~val; break; case 0x40: /* RESETCTL */ + if (board_id(s) == BOARD_ID_VEXPRESS) { + /* reserved: RAZ/WI */ + break; + } if (s->lockval == LOCK_VALUE) { s->resetlevel = val; if (val & 0x100) @@ -216,7 +248,37 @@ static void arm_sysctl_write(void *opaque, target_phys_addr_t offset, case 0x98: /* OSCRESET3 */ case 0x9c: /* OSCRESET4 */ break; + case 0xa0: /* SYS_CFGDATA */ + if (board_id(s) != BOARD_ID_VEXPRESS) { + goto bad_reg; + } + s->sys_cfgdata = val; + return; + case 0xa4: /* SYS_CFGCTRL */ + if (board_id(s) != BOARD_ID_VEXPRESS) { + goto bad_reg; + } + s->sys_cfgctrl = val & ~(3 << 18); + s->sys_cfgstat = 1; /* complete */ + switch (s->sys_cfgctrl) { + case 0xc0800000: /* SYS_CFG_SHUTDOWN to motherboard */ + qemu_system_shutdown_request(); + break; + case 0xc0900000: /* SYS_CFG_REBOOT to motherboard */ + qemu_system_reset_request(); + break; + default: + s->sys_cfgstat |= 2; /* error */ + } + return; + case 0xa8: /* SYS_CFGSTAT */ + if (board_id(s) != BOARD_ID_VEXPRESS) { + goto bad_reg; + } + s->sys_cfgstat = val & 3; + return; default: + bad_reg: printf ("arm_sysctl_write: Bad register offset 0x%x\n", (int)offset); return; } diff --git a/hw/ide/core.c b/hw/ide/core.c index 294d237..007a4ee 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -34,13 +34,26 @@ #include <hw/ide/internal.h> -static const int smart_attributes[][5] = { - /* id, flags, val, wrst, thrsh */ - { 0x01, 0x03, 0x64, 0x64, 0x06}, /* raw read */ - { 0x03, 0x03, 0x64, 0x64, 0x46}, /* spin up */ - { 0x04, 0x02, 0x64, 0x64, 0x14}, /* start stop count */ - { 0x05, 0x03, 0x64, 0x64, 0x36}, /* remapped sectors */ - { 0x00, 0x00, 0x00, 0x00, 0x00} +/* These values were based on a Seagate ST3500418AS but have been modified + to make more sense in QEMU */ +static const int smart_attributes[][12] = { + /* id, flags, hflags, val, wrst, raw (6 bytes), threshold */ + /* raw read error rate*/ + { 0x01, 0x03, 0x00, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06}, + /* spin up */ + { 0x03, 0x03, 0x00, 0x64, 0x64, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* start stop count */ + { 0x04, 0x02, 0x00, 0x64, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14}, + /* remapped sectors */ + { 0x05, 0x03, 0x00, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24}, + /* power on hours */ + { 0x09, 0x03, 0x00, 0x64, 0x64, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* power cycle count */ + { 0x0c, 0x03, 0x00, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* airflow-temperature-celsius */ + { 190, 0x03, 0x00, 0x45, 0x45, 0x1f, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x32}, + /* end of list */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; /* XXX: DVDs that could fit on a CD will be reported as a CD */ @@ -1843,6 +1856,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) break; case WIN_CHECKPOWERMODE1: case WIN_CHECKPOWERMODE2: + s->error = 0; s->nsector = 0xff; /* device active or idle */ s->status = READY_STAT | SEEK_STAT; ide_set_irq(s->bus); @@ -2097,7 +2111,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) if (smart_attributes[n][0] == 0) break; s->io_buffer[2+0+(n*12)] = smart_attributes[n][0]; - s->io_buffer[2+1+(n*12)] = smart_attributes[n][4]; + s->io_buffer[2+1+(n*12)] = smart_attributes[n][11]; } for (n=0; n<511; n++) /* checksum */ s->io_buffer[511] += s->io_buffer[n]; @@ -2110,12 +2124,13 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) memset(s->io_buffer, 0, 0x200); s->io_buffer[0] = 0x01; /* smart struct version */ for (n=0; n<30; n++) { - if (smart_attributes[n][0] == 0) + if (smart_attributes[n][0] == 0) { break; - s->io_buffer[2+0+(n*12)] = smart_attributes[n][0]; - s->io_buffer[2+1+(n*12)] = smart_attributes[n][1]; - s->io_buffer[2+3+(n*12)] = smart_attributes[n][2]; - s->io_buffer[2+4+(n*12)] = smart_attributes[n][3]; + } + int i; + for(i = 0; i < 11; i++) { + s->io_buffer[2+i+(n*12)] = smart_attributes[n][i]; + } } s->io_buffer[362] = 0x02 | (s->smart_autosave?0x80:0x00); if (s->smart_selftest_count == 0) { diff --git a/hw/xen_disk.c b/hw/xen_disk.c index ed9e5eb..445bf03 100644 --- a/hw/xen_disk.c +++ b/hw/xen_disk.c @@ -408,9 +408,9 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq) break; case BLKIF_OP_WRITE: case BLKIF_OP_WRITE_BARRIER: - ioreq->aio_inflight++; if (!ioreq->req.nr_segments) break; + ioreq->aio_inflight++; bdrv_aio_writev(blkdev->bs, ioreq->start / BLOCK_SIZE, &ioreq->v, ioreq->v.size / BLOCK_SIZE, qemu_aio_complete, ioreq); |