static uint64_t hpet_ram_read(void *opaque, target_phys_addr_t addr, unsigned size) { HPETState *s = opaque; uint64_t cur_tick, index; DPRINTF("qemu: Enter hpet_ram_readl at %" PRIx64 "\n", addr); index = addr; /*address range of all TN regs*/ if (index >= 0x100 && index <= 0x3ff) { uint8_t timer_id = (addr - 0x100) / 0x20; HPETTimer *timer = &s->timer[timer_id]; if (timer_id > s->num_timers) { DPRINTF("qemu: timer id out of range\n"); return 0; } switch ((addr - 0x100) % 0x20) { case HPET_TN_CFG: return timer->config; case HPET_TN_CFG + 4: // Interrupt capabilities return timer->config >> 32; case HPET_TN_CMP: // comparator register return timer->cmp; case HPET_TN_CMP + 4: return timer->cmp >> 32; case HPET_TN_ROUTE: return timer->fsb; case HPET_TN_ROUTE + 4: return timer->fsb >> 32; default: DPRINTF("qemu: invalid hpet_ram_readl\n"); break; } } else { switch (index) { case HPET_ID: return s->capability; case HPET_PERIOD: return s->capability >> 32; case HPET_CFG: return s->config; case HPET_CFG + 4: DPRINTF("qemu: invalid HPET_CFG + 4 hpet_ram_readl\n"); return 0; case HPET_COUNTER: if (hpet_enabled(s)) { cur_tick = hpet_get_ticks(s); } else { cur_tick = s->hpet_counter; } DPRINTF("qemu: reading counter = %" PRIx64 "\n", cur_tick); return cur_tick; case HPET_COUNTER + 4: if (hpet_enabled(s)) { cur_tick = hpet_get_ticks(s); } else { cur_tick = s->hpet_counter; } DPRINTF("qemu: reading counter + 4 = %" PRIx64 "\n", cur_tick); return cur_tick >> 32; case HPET_STATUS: return s->isr; default: DPRINTF("qemu: invalid hpet_ram_readl\n"); break; } } return 0; }