diff options
Diffstat (limited to 'hw/misc/macio/cuda.c')
-rw-r--r-- | hw/misc/macio/cuda.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index ff6051defe..b4273aa171 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -123,13 +123,22 @@ static void cuda_update_irq(CUDAState *s) } } +static uint64_t get_tb(uint64_t freq) +{ + return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), + freq, get_ticks_per_sec()); +} + static unsigned int get_counter(CUDATimer *s) { int64_t d; unsigned int counter; + uint64_t tb_diff; + + /* Reverse of the tb calculation algorithm that Mac OS X uses on bootup. */ + tb_diff = get_tb(s->frequency) - s->load_time; + d = (tb_diff * 0xBF401675E5DULL) / (s->frequency << 24); - d = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->load_time, - CUDA_TIMER_FREQ, get_ticks_per_sec()); if (s->index == 0) { /* the timer goes down from latch to -1 (period of latch + 2) */ if (d <= (s->counter_value + 1)) { @@ -147,7 +156,7 @@ static unsigned int get_counter(CUDATimer *s) static void set_counter(CUDAState *s, CUDATimer *ti, unsigned int val) { CUDA_DPRINTF("T%d.counter=%d\n", 1 + (ti->timer == NULL), val); - ti->load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + ti->load_time = get_tb(s->frequency); ti->counter_value = val; cuda_timer_update(s, ti, ti->load_time); } @@ -688,6 +697,8 @@ static void cuda_realizefn(DeviceState *dev, Error **errp) struct tm tm; s->timers[0].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_timer1, s); + s->timers[0].frequency = s->frequency; + s->timers[1].frequency = s->frequency; qemu_get_timedate(&tm, 0); s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET; @@ -713,6 +724,11 @@ static void cuda_initfn(Object *obj) DEVICE(obj), "adb.0"); } +static Property cuda_properties[] = { + DEFINE_PROP_UINT64("frequency", CUDAState, frequency, 0), + DEFINE_PROP_END_OF_LIST() +}; + static void cuda_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -720,6 +736,7 @@ static void cuda_class_init(ObjectClass *oc, void *data) dc->realize = cuda_realizefn; dc->reset = cuda_reset; dc->vmsd = &vmstate_cuda; + dc->props = cuda_properties; } static const TypeInfo cuda_type_info = { |