|
@@ -160,7 +160,9 @@ static uint64_t calculate_next(struct AspeedTimer *t)
|
|
timer_del(&t->timer);
|
|
timer_del(&t->timer);
|
|
|
|
|
|
if (timer_overflow_interrupt(t)) {
|
|
if (timer_overflow_interrupt(t)) {
|
|
|
|
+ AspeedTimerCtrlState *s = timer_to_ctrl(t);
|
|
t->level = !t->level;
|
|
t->level = !t->level;
|
|
|
|
+ s->irq_sts |= BIT(t->id);
|
|
qemu_set_irq(t->irq, t->level);
|
|
qemu_set_irq(t->irq, t->level);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -199,7 +201,9 @@ static void aspeed_timer_expire(void *opaque)
|
|
}
|
|
}
|
|
|
|
|
|
if (interrupt) {
|
|
if (interrupt) {
|
|
|
|
+ AspeedTimerCtrlState *s = timer_to_ctrl(t);
|
|
t->level = !t->level;
|
|
t->level = !t->level;
|
|
|
|
+ s->irq_sts |= BIT(t->id);
|
|
qemu_set_irq(t->irq, t->level);
|
|
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 */
|
|
case 0x30: /* Control Register */
|
|
value = s->ctrl;
|
|
value = s->ctrl;
|
|
break;
|
|
break;
|
|
- case 0x34: /* Control Register 2 */
|
|
|
|
- value = s->ctrl2;
|
|
|
|
- break;
|
|
|
|
case 0x00 ... 0x2c: /* Timers 1 - 4 */
|
|
case 0x00 ... 0x2c: /* Timers 1 - 4 */
|
|
value = aspeed_timer_get_value(&s->timers[(offset >> 4)], reg);
|
|
value = aspeed_timer_get_value(&s->timers[(offset >> 4)], reg);
|
|
break;
|
|
break;
|
|
@@ -438,9 +439,6 @@ static void aspeed_timer_write(void *opaque, hwaddr offset, uint64_t value,
|
|
case 0x30:
|
|
case 0x30:
|
|
aspeed_timer_set_ctrl(s, tv);
|
|
aspeed_timer_set_ctrl(s, tv);
|
|
break;
|
|
break;
|
|
- case 0x34:
|
|
|
|
- aspeed_timer_set_ctrl2(s, tv);
|
|
|
|
- break;
|
|
|
|
/* Timer Registers */
|
|
/* Timer Registers */
|
|
case 0x00 ... 0x2c:
|
|
case 0x00 ... 0x2c:
|
|
aspeed_timer_set_value(s, (offset >> TIMER_NR_REGS), reg, tv);
|
|
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;
|
|
uint64_t value;
|
|
|
|
|
|
switch (offset) {
|
|
switch (offset) {
|
|
|
|
+ case 0x34:
|
|
|
|
+ value = s->ctrl2;
|
|
|
|
+ break;
|
|
case 0x38:
|
|
case 0x38:
|
|
case 0x3C:
|
|
case 0x3C:
|
|
default:
|
|
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,
|
|
static void aspeed_2400_timer_write(AspeedTimerCtrlState *s, hwaddr offset,
|
|
uint64_t value)
|
|
uint64_t value)
|
|
{
|
|
{
|
|
|
|
+ const uint32_t tv = (uint32_t)(value & 0xFFFFFFFF);
|
|
|
|
+
|
|
switch (offset) {
|
|
switch (offset) {
|
|
|
|
+ case 0x34:
|
|
|
|
+ aspeed_timer_set_ctrl2(s, tv);
|
|
|
|
+ break;
|
|
case 0x38:
|
|
case 0x38:
|
|
case 0x3C:
|
|
case 0x3C:
|
|
default:
|
|
default:
|
|
@@ -497,6 +503,9 @@ static uint64_t aspeed_2500_timer_read(AspeedTimerCtrlState *s, hwaddr offset)
|
|
uint64_t value;
|
|
uint64_t value;
|
|
|
|
|
|
switch (offset) {
|
|
switch (offset) {
|
|
|
|
+ case 0x34:
|
|
|
|
+ value = s->ctrl2;
|
|
|
|
+ break;
|
|
case 0x38:
|
|
case 0x38:
|
|
value = s->ctrl3 & BIT(0);
|
|
value = s->ctrl3 & BIT(0);
|
|
break;
|
|
break;
|
|
@@ -517,6 +526,9 @@ static void aspeed_2500_timer_write(AspeedTimerCtrlState *s, hwaddr offset,
|
|
uint8_t command;
|
|
uint8_t command;
|
|
|
|
|
|
switch (offset) {
|
|
switch (offset) {
|
|
|
|
+ case 0x34:
|
|
|
|
+ aspeed_timer_set_ctrl2(s, tv);
|
|
|
|
+ break;
|
|
case 0x38:
|
|
case 0x38:
|
|
command = (value >> 1) & 0xFF;
|
|
command = (value >> 1) & 0xFF;
|
|
if (command == 0xAE) {
|
|
if (command == 0xAE) {
|
|
@@ -543,6 +555,9 @@ static uint64_t aspeed_2600_timer_read(AspeedTimerCtrlState *s, hwaddr offset)
|
|
uint64_t value;
|
|
uint64_t value;
|
|
|
|
|
|
switch (offset) {
|
|
switch (offset) {
|
|
|
|
+ case 0x34:
|
|
|
|
+ value = s->irq_sts;
|
|
|
|
+ break;
|
|
case 0x38:
|
|
case 0x38:
|
|
case 0x3C:
|
|
case 0x3C:
|
|
default:
|
|
default:
|
|
@@ -560,6 +575,9 @@ static void aspeed_2600_timer_write(AspeedTimerCtrlState *s, hwaddr offset,
|
|
const uint32_t tv = (uint32_t)(value & 0xFFFFFFFF);
|
|
const uint32_t tv = (uint32_t)(value & 0xFFFFFFFF);
|
|
|
|
|
|
switch (offset) {
|
|
switch (offset) {
|
|
|
|
+ case 0x34:
|
|
|
|
+ s->irq_sts &= tv;
|
|
|
|
+ break;
|
|
case 0x3C:
|
|
case 0x3C:
|
|
aspeed_timer_set_ctrl(s, s->ctrl & ~tv);
|
|
aspeed_timer_set_ctrl(s, s->ctrl & ~tv);
|
|
break;
|
|
break;
|
|
@@ -626,6 +644,7 @@ static void aspeed_timer_reset(DeviceState *dev)
|
|
s->ctrl = 0;
|
|
s->ctrl = 0;
|
|
s->ctrl2 = 0;
|
|
s->ctrl2 = 0;
|
|
s->ctrl3 = 0;
|
|
s->ctrl3 = 0;
|
|
|
|
+ s->irq_sts = 0;
|
|
}
|
|
}
|
|
|
|
|
|
static const VMStateDescription vmstate_aspeed_timer = {
|
|
static const VMStateDescription vmstate_aspeed_timer = {
|
|
@@ -644,12 +663,13 @@ static const VMStateDescription vmstate_aspeed_timer = {
|
|
|
|
|
|
static const VMStateDescription vmstate_aspeed_timer_state = {
|
|
static const VMStateDescription vmstate_aspeed_timer_state = {
|
|
.name = "aspeed.timerctrl",
|
|
.name = "aspeed.timerctrl",
|
|
- .version_id = 1,
|
|
|
|
- .minimum_version_id = 1,
|
|
|
|
|
|
+ .version_id = 2,
|
|
|
|
+ .minimum_version_id = 2,
|
|
.fields = (VMStateField[]) {
|
|
.fields = (VMStateField[]) {
|
|
VMSTATE_UINT32(ctrl, AspeedTimerCtrlState),
|
|
VMSTATE_UINT32(ctrl, AspeedTimerCtrlState),
|
|
VMSTATE_UINT32(ctrl2, AspeedTimerCtrlState),
|
|
VMSTATE_UINT32(ctrl2, AspeedTimerCtrlState),
|
|
VMSTATE_UINT32(ctrl3, AspeedTimerCtrlState),
|
|
VMSTATE_UINT32(ctrl3, AspeedTimerCtrlState),
|
|
|
|
+ VMSTATE_UINT32(irq_sts, AspeedTimerCtrlState),
|
|
VMSTATE_STRUCT_ARRAY(timers, AspeedTimerCtrlState,
|
|
VMSTATE_STRUCT_ARRAY(timers, AspeedTimerCtrlState,
|
|
ASPEED_TIMER_NR_TIMERS, 1, vmstate_aspeed_timer,
|
|
ASPEED_TIMER_NR_TIMERS, 1, vmstate_aspeed_timer,
|
|
AspeedTimer),
|
|
AspeedTimer),
|