X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=hw%2Fpxa2xx_timer.c;h=982420502aa2530ad0a3f9ce755ef6664a67038e;hb=cd346349b45ef056f138a184f660b8c34c3213cc;hp=8c083595c6ebec9c06ea3da276011a2d2b2d2883;hpb=565d28951e971abf342fcc8701861163b7421f23;p=qemu diff --git a/hw/pxa2xx_timer.c b/hw/pxa2xx_timer.c index 8c08359..9824205 100644 --- a/hw/pxa2xx_timer.c +++ b/hw/pxa2xx_timer.c @@ -66,12 +66,7 @@ struct pxa2xx_timer0_s { }; struct pxa2xx_timer4_s { - uint32_t value; - int level; - qemu_irq irq; - QEMUTimer *qtimer; - int num; - void *info; + struct pxa2xx_timer0_s tm; int32_t oldclock; int32_t clock; uint64_t lastload; @@ -80,7 +75,7 @@ struct pxa2xx_timer4_s { }; typedef struct { - uint32_t base; + target_phys_addr_t base; int32_t clock; int32_t oldclock; uint64_t lastload; @@ -90,8 +85,6 @@ typedef struct { uint32_t events; uint32_t irq_enabled; uint32_t reset3; - CPUState *cpustate; - int64_t qemu_ticks; uint32_t snapshot; } pxa2xx_timer_info; @@ -126,7 +119,7 @@ static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n) counter = counters[n]; if (!s->tm4[counter].freq) { - qemu_del_timer(s->timer[n].qtimer); + qemu_del_timer(s->tm4[n].tm.qtimer); return; } @@ -134,9 +127,9 @@ static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n) s->tm4[counter].lastload, s->tm4[counter].freq, ticks_per_sec); - new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].value - now_vm), + new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm), ticks_per_sec, s->tm4[counter].freq); - qemu_mod_timer(s->timer[n].qtimer, new_qemu); + qemu_mod_timer(s->tm4[n].tm.qtimer, new_qemu); } static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset) @@ -162,7 +155,7 @@ static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset) case OSMR4: if (!s->tm4) goto badreg; - return s->tm4[tm].value; + return s->tm4[tm].tm.value; case OSCR: return s->clock + muldiv64(qemu_get_clock(vm_clock) - s->lastload, s->freq, ticks_per_sec); @@ -245,7 +238,7 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset, case OSMR4: if (!s->tm4) goto badreg; - s->tm4[tm].value = value; + s->tm4[tm].tm.value = value; pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm); break; case OSCR: @@ -282,10 +275,10 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset, } if (s->tm4) { for (i = 0; i < 8; i ++, value >>= 1) - if (s->tm4[i].level && (value & 1)) - s->tm4[i].level = 0; + if (s->tm4[i].tm.level && (value & 1)) + s->tm4[i].tm.level = 0; if (!(s->events & 0xff0)) - qemu_irq_lower(s->tm4->irq); + qemu_irq_lower(s->tm4->tm.irq); } break; case OWER: /* XXX: Reset on OSMR3 match? */ @@ -355,24 +348,91 @@ static void pxa2xx_timer_tick(void *opaque) if (t->num == 3) if (i->reset3 & 1) { i->reset3 = 0; - cpu_reset(i->cpustate); + qemu_system_reset_request(); } } static void pxa2xx_timer_tick4(void *opaque) { struct pxa2xx_timer4_s *t = (struct pxa2xx_timer4_s *) opaque; - pxa2xx_timer_info *i = (pxa2xx_timer_info *) t->info; + pxa2xx_timer_info *i = (pxa2xx_timer_info *) t->tm.info; - pxa2xx_timer_tick(opaque); + pxa2xx_timer_tick(&t->tm); if (t->control & (1 << 3)) t->clock = 0; if (t->control & (1 << 6)) - pxa2xx_timer_update4(i, qemu_get_clock(vm_clock), t->num - 4); + pxa2xx_timer_update4(i, qemu_get_clock(vm_clock), t->tm.num - 4); +} + +static void pxa2xx_timer_save(QEMUFile *f, void *opaque) +{ + pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque; + int i; + + qemu_put_be32s(f, &s->clock); + qemu_put_be32s(f, &s->oldclock); + qemu_put_be64s(f, &s->lastload); + + for (i = 0; i < 4; i ++) { + qemu_put_be32s(f, &s->timer[i].value); + qemu_put_be32(f, s->timer[i].level); + } + if (s->tm4) + for (i = 0; i < 8; i ++) { + qemu_put_be32s(f, &s->tm4[i].tm.value); + qemu_put_be32(f, s->tm4[i].tm.level); + qemu_put_be32s(f, &s->tm4[i].oldclock); + qemu_put_be32s(f, &s->tm4[i].clock); + qemu_put_be64s(f, &s->tm4[i].lastload); + qemu_put_be32s(f, &s->tm4[i].freq); + qemu_put_be32s(f, &s->tm4[i].control); + } + + qemu_put_be32s(f, &s->events); + qemu_put_be32s(f, &s->irq_enabled); + qemu_put_be32s(f, &s->reset3); + qemu_put_be32s(f, &s->snapshot); +} + +static int pxa2xx_timer_load(QEMUFile *f, void *opaque, int version_id) +{ + pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque; + int64_t now; + int i; + + qemu_get_be32s(f, &s->clock); + qemu_get_be32s(f, &s->oldclock); + qemu_get_be64s(f, &s->lastload); + + now = qemu_get_clock(vm_clock); + for (i = 0; i < 4; i ++) { + qemu_get_be32s(f, &s->timer[i].value); + s->timer[i].level = qemu_get_be32(f); + } + pxa2xx_timer_update(s, now); + + if (s->tm4) + for (i = 0; i < 8; i ++) { + qemu_get_be32s(f, &s->tm4[i].tm.value); + s->tm4[i].tm.level = qemu_get_be32(f); + qemu_get_be32s(f, &s->tm4[i].oldclock); + qemu_get_be32s(f, &s->tm4[i].clock); + qemu_get_be64s(f, &s->tm4[i].lastload); + qemu_get_be32s(f, &s->tm4[i].freq); + qemu_get_be32s(f, &s->tm4[i].control); + pxa2xx_timer_update4(s, now, i); + } + + qemu_get_be32s(f, &s->events); + qemu_get_be32s(f, &s->irq_enabled); + qemu_get_be32s(f, &s->reset3); + qemu_get_be32s(f, &s->snapshot); + + return 0; } static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base, - qemu_irq *irqs, CPUState *cpustate) + qemu_irq *irqs) { int i; int iomemtype; @@ -385,7 +445,6 @@ static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base, s->clock = 0; s->lastload = qemu_get_clock(vm_clock); s->reset3 = 0; - s->cpustate = cpustate; for (i = 0; i < 4; i ++) { s->timer[i].value = 0; @@ -399,35 +458,38 @@ static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base, iomemtype = cpu_register_io_memory(0, pxa2xx_timer_readfn, pxa2xx_timer_writefn, s); - cpu_register_physical_memory(base, 0x00000fff, iomemtype); + cpu_register_physical_memory(base, 0x00001000, iomemtype); + + register_savevm("pxa2xx_timer", 0, 0, + pxa2xx_timer_save, pxa2xx_timer_load, s); + return s; } -void pxa25x_timer_init(target_phys_addr_t base, - qemu_irq *irqs, CPUState *cpustate) +void pxa25x_timer_init(target_phys_addr_t base, qemu_irq *irqs) { - pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs, cpustate); + pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs); s->freq = PXA25X_FREQ; s->tm4 = 0; } void pxa27x_timer_init(target_phys_addr_t base, - qemu_irq *irqs, qemu_irq irq4, CPUState *cpustate) + qemu_irq *irqs, qemu_irq irq4) { - pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs, cpustate); + pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs); int i; s->freq = PXA27X_FREQ; s->tm4 = (struct pxa2xx_timer4_s *) qemu_mallocz(8 * sizeof(struct pxa2xx_timer4_s)); for (i = 0; i < 8; i ++) { - s->tm4[i].value = 0; - s->tm4[i].irq = irq4; - s->tm4[i].info = s; - s->tm4[i].num = i + 4; - s->tm4[i].level = 0; + s->tm4[i].tm.value = 0; + s->tm4[i].tm.irq = irq4; + s->tm4[i].tm.info = s; + s->tm4[i].tm.num = i + 4; + s->tm4[i].tm.level = 0; s->tm4[i].freq = 0; s->tm4[i].control = 0x0; - s->tm4[i].qtimer = qemu_new_timer(vm_clock, + s->tm4[i].tm.qtimer = qemu_new_timer(vm_clock, pxa2xx_timer_tick4, &s->tm4[i]); } }