summaryrefslogtreecommitdiff
path: root/hw/misc/macio
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2013-06-30 05:15:14 +0200
committerAlexander Graf <agraf@suse.de>2013-07-11 18:51:25 +0200
commita0f9fdfd98cc0571f9921a7eadd7316532e3e289 (patch)
treec72a0bf79b976d84011bc8f8e2450691b8a9532f /hw/misc/macio
parent80fc95d8bdaf3392106b131a97ca701fd374489a (diff)
downloadqemu-a0f9fdfd98cc0571f9921a7eadd7316532e3e289.tar.gz
PPC: Add timer handler for newworld mac-io
Mac OS X accesses fancy timer registers inside of the mac-io on bootup. These really should be ticking at the mac-io bus frequency, but I don't see anyone upset when we just make them as fast as we want to. With this patch on top of my previous patch queue and latest OpenBIOS I am able to boot Mac OS X 10.4 with -M mac99. Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'hw/misc/macio')
-rw-r--r--hw/misc/macio/macio.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
index 6459bc1325..c0d0bf7287 100644
--- a/hw/misc/macio/macio.c
+++ b/hw/misc/macio/macio.c
@@ -234,11 +234,39 @@ static void macio_oldworld_init(Object *obj)
}
}
+static void timer_write(void *opaque, hwaddr addr, uint64_t value,
+ unsigned size)
+{
+}
+
+static uint64_t timer_read(void *opaque, hwaddr addr, unsigned size)
+{
+ uint32_t value = 0;
+
+ switch (addr) {
+ case 0x38:
+ value = qemu_get_clock_ns(vm_clock);
+ break;
+ case 0x3c:
+ value = qemu_get_clock_ns(vm_clock) >> 32;
+ break;
+ }
+
+ return value;
+}
+
+static const MemoryRegionOps timer_ops = {
+ .read = timer_read,
+ .write = timer_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
static int macio_newworld_initfn(PCIDevice *d)
{
MacIOState *s = MACIO(d);
NewWorldMacIOState *ns = NEWWORLD_MACIO(d);
SysBusDevice *sysbus_dev;
+ MemoryRegion *timer_memory = g_new(MemoryRegion, 1);
int i;
int cur_irq = 0;
int ret = macio_common_initfn(d);
@@ -265,6 +293,11 @@ static int macio_newworld_initfn(PCIDevice *d)
}
}
+ /* Timer */
+ memory_region_init_io(timer_memory, OBJECT(s), &timer_ops, NULL, "timer",
+ 0x1000);
+ memory_region_add_subregion(&s->bar, 0x15000, timer_memory);
+
return 0;
}