[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 41/52] PPC: Cuda: Use cuda timer to expose tbfreq to
From: |
Alexander Graf |
Subject: |
[Qemu-devel] [PULL 41/52] PPC: Cuda: Use cuda timer to expose tbfreq to guest |
Date: |
Thu, 4 Sep 2014 19:20:29 +0200 |
Mac OS X calibrates a number of frequencies on bootup based on reading
tb values on bootup and comparing them to via cuda timer values.
The only variable we can really steer well (thanks to KVM) is the cuda
frequency. So let's use that one to fake Mac OS X into believing the
bus frequency is tbfreq * 4. That way Mac OS X will automatically
calculate the correct timebase frequency.
With this patch and the patch set I posted earlier I can successfully
run Mac OS X 10.2, 10.3 and 10.4 guests with -M mac99 on TCG and KVM.
Suggested-by: Benjamin Herrenschmidt <address@hidden>
Signed-off-by: Alexander Graf <address@hidden>
---
hw/misc/macio/cuda.c | 23 ++++++++++++++++++++---
hw/misc/macio/macio.c | 10 ++++++++++
hw/ppc/mac.h | 2 ++
hw/ppc/mac_newworld.c | 1 +
hw/ppc/mac_oldworld.c | 1 +
5 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index ff6051d..b4273aa 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 = {
diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
index 35eaa00..e0f1e88 100644
--- a/hw/misc/macio/macio.c
+++ b/hw/misc/macio/macio.c
@@ -42,6 +42,7 @@ typedef struct MacIOState
void *dbdma;
MemoryRegion *pic_mem;
MemoryRegion *escc_mem;
+ uint64_t frequency;
} MacIOState;
#define OLDWORLD_MACIO(obj) \
@@ -351,12 +352,19 @@ static void macio_newworld_class_init(ObjectClass *oc,
void *data)
pdc->device_id = PCI_DEVICE_ID_APPLE_UNI_N_KEYL;
}
+static Property macio_properties[] = {
+ DEFINE_PROP_UINT64("frequency", MacIOState, frequency, 0),
+ DEFINE_PROP_END_OF_LIST()
+};
+
static void macio_class_init(ObjectClass *klass, void *data)
{
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
k->vendor_id = PCI_VENDOR_ID_APPLE;
k->class_id = PCI_CLASS_OTHERS << 8;
+ dc->props = macio_properties;
}
static const TypeInfo macio_oldworld_type_info = {
@@ -403,6 +411,8 @@ void macio_init(PCIDevice *d,
macio_state->escc_mem = escc_mem;
/* Note: this code is strongly inspirated from the corresponding code
in PearPC */
+ qdev_prop_set_uint64(DEVICE(&macio_state->cuda), "frequency",
+ macio_state->frequency);
qdev_init_nofail(DEVICE(d));
}
diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
index 23536f4..aff2b9a 100644
--- a/hw/ppc/mac.h
+++ b/hw/ppc/mac.h
@@ -57,6 +57,7 @@ typedef struct CUDATimer {
uint16_t counter_value;
int64_t load_time;
int64_t next_irq_time;
+ uint64_t frequency;
QEMUTimer *timer;
} CUDATimer;
@@ -97,6 +98,7 @@ typedef struct CUDAState {
CUDATimer timers[2];
uint32_t tick_offset;
+ uint64_t frequency;
uint8_t last_b;
uint8_t last_acr;
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index d525247..8453bfa 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -395,6 +395,7 @@ static void ppc_core99_init(MachineState *machine)
qdev_connect_gpio_out(dev, 2, pic[0x02]); /* IDE DMA */
qdev_connect_gpio_out(dev, 3, pic[0x0e]); /* IDE */
qdev_connect_gpio_out(dev, 4, pic[0x03]); /* IDE DMA */
+ qdev_prop_set_uint64(dev, "frequency", tbfreq);
macio_init(macio, pic_mem, escc_bar);
/* We only emulate 2 out of 3 IDE controllers for now */
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 863dd2f..630a9f9 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -286,6 +286,7 @@ static void ppc_heathrow_init(MachineState *machine)
qdev_connect_gpio_out(dev, 2, pic[0x02]); /* IDE-0 DMA */
qdev_connect_gpio_out(dev, 3, pic[0x0E]); /* IDE-1 */
qdev_connect_gpio_out(dev, 4, pic[0x03]); /* IDE-1 DMA */
+ qdev_prop_set_uint64(dev, "frequency", tbfreq);
macio_init(macio, pic_mem, escc_bar);
macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
--
1.8.1.4
- [Qemu-devel] [PULL 44/52] target-ppc: Special Case of rlwimi Should Use Deposit, (continued)
- [Qemu-devel] [PULL 44/52] target-ppc: Special Case of rlwimi Should Use Deposit, Alexander Graf, 2014/09/04
- [Qemu-devel] [PULL 42/52] spapr_pci: Fix config space corruption, Alexander Graf, 2014/09/04
- [Qemu-devel] [PULL 45/52] target-ppc: Optimize rlwinm MB=0 ME=31, Alexander Graf, 2014/09/04
- [Qemu-devel] [PULL 38/52] PPC: mac_nvram: Allow 2 and 4 byte accesses, Alexander Graf, 2014/09/04
- [Qemu-devel] [PULL 46/52] target-ppc: Optimize rlwnm MB=0 ME=31, Alexander Graf, 2014/09/04
- [Qemu-devel] [PULL 48/52] target-ppc: Clean up mullwo, Alexander Graf, 2014/09/04
- [Qemu-devel] [PULL 49/52] target-ppc: Implement mulldo with TCG, Alexander Graf, 2014/09/04
- [Qemu-devel] [PULL 43/52] spapr-vlan: Don't touch last entry in buffer list, Alexander Graf, 2014/09/04
- [Qemu-devel] [PULL 47/52] target-ppc: Clean Up mullw, Alexander Graf, 2014/09/04
- [Qemu-devel] [PULL 52/52] hypervisor property clashes with hypervisor node, Alexander Graf, 2014/09/04
- [Qemu-devel] [PULL 41/52] PPC: Cuda: Use cuda timer to expose tbfreq to guest,
Alexander Graf <=
- [Qemu-devel] [PULL 51/52] PPC: Fix default config ordering and add eTSEC for ppc64, Alexander Graf, 2014/09/04
- [Qemu-devel] [PULL 40/52] PPC: Mac: Move tbfreq into local variable, Alexander Graf, 2014/09/04
- [Qemu-devel] [PULL 50/52] spapr_pci: map the MSI window in each PHB, Alexander Graf, 2014/09/04
- Re: [Qemu-devel] [PULL 00/52] ppc patch queue 2014-09-04, Peter Maydell, 2014/09/04
- Re: [Qemu-devel] [PULL 00/52] ppc patch queue 2014-09-04, Alexander Graf, 2014/09/04
- Re: [Qemu-devel] [Qemu-ppc] [PULL 00/52] ppc patch queue 2014-09-04, Tom Musta, 2014/09/04
- Re: [Qemu-devel] [Qemu-ppc] [PULL 00/52] ppc patch queue 2014-09-04, Alexander Graf, 2014/09/04
- Re: [Qemu-devel] [Qemu-ppc] [PULL 00/52] ppc patch queue 2014-09-04, Peter Maydell, 2014/09/05
- Re: [Qemu-devel] [Qemu-ppc] [PULL 00/52] ppc patch queue 2014-09-04, Alexander Graf, 2014/09/08
- Re: [Qemu-devel] [Qemu-ppc] [PULL 00/52] ppc patch queue 2014-09-04, Peter Maydell, 2014/09/08