macio.c (a504b9b91a1a884ce7e5296f4692b9cac85beab5) | macio.c (343bd85a40811f0522063e58d565c6965bd81e00) |
---|---|
1/* 2 * PowerMac MacIO device emulation 3 * 4 * Copyright (c) 2005-2007 Fabrice Bellard 5 * Copyright (c) 2007 Jocelyn Mayer 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal --- 29 unchanged lines hidden (view full) --- 38{ 39 /*< private >*/ 40 PCIDevice parent; 41 /*< public >*/ 42 43 MemoryRegion bar; 44 CUDAState cuda; 45 DBDMAState dbdma; | 1/* 2 * PowerMac MacIO device emulation 3 * 4 * Copyright (c) 2005-2007 Fabrice Bellard 5 * Copyright (c) 2007 Jocelyn Mayer 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal --- 29 unchanged lines hidden (view full) --- 38{ 39 /*< private >*/ 40 PCIDevice parent; 41 /*< public >*/ 42 43 MemoryRegion bar; 44 CUDAState cuda; 45 DBDMAState dbdma; |
46 ESCCState escc; |
|
46 MemoryRegion *pic_mem; | 47 MemoryRegion *pic_mem; |
47 MemoryRegion *escc_mem; | |
48 uint64_t frequency; 49} MacIOState; 50 51#define OLDWORLD_MACIO(obj) \ 52 OBJECT_CHECK(OldWorldMacIOState, (obj), TYPE_OLDWORLD_MACIO) 53 54typedef struct OldWorldMacIOState { 55 /*< private >*/ 56 MacIOState parent_obj; 57 /*< public >*/ 58 | 48 uint64_t frequency; 49} MacIOState; 50 51#define OLDWORLD_MACIO(obj) \ 52 OBJECT_CHECK(OldWorldMacIOState, (obj), TYPE_OLDWORLD_MACIO) 53 54typedef struct OldWorldMacIOState { 55 /*< private >*/ 56 MacIOState parent_obj; 57 /*< public >*/ 58 |
59 qemu_irq irqs[5]; | 59 qemu_irq irqs[7]; |
60 61 MacIONVRAMState nvram; 62 MACIOIDEState ide[2]; 63} OldWorldMacIOState; 64 65#define NEWWORLD_MACIO(obj) \ 66 OBJECT_CHECK(NewWorldMacIOState, (obj), TYPE_NEWWORLD_MACIO) 67 68typedef struct NewWorldMacIOState { 69 /*< private >*/ 70 MacIOState parent_obj; 71 /*< public >*/ | 60 61 MacIONVRAMState nvram; 62 MACIOIDEState ide[2]; 63} OldWorldMacIOState; 64 65#define NEWWORLD_MACIO(obj) \ 66 OBJECT_CHECK(NewWorldMacIOState, (obj), TYPE_NEWWORLD_MACIO) 67 68typedef struct NewWorldMacIOState { 69 /*< private >*/ 70 MacIOState parent_obj; 71 /*< public >*/ |
72 qemu_irq irqs[5]; | 72 qemu_irq irqs[7]; |
73 MACIOIDEState ide[2]; 74} NewWorldMacIOState; 75 76/* 77 * The mac-io has two interfaces to the ESCC. One is called "escc-legacy", 78 * while the other one is the normal, current ESCC interface. 79 * 80 * The magic below creates memory aliases to spawn the escc-legacy device 81 * purely by rerouting the respective registers to our escc region. This 82 * works because the only difference between the two memory regions is the 83 * register layout, not their semantics. 84 * 85 * Reference: ftp://ftp.software.ibm.com/rs6000/technology/spec/chrp/inwork/CHRP_IORef_1.0.pdf 86 */ | 73 MACIOIDEState ide[2]; 74} NewWorldMacIOState; 75 76/* 77 * The mac-io has two interfaces to the ESCC. One is called "escc-legacy", 78 * while the other one is the normal, current ESCC interface. 79 * 80 * The magic below creates memory aliases to spawn the escc-legacy device 81 * purely by rerouting the respective registers to our escc region. This 82 * works because the only difference between the two memory regions is the 83 * register layout, not their semantics. 84 * 85 * Reference: ftp://ftp.software.ibm.com/rs6000/technology/spec/chrp/inwork/CHRP_IORef_1.0.pdf 86 */ |
87static void macio_escc_legacy_setup(MacIOState *macio_state) | 87static void macio_escc_legacy_setup(MacIOState *s) |
88{ | 88{ |
89 ESCCState *escc = ESCC(&s->escc); 90 SysBusDevice *sbd = SYS_BUS_DEVICE(escc); |
|
89 MemoryRegion *escc_legacy = g_new(MemoryRegion, 1); | 91 MemoryRegion *escc_legacy = g_new(MemoryRegion, 1); |
90 MemoryRegion *bar = &macio_state->bar; | 92 MemoryRegion *bar = &s->bar; |
91 int i; 92 static const int maps[] = { 93 0x00, 0x00, /* Command B */ 94 0x02, 0x20, /* Command A */ 95 0x04, 0x10, /* Data B */ 96 0x06, 0x30, /* Data A */ 97 0x08, 0x40, /* Enhancement B */ 98 0x0A, 0x50, /* Enhancement A */ 99 0x80, 0x80, /* Recovery count */ 100 0x90, 0x90, /* Start A */ 101 0xa0, 0xa0, /* Start B */ 102 0xb0, 0xb0, /* Detect AB */ 103 }; 104 | 93 int i; 94 static const int maps[] = { 95 0x00, 0x00, /* Command B */ 96 0x02, 0x20, /* Command A */ 97 0x04, 0x10, /* Data B */ 98 0x06, 0x30, /* Data A */ 99 0x08, 0x40, /* Enhancement B */ 100 0x0A, 0x50, /* Enhancement A */ 101 0x80, 0x80, /* Recovery count */ 102 0x90, 0x90, /* Start A */ 103 0xa0, 0xa0, /* Start B */ 104 0xb0, 0xb0, /* Detect AB */ 105 }; 106 |
105 memory_region_init(escc_legacy, OBJECT(macio_state), "escc-legacy", 256); | 107 memory_region_init(escc_legacy, OBJECT(s), "escc-legacy", 256); |
106 for (i = 0; i < ARRAY_SIZE(maps); i += 2) { 107 MemoryRegion *port = g_new(MemoryRegion, 1); | 108 for (i = 0; i < ARRAY_SIZE(maps); i += 2) { 109 MemoryRegion *port = g_new(MemoryRegion, 1); |
108 memory_region_init_alias(port, OBJECT(macio_state), "escc-legacy-port", 109 macio_state->escc_mem, maps[i+1], 0x2); | 110 memory_region_init_alias(port, OBJECT(s), "escc-legacy-port", 111 sysbus_mmio_get_region(sbd, 0), 112 maps[i + 1], 0x2); |
110 memory_region_add_subregion(escc_legacy, maps[i], port); 111 } 112 113 memory_region_add_subregion(bar, 0x12000, escc_legacy); 114} 115 | 113 memory_region_add_subregion(escc_legacy, maps[i], port); 114 } 115 116 memory_region_add_subregion(bar, 0x12000, escc_legacy); 117} 118 |
116static void macio_bar_setup(MacIOState *macio_state) | 119static void macio_bar_setup(MacIOState *s) |
117{ | 120{ |
118 MemoryRegion *bar = &macio_state->bar; | 121 ESCCState *escc = ESCC(&s->escc); 122 SysBusDevice *sbd = SYS_BUS_DEVICE(escc); 123 MemoryRegion *bar = &s->bar; |
119 | 124 |
120 if (macio_state->escc_mem) { 121 memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem); 122 macio_escc_legacy_setup(macio_state); 123 } | 125 memory_region_add_subregion(bar, 0x13000, sysbus_mmio_get_region(sbd, 0)); 126 macio_escc_legacy_setup(s); |
124} 125 126static void macio_common_realize(PCIDevice *d, Error **errp) 127{ 128 MacIOState *s = MACIO(d); 129 SysBusDevice *sysbus_dev; 130 Error *err = NULL; 131 --- 10 unchanged lines hidden (view full) --- 142 if (err) { 143 error_propagate(errp, err); 144 return; 145 } 146 sysbus_dev = SYS_BUS_DEVICE(&s->cuda); 147 memory_region_add_subregion(&s->bar, 0x16000, 148 sysbus_mmio_get_region(sysbus_dev, 0)); 149 | 127} 128 129static void macio_common_realize(PCIDevice *d, Error **errp) 130{ 131 MacIOState *s = MACIO(d); 132 SysBusDevice *sysbus_dev; 133 Error *err = NULL; 134 --- 10 unchanged lines hidden (view full) --- 145 if (err) { 146 error_propagate(errp, err); 147 return; 148 } 149 sysbus_dev = SYS_BUS_DEVICE(&s->cuda); 150 memory_region_add_subregion(&s->bar, 0x16000, 151 sysbus_mmio_get_region(sysbus_dev, 0)); 152 |
153 object_property_set_bool(OBJECT(&s->escc), true, "realized", &err); 154 if (err) { 155 error_propagate(errp, err); 156 return; 157 } 158 |
|
150 macio_bar_setup(s); 151 pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar); 152} 153 154static void macio_realize_ide(MacIOState *s, MACIOIDEState *ide, 155 qemu_irq irq0, qemu_irq irq1, int dmaid, 156 Error **errp) 157{ --- 22 unchanged lines hidden (view full) --- 180 if (err) { 181 error_propagate(errp, err); 182 return; 183 } 184 185 sysbus_dev = SYS_BUS_DEVICE(&s->cuda); 186 sysbus_connect_irq(sysbus_dev, 0, os->irqs[cur_irq++]); 187 | 159 macio_bar_setup(s); 160 pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar); 161} 162 163static void macio_realize_ide(MacIOState *s, MACIOIDEState *ide, 164 qemu_irq irq0, qemu_irq irq1, int dmaid, 165 Error **errp) 166{ --- 22 unchanged lines hidden (view full) --- 189 if (err) { 190 error_propagate(errp, err); 191 return; 192 } 193 194 sysbus_dev = SYS_BUS_DEVICE(&s->cuda); 195 sysbus_connect_irq(sysbus_dev, 0, os->irqs[cur_irq++]); 196 |
197 sysbus_dev = SYS_BUS_DEVICE(&s->escc); 198 sysbus_connect_irq(sysbus_dev, 0, os->irqs[cur_irq++]); 199 sysbus_connect_irq(sysbus_dev, 1, os->irqs[cur_irq++]); 200 |
|
188 object_property_set_bool(OBJECT(&os->nvram), true, "realized", &err); 189 if (err) { 190 error_propagate(errp, err); 191 return; 192 } 193 sysbus_dev = SYS_BUS_DEVICE(&os->nvram); 194 memory_region_add_subregion(&s->bar, 0x60000, 195 sysbus_mmio_get_region(sysbus_dev, 0)); --- 96 unchanged lines hidden (view full) --- 292 if (err) { 293 error_propagate(errp, err); 294 return; 295 } 296 297 sysbus_dev = SYS_BUS_DEVICE(&s->cuda); 298 sysbus_connect_irq(sysbus_dev, 0, ns->irqs[cur_irq++]); 299 | 201 object_property_set_bool(OBJECT(&os->nvram), true, "realized", &err); 202 if (err) { 203 error_propagate(errp, err); 204 return; 205 } 206 sysbus_dev = SYS_BUS_DEVICE(&os->nvram); 207 memory_region_add_subregion(&s->bar, 0x60000, 208 sysbus_mmio_get_region(sysbus_dev, 0)); --- 96 unchanged lines hidden (view full) --- 305 if (err) { 306 error_propagate(errp, err); 307 return; 308 } 309 310 sysbus_dev = SYS_BUS_DEVICE(&s->cuda); 311 sysbus_connect_irq(sysbus_dev, 0, ns->irqs[cur_irq++]); 312 |
313 sysbus_dev = SYS_BUS_DEVICE(&s->escc); 314 sysbus_connect_irq(sysbus_dev, 0, ns->irqs[cur_irq++]); 315 sysbus_connect_irq(sysbus_dev, 1, ns->irqs[cur_irq++]); 316 |
|
300 if (s->pic_mem) { 301 /* OpenPIC */ 302 memory_region_add_subregion(&s->bar, 0x40000, s->pic_mem); 303 } 304 305 /* IDE buses */ 306 for (i = 0; i < ARRAY_SIZE(ns->ide); i++) { 307 qemu_irq irq0 = ns->irqs[cur_irq++]; --- 34 unchanged lines hidden (view full) --- 342 343 object_initialize(&s->cuda, sizeof(s->cuda), TYPE_CUDA); 344 qdev_set_parent_bus(DEVICE(&s->cuda), sysbus_get_default()); 345 object_property_add_child(obj, "cuda", OBJECT(&s->cuda), NULL); 346 347 object_initialize(&s->dbdma, sizeof(s->dbdma), TYPE_MAC_DBDMA); 348 qdev_set_parent_bus(DEVICE(&s->dbdma), sysbus_get_default()); 349 object_property_add_child(obj, "dbdma", OBJECT(&s->dbdma), NULL); | 317 if (s->pic_mem) { 318 /* OpenPIC */ 319 memory_region_add_subregion(&s->bar, 0x40000, s->pic_mem); 320 } 321 322 /* IDE buses */ 323 for (i = 0; i < ARRAY_SIZE(ns->ide); i++) { 324 qemu_irq irq0 = ns->irqs[cur_irq++]; --- 34 unchanged lines hidden (view full) --- 359 360 object_initialize(&s->cuda, sizeof(s->cuda), TYPE_CUDA); 361 qdev_set_parent_bus(DEVICE(&s->cuda), sysbus_get_default()); 362 object_property_add_child(obj, "cuda", OBJECT(&s->cuda), NULL); 363 364 object_initialize(&s->dbdma, sizeof(s->dbdma), TYPE_MAC_DBDMA); 365 qdev_set_parent_bus(DEVICE(&s->dbdma), sysbus_get_default()); 366 object_property_add_child(obj, "dbdma", OBJECT(&s->dbdma), NULL); |
367 368 object_initialize(&s->escc, sizeof(s->escc), TYPE_ESCC); 369 qdev_prop_set_uint32(DEVICE(&s->escc), "disabled", 0); 370 qdev_prop_set_uint32(DEVICE(&s->escc), "frequency", ESCC_CLOCK); 371 qdev_prop_set_uint32(DEVICE(&s->escc), "it_shift", 4); 372 qdev_prop_set_chr(DEVICE(&s->escc), "chrA", serial_hds[0]); 373 qdev_prop_set_chr(DEVICE(&s->escc), "chrB", serial_hds[1]); 374 qdev_prop_set_uint32(DEVICE(&s->escc), "chnBtype", escc_serial); 375 qdev_prop_set_uint32(DEVICE(&s->escc), "chnAtype", escc_serial); 376 qdev_set_parent_bus(DEVICE(&s->escc), sysbus_get_default()); 377 object_property_add_child(obj, "escc", OBJECT(&s->escc), NULL); |
|
350} 351 352static const VMStateDescription vmstate_macio_oldworld = { 353 .name = "macio-oldworld", 354 .version_id = 0, 355 .minimum_version_id = 0, 356 .fields = (VMStateField[]) { 357 VMSTATE_PCI_DEVICE(parent_obj.parent, OldWorldMacIOState), --- 81 unchanged lines hidden (view full) --- 439 type_register_static(&macio_type_info); 440 type_register_static(&macio_oldworld_type_info); 441 type_register_static(&macio_newworld_type_info); 442} 443 444type_init(macio_register_types) 445 446void macio_init(PCIDevice *d, | 378} 379 380static const VMStateDescription vmstate_macio_oldworld = { 381 .name = "macio-oldworld", 382 .version_id = 0, 383 .minimum_version_id = 0, 384 .fields = (VMStateField[]) { 385 VMSTATE_PCI_DEVICE(parent_obj.parent, OldWorldMacIOState), --- 81 unchanged lines hidden (view full) --- 467 type_register_static(&macio_type_info); 468 type_register_static(&macio_oldworld_type_info); 469 type_register_static(&macio_newworld_type_info); 470} 471 472type_init(macio_register_types) 473 474void macio_init(PCIDevice *d, |
447 MemoryRegion *pic_mem, 448 MemoryRegion *escc_mem) | 475 MemoryRegion *pic_mem) |
449{ 450 MacIOState *macio_state = MACIO(d); 451 452 macio_state->pic_mem = pic_mem; | 476{ 477 MacIOState *macio_state = MACIO(d); 478 479 macio_state->pic_mem = pic_mem; |
453 macio_state->escc_mem = escc_mem; | |
454 /* Note: this code is strongly inspirated from the corresponding code 455 in PearPC */ 456 qdev_prop_set_uint64(DEVICE(&macio_state->cuda), "timebase-frequency", 457 macio_state->frequency); 458 459 qdev_init_nofail(DEVICE(d)); 460} | 480 /* Note: this code is strongly inspirated from the corresponding code 481 in PearPC */ 482 qdev_prop_set_uint64(DEVICE(&macio_state->cuda), "timebase-frequency", 483 macio_state->frequency); 484 485 qdev_init_nofail(DEVICE(d)); 486} |