aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorCédric Le Goater <clg@kaod.org>2019-09-25 16:32:32 +0200
committerPeter Maydell <peter.maydell@linaro.org>2019-10-15 18:09:04 +0100
commitfadefada4d07a3a77c4171244cded0e9af81331c (patch)
tree0ad3e577ea46c5dd89c86caf669d58d2597c6985 /hw
parentc20375dd8678eae2462a986938e6d119cb5abefa (diff)
downloadqemu-fadefada4d07a3a77c4171244cded0e9af81331c.zip
qemu-fadefada4d07a3a77c4171244cded0e9af81331c.tar.gz
qemu-fadefada4d07a3a77c4171244cded0e9af81331c.tar.bz2
aspeed/timer: Add support for IRQ status register on the AST2600
The AST2600 timer replaces control register 2 with a interrupt status register. It is set by hardware when an IRQ occurs and cleared by software. Modify the vmstate version to take into account the new fields. Based on previous work from Joel Stanley. Signed-off-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Joel Stanley <joel@jms.id.au> Message-id: 20190925143248.10000-8-clg@kaod.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/timer/aspeed_timer.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
index 7f73d0c..bcce219 100644
--- a/hw/timer/aspeed_timer.c
+++ b/hw/timer/aspeed_timer.c
@@ -160,7 +160,9 @@ static uint64_t calculate_next(struct AspeedTimer *t)
timer_del(&t->timer);
if (timer_overflow_interrupt(t)) {
+ AspeedTimerCtrlState *s = timer_to_ctrl(t);
t->level = !t->level;
+ s->irq_sts |= BIT(t->id);
qemu_set_irq(t->irq, t->level);
}
@@ -199,7 +201,9 @@ static void aspeed_timer_expire(void *opaque)
}
if (interrupt) {
+ AspeedTimerCtrlState *s = timer_to_ctrl(t);
t->level = !t->level;
+ s->irq_sts |= BIT(t->id);
qemu_set_irq(t->irq, t->level);
}
@@ -244,9 +248,6 @@ static uint64_t aspeed_timer_read(void *opaque, hwaddr offset, unsigned size)
case 0x30: /* Control Register */
value = s->ctrl;
break;
- case 0x34: /* Control Register 2 */
- value = s->ctrl2;
- break;
case 0x00 ... 0x2c: /* Timers 1 - 4 */
value = aspeed_timer_get_value(&s->timers[(offset >> 4)], reg);
break;
@@ -438,9 +439,6 @@ static void aspeed_timer_write(void *opaque, hwaddr offset, uint64_t value,
case 0x30:
aspeed_timer_set_ctrl(s, tv);
break;
- case 0x34:
- aspeed_timer_set_ctrl2(s, tv);
- break;
/* Timer Registers */
case 0x00 ... 0x2c:
aspeed_timer_set_value(s, (offset >> TIMER_NR_REGS), reg, tv);
@@ -468,6 +466,9 @@ static uint64_t aspeed_2400_timer_read(AspeedTimerCtrlState *s, hwaddr offset)
uint64_t value;
switch (offset) {
+ case 0x34:
+ value = s->ctrl2;
+ break;
case 0x38:
case 0x3C:
default:
@@ -482,7 +483,12 @@ static uint64_t aspeed_2400_timer_read(AspeedTimerCtrlState *s, hwaddr offset)
static void aspeed_2400_timer_write(AspeedTimerCtrlState *s, hwaddr offset,
uint64_t value)
{
+ const uint32_t tv = (uint32_t)(value & 0xFFFFFFFF);
+
switch (offset) {
+ case 0x34:
+ aspeed_timer_set_ctrl2(s, tv);
+ break;
case 0x38:
case 0x3C:
default:
@@ -497,6 +503,9 @@ static uint64_t aspeed_2500_timer_read(AspeedTimerCtrlState *s, hwaddr offset)
uint64_t value;
switch (offset) {
+ case 0x34:
+ value = s->ctrl2;
+ break;
case 0x38:
value = s->ctrl3 & BIT(0);
break;
@@ -517,6 +526,9 @@ static void aspeed_2500_timer_write(AspeedTimerCtrlState *s, hwaddr offset,
uint8_t command;
switch (offset) {
+ case 0x34:
+ aspeed_timer_set_ctrl2(s, tv);
+ break;
case 0x38:
command = (value >> 1) & 0xFF;
if (command == 0xAE) {
@@ -543,6 +555,9 @@ static uint64_t aspeed_2600_timer_read(AspeedTimerCtrlState *s, hwaddr offset)
uint64_t value;
switch (offset) {
+ case 0x34:
+ value = s->irq_sts;
+ break;
case 0x38:
case 0x3C:
default:
@@ -560,6 +575,9 @@ static void aspeed_2600_timer_write(AspeedTimerCtrlState *s, hwaddr offset,
const uint32_t tv = (uint32_t)(value & 0xFFFFFFFF);
switch (offset) {
+ case 0x34:
+ s->irq_sts &= tv;
+ break;
case 0x3C:
aspeed_timer_set_ctrl(s, s->ctrl & ~tv);
break;
@@ -626,6 +644,7 @@ static void aspeed_timer_reset(DeviceState *dev)
s->ctrl = 0;
s->ctrl2 = 0;
s->ctrl3 = 0;
+ s->irq_sts = 0;
}
static const VMStateDescription vmstate_aspeed_timer = {
@@ -644,12 +663,13 @@ static const VMStateDescription vmstate_aspeed_timer = {
static const VMStateDescription vmstate_aspeed_timer_state = {
.name = "aspeed.timerctrl",
- .version_id = 1,
- .minimum_version_id = 1,
+ .version_id = 2,
+ .minimum_version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_UINT32(ctrl, AspeedTimerCtrlState),
VMSTATE_UINT32(ctrl2, AspeedTimerCtrlState),
VMSTATE_UINT32(ctrl3, AspeedTimerCtrlState),
+ VMSTATE_UINT32(irq_sts, AspeedTimerCtrlState),
VMSTATE_STRUCT_ARRAY(timers, AspeedTimerCtrlState,
ASPEED_TIMER_NR_TIMERS, 1, vmstate_aspeed_timer,
AspeedTimer),