/* CUDA returns time_t's offset from Jan 1, 1904, not 1970 */
#define RTC_OFFSET 2082844800
-typedef struct CUDATimer {
- int index;
- uint16_t latch;
- uint16_t counter_value; /* counter value at load time */
- int64_t load_time;
- int64_t next_irq_time;
- QEMUTimer *timer;
-} CUDATimer;
-
-typedef struct CUDAState {
- MemoryRegion mem;
- /* cuda registers */
- uint8_t b; /* B-side data */
- uint8_t a; /* A-side data */
- uint8_t dirb; /* B-side direction (1=output) */
- uint8_t dira; /* A-side direction (1=output) */
- uint8_t sr; /* Shift register */
- uint8_t acr; /* Auxiliary control register */
- uint8_t pcr; /* Peripheral control register */
- uint8_t ifr; /* Interrupt flag register */
- uint8_t ier; /* Interrupt enable register */
- uint8_t anh; /* A-side data, no handshake */
-
- CUDATimer timers[2];
-
- uint32_t tick_offset;
-
- uint8_t last_b; /* last value of B register */
- uint8_t last_acr; /* last value of B register */
-
- int data_in_size;
- int data_in_index;
- int data_out_index;
-
- qemu_irq irq;
- uint8_t autopoll;
- uint8_t data_in[128];
- uint8_t data_out[16];
- QEMUTimer *adb_poll_timer;
-} CUDAState;
-
-static CUDAState cuda_state;
ADBBusState adb_bus;
static void cuda_update(CUDAState *s);
}
};
-static void cuda_reset(void *opaque)
+static void cuda_reset(DeviceState *dev)
{
- CUDAState *s = opaque;
+ CUDAState *s = CUDA(dev);
s->b = 0;
s->a = 0;
set_counter(s, &s->timers[1], 0xffff);
}
-void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq)
+static void cuda_realizefn(DeviceState *dev, Error **errp)
{
+ CUDAState *s = CUDA(dev);
struct tm tm;
- CUDAState *s = &cuda_state;
-
- s->irq = irq;
- s->timers[0].index = 0;
s->timers[0].timer = qemu_new_timer_ns(vm_clock, cuda_timer1, s);
- s->timers[1].index = 1;
-
qemu_get_timedate(&tm, 0);
s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
s->adb_poll_timer = qemu_new_timer_ns(vm_clock, cuda_adb_poll, s);
+}
+
+static void cuda_initfn(Object *obj)
+{
+ SysBusDevice *d = SYS_BUS_DEVICE(obj);
+ CUDAState *s = CUDA(obj);
+ int i;
+
memory_region_init_io(&s->mem, &cuda_ops, s, "cuda", 0x2000);
+ sysbus_init_mmio(d, &s->mem);
+ sysbus_init_irq(d, &s->irq);
+
+ for (i = 0; i < ARRAY_SIZE(s->timers); i++) {
+ s->timers[i].index = i;
+ }
+}
+
+static void cuda_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
- *cuda_mem = &s->mem;
- vmstate_register(NULL, -1, &vmstate_cuda, s);
- qemu_register_reset(cuda_reset, s);
+ dc->realize = cuda_realizefn;
+ dc->reset = cuda_reset;
+ dc->vmsd = &vmstate_cuda;
}
+
+static const TypeInfo cuda_type_info = {
+ .name = TYPE_CUDA,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(CUDAState),
+ .instance_init = cuda_initfn,
+ .class_init = cuda_class_init,
+};
+
+static void cuda_register_types(void)
+{
+ type_register_static(&cuda_type_info);
+}
+
+type_init(cuda_register_types)
/*< public >*/
MemoryRegion bar;
+ CUDAState cuda;
void *dbdma;
MemoryRegion *pic_mem;
- MemoryRegion *cuda_mem;
MemoryRegion *escc_mem;
} MacIOState;
MacIOState parent_obj;
/*< public >*/
- qemu_irq irqs[2];
+ qemu_irq irqs[3];
MacIONVRAMState nvram;
MACIOIDEState ide;
/*< private >*/
MacIOState parent_obj;
/*< public >*/
- qemu_irq irqs[4];
+ qemu_irq irqs[5];
MACIOIDEState ide[2];
} NewWorldMacIOState;
if (macio_state->escc_mem) {
memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem);
}
- if (macio_state->cuda_mem) {
- memory_region_add_subregion(bar, 0x16000, macio_state->cuda_mem);
- }
}
static int macio_common_initfn(PCIDevice *d)
{
MacIOState *s = MACIO(d);
+ SysBusDevice *sysbus_dev;
+ int ret;
d->config[0x3d] = 0x01; // interrupt on pin 1
+ ret = qdev_init(DEVICE(&s->cuda));
+ if (ret < 0) {
+ return ret;
+ }
+ sysbus_dev = SYS_BUS_DEVICE(&s->cuda);
+ memory_region_add_subregion(&s->bar, 0x16000,
+ sysbus_mmio_get_region(sysbus_dev, 0));
+
macio_bar_setup(s);
pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar);
return ret;
}
+ sysbus_dev = SYS_BUS_DEVICE(&s->cuda);
+ sysbus_connect_irq(sysbus_dev, 0, os->irqs[0]);
+
ret = qdev_init(DEVICE(&os->nvram));
if (ret < 0) {
return ret;
}
sysbus_dev = SYS_BUS_DEVICE(&os->ide);
- sysbus_connect_irq(sysbus_dev, 0, os->irqs[0]);
- sysbus_connect_irq(sysbus_dev, 1, os->irqs[1]);
+ sysbus_connect_irq(sysbus_dev, 0, os->irqs[1]);
+ sysbus_connect_irq(sysbus_dev, 1, os->irqs[2]);
macio_ide_register_dma(&os->ide, s->dbdma, 0x16);
ret = qdev_init(DEVICE(&os->ide));
if (ret < 0) {
return ret;
}
+ sysbus_dev = SYS_BUS_DEVICE(&s->cuda);
+ sysbus_connect_irq(sysbus_dev, 0, ns->irqs[0]);
+
if (s->pic_mem) {
/* OpenPIC */
memory_region_add_subregion(&s->bar, 0x40000, s->pic_mem);
}
sysbus_dev = SYS_BUS_DEVICE(&ns->ide[0]);
- sysbus_connect_irq(sysbus_dev, 0, ns->irqs[0]);
- sysbus_connect_irq(sysbus_dev, 1, ns->irqs[1]);
+ sysbus_connect_irq(sysbus_dev, 0, ns->irqs[1]);
+ sysbus_connect_irq(sysbus_dev, 1, ns->irqs[2]);
macio_ide_register_dma(&ns->ide[0], s->dbdma, 0x16);
ret = qdev_init(DEVICE(&ns->ide[0]));
if (ret < 0) {
}
sysbus_dev = SYS_BUS_DEVICE(&ns->ide[1]);
- sysbus_connect_irq(sysbus_dev, 0, ns->irqs[2]);
- sysbus_connect_irq(sysbus_dev, 1, ns->irqs[3]);
+ sysbus_connect_irq(sysbus_dev, 0, ns->irqs[3]);
+ sysbus_connect_irq(sysbus_dev, 1, ns->irqs[4]);
macio_ide_register_dma(&ns->ide[0], s->dbdma, 0x1a);
ret = qdev_init(DEVICE(&ns->ide[1]));
if (ret < 0) {
memory_region_init(&s->bar, "macio", 0x80000);
+ object_initialize(&s->cuda, TYPE_CUDA);
+ qdev_set_parent_bus(DEVICE(&s->cuda), sysbus_get_default());
+ object_property_add_child(obj, "cuda", OBJECT(&s->cuda), NULL);
+
s->dbdma = DBDMA_init(&dbdma_mem);
memory_region_add_subregion(&s->bar, 0x08000, dbdma_mem);
}
void macio_init(PCIDevice *d,
MemoryRegion *pic_mem,
- MemoryRegion *cuda_mem,
MemoryRegion *escc_mem)
{
MacIOState *macio_state = MACIO(d);
macio_state->pic_mem = pic_mem;
- macio_state->cuda_mem = cuda_mem;
macio_state->escc_mem = escc_mem;
/* Note: this code is strongly inspirated from the corresponding code
in PearPC */
#define ESCC_CLOCK 3686400
/* Cuda */
-void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq);
+#define TYPE_CUDA "cuda"
+#define CUDA(obj) OBJECT_CHECK(CUDAState, (obj), TYPE_CUDA)
+
+/**
+ * CUDATimer:
+ * @counter_value: counter value at load time
+ */
+typedef struct CUDATimer {
+ int index;
+ uint16_t latch;
+ uint16_t counter_value;
+ int64_t load_time;
+ int64_t next_irq_time;
+ QEMUTimer *timer;
+} CUDATimer;
+
+/**
+ * CUDAState:
+ * @b: B-side data
+ * @a: A-side data
+ * @dirb: B-side direction (1=output)
+ * @dira: A-side direction (1=output)
+ * @sr: Shift register
+ * @acr: Auxiliary control register
+ * @pcr: Peripheral control register
+ * @ifr: Interrupt flag register
+ * @ier: Interrupt enable register
+ * @anh: A-side data, no handshake
+ * @last_b: last value of B register
+ * @last_acr: last value of ACR register
+ */
+typedef struct CUDAState {
+ /*< private >*/
+ SysBusDevice parent_obj;
+ /*< public >*/
+
+ MemoryRegion mem;
+ /* cuda registers */
+ uint8_t b;
+ uint8_t a;
+ uint8_t dirb;
+ uint8_t dira;
+ uint8_t sr;
+ uint8_t acr;
+ uint8_t pcr;
+ uint8_t ifr;
+ uint8_t ier;
+ uint8_t anh;
+
+ CUDATimer timers[2];
+
+ uint32_t tick_offset;
+
+ uint8_t last_b;
+ uint8_t last_acr;
+
+ int data_in_size;
+ int data_in_index;
+ int data_out_index;
+
+ qemu_irq irq;
+ uint8_t autopoll;
+ uint8_t data_in[128];
+ uint8_t data_out[16];
+ QEMUTimer *adb_poll_timer;
+} CUDAState;
/* MacIO */
#define TYPE_OLDWORLD_MACIO "macio-oldworld"
void macio_init(PCIDevice *dev,
MemoryRegion *pic_mem,
- MemoryRegion *cuda_mem,
MemoryRegion *escc_mem);
/* Heathrow PIC */
MACIOIDEState *macio_ide;
MacIONVRAMState *nvr;
int bios_size;
- MemoryRegion *pic_mem, *cuda_mem, *escc_mem;
+ MemoryRegion *pic_mem, *escc_mem;
MemoryRegion *escc_bar = g_new(MemoryRegion, 1);
int ppc_boot_device;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
ide_drive_get(hd, MAX_IDE_BUS);
- cuda_init(&cuda_mem, pic[0x19]);
-
- adb_kbd_init(&adb_bus);
- adb_mouse_init(&adb_bus);
-
macio = pci_create(pci_bus, -1, TYPE_NEWWORLD_MACIO);
dev = DEVICE(macio);
- qdev_connect_gpio_out(dev, 0, pic[0x0d]); /* IDE */
- qdev_connect_gpio_out(dev, 1, pic[0x02]); /* IDE DMA */
- qdev_connect_gpio_out(dev, 2, pic[0x0e]); /* IDE */
- qdev_connect_gpio_out(dev, 3, pic[0x02]); /* IDE DMA */
- macio_init(macio, pic_mem, cuda_mem, escc_bar);
+ qdev_connect_gpio_out(dev, 0, pic[0x19]); /* CUDA */
+ qdev_connect_gpio_out(dev, 1, pic[0x0d]); /* IDE */
+ 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[0x02]); /* IDE DMA */
+ macio_init(macio, pic_mem, escc_bar);
/* We only emulate 2 out of 3 IDE controllers for now */
macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
"ide[1]"));
macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]);
+ adb_kbd_init(&adb_bus);
+ adb_mouse_init(&adb_bus);
+
if (usb_enabled(machine_arch == ARCH_MAC99_U3)) {
pci_create_simple(pci_bus, -1, "pci-ohci");
/* U3 needs to use USB for input because Linux doesn't support via-cuda
MACIOIDEState *macio_ide;
DeviceState *dev;
int bios_size;
- MemoryRegion *pic_mem, *cuda_mem;
+ MemoryRegion *pic_mem;
MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1);
uint16_t ppc_boot_device;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
ide_drive_get(hd, MAX_IDE_BUS);
- /* cuda also initialize ADB */
- cuda_init(&cuda_mem, pic[0x12]);
-
- adb_kbd_init(&adb_bus);
- adb_mouse_init(&adb_bus);
-
macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO);
dev = DEVICE(macio);
- qdev_connect_gpio_out(dev, 0, pic[0x0D]); /* IDE */
- qdev_connect_gpio_out(dev, 1, pic[0x02]); /* IDE DMA */
- macio_init(macio, pic_mem, cuda_mem, escc_bar);
+ qdev_connect_gpio_out(dev, 0, pic[0x12]); /* CUDA */
+ qdev_connect_gpio_out(dev, 1, pic[0x0D]); /* IDE */
+ qdev_connect_gpio_out(dev, 2, pic[0x02]); /* IDE DMA */
+ macio_init(macio, pic_mem, escc_bar);
/* First IDE channel is a MAC IDE on the MacIO bus */
macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
hd[3] = hd[2] = NULL;
pci_cmd646_ide_init(pci_bus, hd, 0);
+ adb_kbd_init(&adb_bus);
+ adb_mouse_init(&adb_bus);
+
if (usb_enabled(false)) {
pci_create_simple(pci_bus, -1, "pci-ohci");
}