]>
Commit | Line | Data |
---|---|---|
3cbee15b JM |
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 | |
9 | * in the Software without restriction, including without limitation the rights | |
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
11 | * copies of the Software, and to permit persons to whom the Software is | |
12 | * furnished to do so, subject to the following conditions: | |
13 | * | |
14 | * The above copyright notice and this permission notice shall be included in | |
15 | * all copies or substantial portions of the Software. | |
16 | * | |
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
23 | * THE SOFTWARE. | |
24 | */ | |
0b8fa32f | 25 | |
0d75590d | 26 | #include "qemu/osdep.h" |
da34e65c | 27 | #include "qapi/error.h" |
0b8fa32f | 28 | #include "qemu/module.h" |
83c9f4ca | 29 | #include "hw/ppc/mac.h" |
7092e84d | 30 | #include "hw/misc/macio/cuda.h" |
83c9f4ca | 31 | #include "hw/pci/pci.h" |
0d09e41a | 32 | #include "hw/ppc/mac_dbdma.h" |
a27bd6c7 | 33 | #include "hw/qdev-properties.h" |
d6454270 | 34 | #include "migration/vmstate.h" |
0d09e41a | 35 | #include "hw/char/escc.h" |
e1218e48 | 36 | #include "hw/misc/macio/macio.h" |
017812df | 37 | #include "hw/intc/heathrow_pic.h" |
2f780b6a | 38 | #include "sysemu/sysemu.h" |
56e7404b | 39 | #include "trace.h" |
07a7484e | 40 | |
b6712ea3 MCA |
41 | /* Note: this code is strongly inspirated from the corresponding code |
42 | * in PearPC */ | |
43 | ||
0d54a502 AG |
44 | /* |
45 | * The mac-io has two interfaces to the ESCC. One is called "escc-legacy", | |
46 | * while the other one is the normal, current ESCC interface. | |
47 | * | |
48 | * The magic below creates memory aliases to spawn the escc-legacy device | |
49 | * purely by rerouting the respective registers to our escc region. This | |
50 | * works because the only difference between the two memory regions is the | |
51 | * register layout, not their semantics. | |
52 | * | |
53 | * Reference: ftp://ftp.software.ibm.com/rs6000/technology/spec/chrp/inwork/CHRP_IORef_1.0.pdf | |
54 | */ | |
343bd85a | 55 | static void macio_escc_legacy_setup(MacIOState *s) |
0d54a502 | 56 | { |
343bd85a MCA |
57 | ESCCState *escc = ESCC(&s->escc); |
58 | SysBusDevice *sbd = SYS_BUS_DEVICE(escc); | |
0d54a502 | 59 | MemoryRegion *escc_legacy = g_new(MemoryRegion, 1); |
343bd85a | 60 | MemoryRegion *bar = &s->bar; |
0d54a502 AG |
61 | int i; |
62 | static const int maps[] = { | |
dd2fa4f7 BH |
63 | 0x00, 0x00, /* Command B */ |
64 | 0x02, 0x20, /* Command A */ | |
65 | 0x04, 0x10, /* Data B */ | |
66 | 0x06, 0x30, /* Data A */ | |
67 | 0x08, 0x40, /* Enhancement B */ | |
68 | 0x0A, 0x50, /* Enhancement A */ | |
69 | 0x80, 0x80, /* Recovery count */ | |
70 | 0x90, 0x90, /* Start A */ | |
71 | 0xa0, 0xa0, /* Start B */ | |
72 | 0xb0, 0xb0, /* Detect AB */ | |
0d54a502 AG |
73 | }; |
74 | ||
343bd85a | 75 | memory_region_init(escc_legacy, OBJECT(s), "escc-legacy", 256); |
0d54a502 AG |
76 | for (i = 0; i < ARRAY_SIZE(maps); i += 2) { |
77 | MemoryRegion *port = g_new(MemoryRegion, 1); | |
343bd85a MCA |
78 | memory_region_init_alias(port, OBJECT(s), "escc-legacy-port", |
79 | sysbus_mmio_get_region(sbd, 0), | |
80 | maps[i + 1], 0x2); | |
0d54a502 AG |
81 | memory_region_add_subregion(escc_legacy, maps[i], port); |
82 | } | |
83 | ||
84 | memory_region_add_subregion(bar, 0x12000, escc_legacy); | |
85 | } | |
86 | ||
343bd85a | 87 | static void macio_bar_setup(MacIOState *s) |
3cbee15b | 88 | { |
343bd85a MCA |
89 | ESCCState *escc = ESCC(&s->escc); |
90 | SysBusDevice *sbd = SYS_BUS_DEVICE(escc); | |
91 | MemoryRegion *bar = &s->bar; | |
3cbee15b | 92 | |
343bd85a MCA |
93 | memory_region_add_subregion(bar, 0x13000, sysbus_mmio_get_region(sbd, 0)); |
94 | macio_escc_legacy_setup(s); | |
3cbee15b JM |
95 | } |
96 | ||
62e9cd77 | 97 | static void macio_common_realize(PCIDevice *d, Error **errp) |
d8c51b05 | 98 | { |
7b925079 | 99 | MacIOState *s = MACIO(d); |
45fa67fb | 100 | SysBusDevice *sysbus_dev; |
62e9cd77 | 101 | Error *err = NULL; |
c7104402 | 102 | |
118bfd76 | 103 | if (!qdev_realize(DEVICE(&s->dbdma), BUS(&s->macio_bus), &err)) { |
ecba28db MCA |
104 | error_propagate(errp, err); |
105 | return; | |
106 | } | |
a504b9b9 | 107 | sysbus_dev = SYS_BUS_DEVICE(&s->dbdma); |
ecba28db MCA |
108 | memory_region_add_subregion(&s->bar, 0x08000, |
109 | sysbus_mmio_get_region(sysbus_dev, 0)); | |
7b925079 | 110 | |
ddd835f3 TH |
111 | qdev_prop_set_uint32(DEVICE(&s->escc), "disabled", 0); |
112 | qdev_prop_set_uint32(DEVICE(&s->escc), "frequency", ESCC_CLOCK); | |
113 | qdev_prop_set_uint32(DEVICE(&s->escc), "it_shift", 4); | |
9bca0edb PM |
114 | qdev_prop_set_chr(DEVICE(&s->escc), "chrA", serial_hd(0)); |
115 | qdev_prop_set_chr(DEVICE(&s->escc), "chrB", serial_hd(1)); | |
ddd835f3 TH |
116 | qdev_prop_set_uint32(DEVICE(&s->escc), "chnBtype", escc_serial); |
117 | qdev_prop_set_uint32(DEVICE(&s->escc), "chnAtype", escc_serial); | |
118bfd76 | 118 | if (!qdev_realize(DEVICE(&s->escc), BUS(&s->macio_bus), &err)) { |
343bd85a MCA |
119 | error_propagate(errp, err); |
120 | return; | |
121 | } | |
122 | ||
7b925079 AF |
123 | macio_bar_setup(s); |
124 | pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar); | |
d8c51b05 AL |
125 | } |
126 | ||
62e9cd77 MA |
127 | static void macio_realize_ide(MacIOState *s, MACIOIDEState *ide, |
128 | qemu_irq irq0, qemu_irq irq1, int dmaid, | |
129 | Error **errp) | |
14eefd0e AG |
130 | { |
131 | SysBusDevice *sysbus_dev; | |
132 | ||
133 | sysbus_dev = SYS_BUS_DEVICE(ide); | |
134 | sysbus_connect_irq(sysbus_dev, 0, irq0); | |
135 | sysbus_connect_irq(sysbus_dev, 1, irq1); | |
0fc84331 | 136 | qdev_prop_set_uint32(DEVICE(ide), "channel", dmaid); |
2726dc51 MA |
137 | object_property_set_link(OBJECT(ide), OBJECT(&s->dbdma), "dbdma", |
138 | &error_abort); | |
e451b85f | 139 | macio_ide_register_dma(ide); |
0fc84331 | 140 | |
f4a0df70 | 141 | qdev_realize(DEVICE(ide), BUS(&s->macio_bus), errp); |
14eefd0e AG |
142 | } |
143 | ||
62e9cd77 | 144 | static void macio_oldworld_realize(PCIDevice *d, Error **errp) |
d037834a AF |
145 | { |
146 | MacIOState *s = MACIO(d); | |
95ed3b7c | 147 | OldWorldMacIOState *os = OLDWORLD_MACIO(d); |
20d2514a | 148 | DeviceState *pic_dev = DEVICE(os->pic); |
62e9cd77 | 149 | Error *err = NULL; |
95ed3b7c | 150 | SysBusDevice *sysbus_dev; |
62e9cd77 MA |
151 | |
152 | macio_common_realize(d, &err); | |
153 | if (err) { | |
154 | error_propagate(errp, err); | |
155 | return; | |
d037834a AF |
156 | } |
157 | ||
d811d61f MCA |
158 | qdev_prop_set_uint64(DEVICE(&s->cuda), "timebase-frequency", |
159 | s->frequency); | |
118bfd76 | 160 | if (!qdev_realize(DEVICE(&s->cuda), BUS(&s->macio_bus), &err)) { |
d811d61f MCA |
161 | error_propagate(errp, err); |
162 | return; | |
163 | } | |
45fa67fb | 164 | sysbus_dev = SYS_BUS_DEVICE(&s->cuda); |
d811d61f MCA |
165 | memory_region_add_subregion(&s->bar, 0x16000, |
166 | sysbus_mmio_get_region(sysbus_dev, 0)); | |
20d2514a MCA |
167 | sysbus_connect_irq(sysbus_dev, 0, qdev_get_gpio_in(pic_dev, |
168 | OLDWORLD_CUDA_IRQ)); | |
45fa67fb | 169 | |
343bd85a | 170 | sysbus_dev = SYS_BUS_DEVICE(&s->escc); |
20d2514a MCA |
171 | sysbus_connect_irq(sysbus_dev, 0, qdev_get_gpio_in(pic_dev, |
172 | OLDWORLD_ESCCB_IRQ)); | |
173 | sysbus_connect_irq(sysbus_dev, 1, qdev_get_gpio_in(pic_dev, | |
174 | OLDWORLD_ESCCA_IRQ)); | |
343bd85a | 175 | |
118bfd76 | 176 | if (!qdev_realize(DEVICE(&os->nvram), BUS(&s->macio_bus), &err)) { |
62e9cd77 MA |
177 | error_propagate(errp, err); |
178 | return; | |
95ed3b7c AF |
179 | } |
180 | sysbus_dev = SYS_BUS_DEVICE(&os->nvram); | |
181 | memory_region_add_subregion(&s->bar, 0x60000, | |
182 | sysbus_mmio_get_region(sysbus_dev, 0)); | |
183 | pmac_format_nvram_partition(&os->nvram, os->nvram.size); | |
184 | ||
017812df MCA |
185 | /* Heathrow PIC */ |
186 | sysbus_dev = SYS_BUS_DEVICE(os->pic); | |
187 | memory_region_add_subregion(&s->bar, 0x0, | |
188 | sysbus_mmio_get_region(sysbus_dev, 0)); | |
d037834a | 189 | |
14eefd0e | 190 | /* IDE buses */ |
20d2514a MCA |
191 | macio_realize_ide(s, &os->ide[0], |
192 | qdev_get_gpio_in(pic_dev, OLDWORLD_IDE0_IRQ), | |
193 | qdev_get_gpio_in(pic_dev, OLDWORLD_IDE0_DMA_IRQ), | |
194 | 0x16, &err); | |
195 | if (err) { | |
196 | error_propagate(errp, err); | |
197 | return; | |
198 | } | |
199 | ||
200 | macio_realize_ide(s, &os->ide[1], | |
201 | qdev_get_gpio_in(pic_dev, OLDWORLD_IDE1_IRQ), | |
202 | qdev_get_gpio_in(pic_dev, OLDWORLD_IDE1_DMA_IRQ), | |
203 | 0x1a, &err); | |
204 | if (err) { | |
205 | error_propagate(errp, err); | |
206 | return; | |
07a7484e | 207 | } |
d037834a AF |
208 | } |
209 | ||
8fb9cfe7 | 210 | static void macio_init_ide(MacIOState *s, MACIOIDEState *ide, int index) |
14eefd0e | 211 | { |
1069a3c6 | 212 | gchar *name = g_strdup_printf("ide[%i]", index); |
5c8e3d17 | 213 | uint32_t addr = 0x1f000 + ((index + 1) * 0x1000); |
14eefd0e | 214 | |
8fb9cfe7 | 215 | object_initialize_child(OBJECT(s), name, ide, TYPE_MACIO_IDE); |
5c8e3d17 MCA |
216 | qdev_prop_set_uint32(DEVICE(ide), "addr", addr); |
217 | memory_region_add_subregion(&s->bar, addr, &ide->mem); | |
14eefd0e AG |
218 | g_free(name); |
219 | } | |
220 | ||
95ed3b7c AF |
221 | static void macio_oldworld_init(Object *obj) |
222 | { | |
07a7484e | 223 | MacIOState *s = MACIO(obj); |
95ed3b7c AF |
224 | OldWorldMacIOState *os = OLDWORLD_MACIO(obj); |
225 | DeviceState *dev; | |
14eefd0e | 226 | int i; |
95ed3b7c | 227 | |
017812df MCA |
228 | object_property_add_link(obj, "pic", TYPE_HEATHROW, |
229 | (Object **) &os->pic, | |
230 | qdev_prop_allow_set_link_before_realize, | |
d2623129 | 231 | 0); |
017812df | 232 | |
8fb9cfe7 | 233 | object_initialize_child(OBJECT(s), "cuda", &s->cuda, TYPE_CUDA); |
d811d61f | 234 | |
8fb9cfe7 | 235 | object_initialize_child(OBJECT(s), "nvram", &os->nvram, TYPE_MACIO_NVRAM); |
95ed3b7c AF |
236 | dev = DEVICE(&os->nvram); |
237 | qdev_prop_set_uint32(dev, "size", 0x2000); | |
238 | qdev_prop_set_uint32(dev, "it_shift", 4); | |
07a7484e | 239 | |
14eefd0e | 240 | for (i = 0; i < 2; i++) { |
8fb9cfe7 | 241 | macio_init_ide(s, &os->ide[i], i); |
14eefd0e | 242 | } |
95ed3b7c AF |
243 | } |
244 | ||
a0f9fdfd AG |
245 | static void timer_write(void *opaque, hwaddr addr, uint64_t value, |
246 | unsigned size) | |
247 | { | |
56e7404b | 248 | trace_macio_timer_write(addr, size, value); |
a0f9fdfd AG |
249 | } |
250 | ||
251 | static uint64_t timer_read(void *opaque, hwaddr addr, unsigned size) | |
252 | { | |
253 | uint32_t value = 0; | |
d696760b AG |
254 | uint64_t systime = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); |
255 | uint64_t kltime; | |
256 | ||
73bcb24d | 257 | kltime = muldiv64(systime, 4194300, NANOSECONDS_PER_SECOND * 4); |
d696760b | 258 | kltime = muldiv64(kltime, 18432000, 1048575); |
a0f9fdfd AG |
259 | |
260 | switch (addr) { | |
261 | case 0x38: | |
d696760b | 262 | value = kltime; |
a0f9fdfd AG |
263 | break; |
264 | case 0x3c: | |
d696760b | 265 | value = kltime >> 32; |
a0f9fdfd AG |
266 | break; |
267 | } | |
268 | ||
56e7404b | 269 | trace_macio_timer_read(addr, size, value); |
a0f9fdfd AG |
270 | return value; |
271 | } | |
272 | ||
273 | static const MemoryRegionOps timer_ops = { | |
274 | .read = timer_read, | |
275 | .write = timer_write, | |
9397a7c8 | 276 | .endianness = DEVICE_LITTLE_ENDIAN, |
a0f9fdfd AG |
277 | }; |
278 | ||
62e9cd77 | 279 | static void macio_newworld_realize(PCIDevice *d, Error **errp) |
d037834a AF |
280 | { |
281 | MacIOState *s = MACIO(d); | |
07a7484e | 282 | NewWorldMacIOState *ns = NEWWORLD_MACIO(d); |
0fcd2a81 | 283 | DeviceState *pic_dev = DEVICE(ns->pic); |
62e9cd77 | 284 | Error *err = NULL; |
07a7484e | 285 | SysBusDevice *sysbus_dev; |
6c5819c4 | 286 | MemoryRegion *timer_memory = NULL; |
62e9cd77 MA |
287 | |
288 | macio_common_realize(d, &err); | |
289 | if (err) { | |
290 | error_propagate(errp, err); | |
291 | return; | |
d037834a AF |
292 | } |
293 | ||
343bd85a | 294 | sysbus_dev = SYS_BUS_DEVICE(&s->escc); |
0fcd2a81 MCA |
295 | sysbus_connect_irq(sysbus_dev, 0, qdev_get_gpio_in(pic_dev, |
296 | NEWWORLD_ESCCB_IRQ)); | |
297 | sysbus_connect_irq(sysbus_dev, 1, qdev_get_gpio_in(pic_dev, | |
298 | NEWWORLD_ESCCA_IRQ)); | |
343bd85a | 299 | |
dda12e9a MCA |
300 | /* OpenPIC */ |
301 | sysbus_dev = SYS_BUS_DEVICE(ns->pic); | |
302 | memory_region_add_subregion(&s->bar, 0x40000, | |
303 | sysbus_mmio_get_region(sysbus_dev, 0)); | |
d037834a | 304 | |
14eefd0e | 305 | /* IDE buses */ |
0fcd2a81 MCA |
306 | macio_realize_ide(s, &ns->ide[0], |
307 | qdev_get_gpio_in(pic_dev, NEWWORLD_IDE0_IRQ), | |
308 | qdev_get_gpio_in(pic_dev, NEWWORLD_IDE0_DMA_IRQ), | |
309 | 0x16, &err); | |
310 | if (err) { | |
311 | error_propagate(errp, err); | |
312 | return; | |
313 | } | |
314 | ||
315 | macio_realize_ide(s, &ns->ide[1], | |
316 | qdev_get_gpio_in(pic_dev, NEWWORLD_IDE1_IRQ), | |
317 | qdev_get_gpio_in(pic_dev, NEWWORLD_IDE1_DMA_IRQ), | |
318 | 0x1a, &err); | |
319 | if (err) { | |
320 | error_propagate(errp, err); | |
321 | return; | |
07a7484e AF |
322 | } |
323 | ||
a0f9fdfd | 324 | /* Timer */ |
6c5819c4 | 325 | timer_memory = g_new(MemoryRegion, 1); |
a0f9fdfd AG |
326 | memory_region_init_io(timer_memory, OBJECT(s), &timer_ops, NULL, "timer", |
327 | 0x1000); | |
328 | memory_region_add_subregion(&s->bar, 0x15000, timer_memory); | |
7c4166a9 MCA |
329 | |
330 | if (ns->has_pmu) { | |
331 | /* GPIOs */ | |
332 | sysbus_dev = SYS_BUS_DEVICE(&ns->gpio); | |
333 | object_property_set_link(OBJECT(&ns->gpio), OBJECT(pic_dev), "pic", | |
334 | &error_abort); | |
335 | memory_region_add_subregion(&s->bar, 0x50, | |
336 | sysbus_mmio_get_region(sysbus_dev, 0)); | |
f4a0df70 | 337 | qdev_realize(DEVICE(&ns->gpio), BUS(&s->macio_bus), &err); |
d811d61f MCA |
338 | |
339 | /* PMU */ | |
9fc7fc4d | 340 | object_initialize_child(OBJECT(s), "pmu", &s->pmu, TYPE_VIA_PMU); |
d811d61f MCA |
341 | object_property_set_link(OBJECT(&s->pmu), OBJECT(sysbus_dev), "gpio", |
342 | &error_abort); | |
343 | qdev_prop_set_bit(DEVICE(&s->pmu), "has-adb", ns->has_adb); | |
118bfd76 | 344 | if (!qdev_realize(DEVICE(&s->pmu), BUS(&s->macio_bus), &err)) { |
d811d61f MCA |
345 | error_propagate(errp, err); |
346 | return; | |
347 | } | |
348 | sysbus_dev = SYS_BUS_DEVICE(&s->pmu); | |
349 | sysbus_connect_irq(sysbus_dev, 0, qdev_get_gpio_in(pic_dev, | |
350 | NEWWORLD_PMU_IRQ)); | |
351 | memory_region_add_subregion(&s->bar, 0x16000, | |
352 | sysbus_mmio_get_region(sysbus_dev, 0)); | |
353 | } else { | |
33208432 MA |
354 | object_unparent(OBJECT(&ns->gpio)); |
355 | ||
d811d61f | 356 | /* CUDA */ |
9fc7fc4d | 357 | object_initialize_child(OBJECT(s), "cuda", &s->cuda, TYPE_CUDA); |
d811d61f MCA |
358 | qdev_prop_set_uint64(DEVICE(&s->cuda), "timebase-frequency", |
359 | s->frequency); | |
360 | ||
118bfd76 | 361 | if (!qdev_realize(DEVICE(&s->cuda), BUS(&s->macio_bus), &err)) { |
d811d61f MCA |
362 | error_propagate(errp, err); |
363 | return; | |
364 | } | |
365 | sysbus_dev = SYS_BUS_DEVICE(&s->cuda); | |
366 | sysbus_connect_irq(sysbus_dev, 0, qdev_get_gpio_in(pic_dev, | |
367 | NEWWORLD_CUDA_IRQ)); | |
368 | memory_region_add_subregion(&s->bar, 0x16000, | |
369 | sysbus_mmio_get_region(sysbus_dev, 0)); | |
7c4166a9 | 370 | } |
d037834a AF |
371 | } |
372 | ||
07a7484e AF |
373 | static void macio_newworld_init(Object *obj) |
374 | { | |
375 | MacIOState *s = MACIO(obj); | |
376 | NewWorldMacIOState *ns = NEWWORLD_MACIO(obj); | |
377 | int i; | |
07a7484e | 378 | |
dda12e9a MCA |
379 | object_property_add_link(obj, "pic", TYPE_OPENPIC, |
380 | (Object **) &ns->pic, | |
381 | qdev_prop_allow_set_link_before_realize, | |
d2623129 | 382 | 0); |
dda12e9a | 383 | |
8fb9cfe7 | 384 | object_initialize_child(OBJECT(s), "gpio", &ns->gpio, TYPE_MACIO_GPIO); |
7c4166a9 | 385 | |
07a7484e | 386 | for (i = 0; i < 2; i++) { |
8fb9cfe7 | 387 | macio_init_ide(s, &ns->ide[i], i); |
07a7484e AF |
388 | } |
389 | } | |
390 | ||
fcf1bbab AF |
391 | static void macio_instance_init(Object *obj) |
392 | { | |
393 | MacIOState *s = MACIO(obj); | |
394 | ||
81e0ab48 | 395 | memory_region_init(&s->bar, obj, "macio", 0x80000); |
07a7484e | 396 | |
bf31c56f MCA |
397 | qbus_create_inplace(&s->macio_bus, sizeof(s->macio_bus), TYPE_MACIO_BUS, |
398 | DEVICE(obj), "macio.0"); | |
343bd85a | 399 | |
8fb9cfe7 | 400 | object_initialize_child(OBJECT(s), "dbdma", &s->dbdma, TYPE_MAC_DBDMA); |
bf31c56f | 401 | |
8fb9cfe7 | 402 | object_initialize_child(OBJECT(s), "escc", &s->escc, TYPE_ESCC); |
fcf1bbab AF |
403 | } |
404 | ||
02635923 MCA |
405 | static const VMStateDescription vmstate_macio_oldworld = { |
406 | .name = "macio-oldworld", | |
407 | .version_id = 0, | |
408 | .minimum_version_id = 0, | |
409 | .fields = (VMStateField[]) { | |
410 | VMSTATE_PCI_DEVICE(parent_obj.parent, OldWorldMacIOState), | |
411 | VMSTATE_END_OF_LIST() | |
412 | } | |
413 | }; | |
414 | ||
d037834a AF |
415 | static void macio_oldworld_class_init(ObjectClass *oc, void *data) |
416 | { | |
417 | PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc); | |
02635923 | 418 | DeviceClass *dc = DEVICE_CLASS(oc); |
d037834a | 419 | |
62e9cd77 | 420 | pdc->realize = macio_oldworld_realize; |
d037834a | 421 | pdc->device_id = PCI_DEVICE_ID_APPLE_343S1201; |
02635923 | 422 | dc->vmsd = &vmstate_macio_oldworld; |
d037834a AF |
423 | } |
424 | ||
02635923 MCA |
425 | static const VMStateDescription vmstate_macio_newworld = { |
426 | .name = "macio-newworld", | |
427 | .version_id = 0, | |
428 | .minimum_version_id = 0, | |
429 | .fields = (VMStateField[]) { | |
430 | VMSTATE_PCI_DEVICE(parent_obj.parent, NewWorldMacIOState), | |
431 | VMSTATE_END_OF_LIST() | |
432 | } | |
433 | }; | |
434 | ||
f1114c17 MCA |
435 | static Property macio_newworld_properties[] = { |
436 | DEFINE_PROP_BOOL("has-pmu", NewWorldMacIOState, has_pmu, false), | |
437 | DEFINE_PROP_BOOL("has-adb", NewWorldMacIOState, has_adb, false), | |
438 | DEFINE_PROP_END_OF_LIST() | |
439 | }; | |
440 | ||
d037834a AF |
441 | static void macio_newworld_class_init(ObjectClass *oc, void *data) |
442 | { | |
443 | PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc); | |
02635923 | 444 | DeviceClass *dc = DEVICE_CLASS(oc); |
d037834a | 445 | |
62e9cd77 | 446 | pdc->realize = macio_newworld_realize; |
d037834a | 447 | pdc->device_id = PCI_DEVICE_ID_APPLE_UNI_N_KEYL; |
02635923 | 448 | dc->vmsd = &vmstate_macio_newworld; |
4f67d30b | 449 | device_class_set_props(dc, macio_newworld_properties); |
d037834a AF |
450 | } |
451 | ||
b981289c AG |
452 | static Property macio_properties[] = { |
453 | DEFINE_PROP_UINT64("frequency", MacIOState, frequency, 0), | |
454 | DEFINE_PROP_END_OF_LIST() | |
455 | }; | |
456 | ||
40021f08 AL |
457 | static void macio_class_init(ObjectClass *klass, void *data) |
458 | { | |
459 | PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); | |
b981289c | 460 | DeviceClass *dc = DEVICE_CLASS(klass); |
40021f08 | 461 | |
40021f08 AL |
462 | k->vendor_id = PCI_VENDOR_ID_APPLE; |
463 | k->class_id = PCI_CLASS_OTHERS << 8; | |
4f67d30b | 464 | device_class_set_props(dc, macio_properties); |
f9f2a9f2 | 465 | set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); |
1ca15d85 TH |
466 | /* Reason: Uses serial_hds in macio_instance_init */ |
467 | dc->user_creatable = false; | |
40021f08 AL |
468 | } |
469 | ||
bf31c56f MCA |
470 | static const TypeInfo macio_bus_info = { |
471 | .name = TYPE_MACIO_BUS, | |
6741a343 | 472 | .parent = TYPE_SYSTEM_BUS, |
bf31c56f MCA |
473 | .instance_size = sizeof(MacIOBusState), |
474 | }; | |
475 | ||
d037834a AF |
476 | static const TypeInfo macio_oldworld_type_info = { |
477 | .name = TYPE_OLDWORLD_MACIO, | |
478 | .parent = TYPE_MACIO, | |
95ed3b7c AF |
479 | .instance_size = sizeof(OldWorldMacIOState), |
480 | .instance_init = macio_oldworld_init, | |
d037834a AF |
481 | .class_init = macio_oldworld_class_init, |
482 | }; | |
483 | ||
484 | static const TypeInfo macio_newworld_type_info = { | |
485 | .name = TYPE_NEWWORLD_MACIO, | |
486 | .parent = TYPE_MACIO, | |
07a7484e AF |
487 | .instance_size = sizeof(NewWorldMacIOState), |
488 | .instance_init = macio_newworld_init, | |
d037834a AF |
489 | .class_init = macio_newworld_class_init, |
490 | }; | |
491 | ||
fcf1bbab AF |
492 | static const TypeInfo macio_type_info = { |
493 | .name = TYPE_MACIO, | |
39bffca2 AL |
494 | .parent = TYPE_PCI_DEVICE, |
495 | .instance_size = sizeof(MacIOState), | |
fcf1bbab | 496 | .instance_init = macio_instance_init, |
d037834a | 497 | .abstract = true, |
39bffca2 | 498 | .class_init = macio_class_init, |
fd3b02c8 EH |
499 | .interfaces = (InterfaceInfo[]) { |
500 | { INTERFACE_CONVENTIONAL_PCI_DEVICE }, | |
501 | { }, | |
502 | }, | |
d8c51b05 AL |
503 | }; |
504 | ||
83f7d43a | 505 | static void macio_register_types(void) |
d8c51b05 | 506 | { |
bf31c56f | 507 | type_register_static(&macio_bus_info); |
fcf1bbab | 508 | type_register_static(&macio_type_info); |
d037834a AF |
509 | type_register_static(&macio_oldworld_type_info); |
510 | type_register_static(&macio_newworld_type_info); | |
d8c51b05 AL |
511 | } |
512 | ||
83f7d43a | 513 | type_init(macio_register_types) |