diff options
-rw-r--r-- | hw/cuda.c | 95 | ||||
-rw-r--r-- | hw/macio.c | 43 | ||||
-rw-r--r-- | hw/ppc/mac.h | 68 | ||||
-rw-r--r-- | hw/ppc/mac_newworld.c | 21 | ||||
-rw-r--r-- | hw/ppc/mac_oldworld.c | 18 |
5 files changed, 154 insertions, 91 deletions
@@ -108,48 +108,6 @@ /* 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); @@ -701,9 +659,9 @@ static const VMStateDescription vmstate_cuda = { } }; -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; @@ -728,25 +686,54 @@ static void cuda_reset(void *opaque) 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) diff --git a/hw/macio.c b/hw/macio.c index 36c00e33a1..74bdcd1039 100644 --- a/hw/macio.c +++ b/hw/macio.c @@ -38,9 +38,9 @@ typedef struct MacIOState /*< public >*/ MemoryRegion bar; + CUDAState cuda; void *dbdma; MemoryRegion *pic_mem; - MemoryRegion *cuda_mem; MemoryRegion *escc_mem; } MacIOState; @@ -52,7 +52,7 @@ typedef struct OldWorldMacIOState { MacIOState parent_obj; /*< public >*/ - qemu_irq irqs[2]; + qemu_irq irqs[3]; MacIONVRAMState nvram; MACIOIDEState ide; @@ -65,7 +65,7 @@ typedef struct NewWorldMacIOState { /*< private >*/ MacIOState parent_obj; /*< public >*/ - qemu_irq irqs[4]; + qemu_irq irqs[5]; MACIOIDEState ide[2]; } NewWorldMacIOState; @@ -76,17 +76,24 @@ static void macio_bar_setup(MacIOState *macio_state) 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); @@ -103,6 +110,9 @@ static int macio_oldworld_initfn(PCIDevice *d) 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; @@ -118,8 +128,8 @@ static int macio_oldworld_initfn(PCIDevice *d) } 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) { @@ -158,14 +168,17 @@ static int macio_newworld_initfn(PCIDevice *d) 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) { @@ -173,8 +186,8 @@ static int macio_newworld_initfn(PCIDevice *d) } 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) { @@ -211,6 +224,10 @@ static void macio_instance_init(Object *obj) 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); } @@ -275,13 +292,11 @@ type_init(macio_register_types) 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 */ diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index 3e390d3ee9..26cb497b2d 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -44,7 +44,72 @@ #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" @@ -71,7 +136,6 @@ void macio_ide_register_dma(MACIOIDEState *ide, void *dbdma, int channel); void macio_init(PCIDevice *dev, MemoryRegion *pic_mem, - MemoryRegion *cuda_mem, MemoryRegion *escc_mem); /* Heathrow PIC */ diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 4fd86b042a..b9c58c188d 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -151,7 +151,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args) 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]; @@ -363,18 +363,14 @@ static void ppc_core99_init(QEMUMachineInitArgs *args) 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), @@ -385,6 +381,9 @@ static void ppc_core99_init(QEMUMachineInitArgs *args) "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 diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 6039ea61f4..9d9212a37e 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -93,7 +93,7 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args) 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]; @@ -263,17 +263,12 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args) 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), @@ -286,6 +281,9 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args) 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"); } |