1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include "qemu/osdep.h"
24#include "qemu/units.h"
25#include "qemu/datadir.h"
26#include "sysemu/sysemu.h"
27#include "cpu.h"
28#include "hw/boards.h"
29#include "hw/or-irq.h"
30#include "hw/nmi.h"
31#include "elf.h"
32#include "hw/loader.h"
33#include "ui/console.h"
34#include "hw/char/escc.h"
35#include "hw/sysbus.h"
36#include "hw/scsi/esp.h"
37#include "standard-headers/asm-m68k/bootinfo.h"
38#include "standard-headers/asm-m68k/bootinfo-mac.h"
39#include "bootinfo.h"
40#include "hw/misc/mac_via.h"
41#include "hw/input/adb.h"
42#include "hw/nubus/mac-nubus-bridge.h"
43#include "hw/display/macfb.h"
44#include "hw/block/swim.h"
45#include "net/net.h"
46#include "qapi/error.h"
47#include "sysemu/qtest.h"
48#include "sysemu/runstate.h"
49#include "sysemu/reset.h"
50#include "migration/vmstate.h"
51
52#define MACROM_ADDR 0x40800000
53#define MACROM_SIZE 0x00100000
54
55#define MACROM_FILENAME "MacROM.bin"
56
57#define IO_BASE 0x50000000
58#define IO_SLICE 0x00040000
59#define IO_SIZE 0x04000000
60
61#define VIA_BASE (IO_BASE + 0x00000)
62#define SONIC_PROM_BASE (IO_BASE + 0x08000)
63#define SONIC_BASE (IO_BASE + 0x0a000)
64#define SCC_BASE (IO_BASE + 0x0c020)
65#define ESP_BASE (IO_BASE + 0x10000)
66#define ESP_PDMA (IO_BASE + 0x10100)
67#define ASC_BASE (IO_BASE + 0x14000)
68#define SWIM_BASE (IO_BASE + 0x1E000)
69
70#define SONIC_PROM_SIZE 0x1000
71
72
73
74
75
76
77#define VIDEO_BASE 0xf9000000
78
79#define MAC_CLOCK 3686418
80
81
82
83
84
85#define Q800_NUBUS_SLOTS_AVAILABLE (BIT(0x9) | BIT(0xc) | BIT(0xd) | \
86 BIT(0xe))
87
88
89
90
91
92
93
94
95
96#define TYPE_GLUE "q800-glue"
97OBJECT_DECLARE_SIMPLE_TYPE(GLUEState, GLUE)
98
99struct GLUEState {
100 SysBusDevice parent_obj;
101 M68kCPU *cpu;
102 uint8_t ipr;
103 uint8_t auxmode;
104 qemu_irq irqs[1];
105 QEMUTimer *nmi_release;
106};
107
108#define GLUE_IRQ_IN_VIA1 0
109#define GLUE_IRQ_IN_VIA2 1
110#define GLUE_IRQ_IN_SONIC 2
111#define GLUE_IRQ_IN_ESCC 3
112#define GLUE_IRQ_IN_NMI 4
113
114#define GLUE_IRQ_NUBUS_9 0
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147static void GLUE_set_irq(void *opaque, int irq, int level)
148{
149 GLUEState *s = opaque;
150 int i;
151
152 if (s->auxmode) {
153
154 switch (irq) {
155 case GLUE_IRQ_IN_VIA1:
156 irq = 0;
157 break;
158
159 case GLUE_IRQ_IN_VIA2:
160 irq = 1;
161 break;
162
163 case GLUE_IRQ_IN_SONIC:
164
165 qemu_set_irq(s->irqs[GLUE_IRQ_NUBUS_9], level);
166 return;
167
168 case GLUE_IRQ_IN_ESCC:
169 irq = 3;
170 break;
171
172 case GLUE_IRQ_IN_NMI:
173 irq = 6;
174 break;
175
176 default:
177 g_assert_not_reached();
178 }
179 } else {
180
181 switch (irq) {
182 case GLUE_IRQ_IN_VIA1:
183 irq = 5;
184 break;
185
186 case GLUE_IRQ_IN_VIA2:
187 irq = 1;
188 break;
189
190 case GLUE_IRQ_IN_SONIC:
191 irq = 2;
192 break;
193
194 case GLUE_IRQ_IN_ESCC:
195 irq = 3;
196 break;
197
198 case GLUE_IRQ_IN_NMI:
199 irq = 6;
200 break;
201
202 default:
203 g_assert_not_reached();
204 }
205 }
206
207 if (level) {
208 s->ipr |= 1 << irq;
209 } else {
210 s->ipr &= ~(1 << irq);
211 }
212
213 for (i = 7; i >= 0; i--) {
214 if ((s->ipr >> i) & 1) {
215 m68k_set_irq_level(s->cpu, i + 1, i + 25);
216 return;
217 }
218 }
219 m68k_set_irq_level(s->cpu, 0, 0);
220}
221
222static void glue_auxmode_set_irq(void *opaque, int irq, int level)
223{
224 GLUEState *s = GLUE(opaque);
225
226 s->auxmode = level;
227}
228
229static void glue_nmi(NMIState *n, int cpu_index, Error **errp)
230{
231 GLUEState *s = GLUE(n);
232
233
234 GLUE_set_irq(s, GLUE_IRQ_IN_NMI, 1);
235 timer_mod(s->nmi_release, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 100);
236}
237
238static void glue_nmi_release(void *opaque)
239{
240 GLUEState *s = GLUE(opaque);
241
242 GLUE_set_irq(s, GLUE_IRQ_IN_NMI, 0);
243}
244
245static void glue_reset(DeviceState *dev)
246{
247 GLUEState *s = GLUE(dev);
248
249 s->ipr = 0;
250 s->auxmode = 0;
251
252 timer_del(s->nmi_release);
253}
254
255static const VMStateDescription vmstate_glue = {
256 .name = "q800-glue",
257 .version_id = 0,
258 .minimum_version_id = 0,
259 .fields = (VMStateField[]) {
260 VMSTATE_UINT8(ipr, GLUEState),
261 VMSTATE_UINT8(auxmode, GLUEState),
262 VMSTATE_TIMER_PTR(nmi_release, GLUEState),
263 VMSTATE_END_OF_LIST(),
264 },
265};
266
267
268
269
270
271
272
273static Property glue_properties[] = {
274 DEFINE_PROP_LINK("cpu", GLUEState, cpu, TYPE_M68K_CPU, M68kCPU *),
275 DEFINE_PROP_END_OF_LIST(),
276};
277
278static void glue_finalize(Object *obj)
279{
280 GLUEState *s = GLUE(obj);
281
282 timer_free(s->nmi_release);
283}
284
285static void glue_init(Object *obj)
286{
287 DeviceState *dev = DEVICE(obj);
288 GLUEState *s = GLUE(dev);
289
290 qdev_init_gpio_in(dev, GLUE_set_irq, 8);
291 qdev_init_gpio_in_named(dev, glue_auxmode_set_irq, "auxmode", 1);
292
293 qdev_init_gpio_out(dev, s->irqs, 1);
294
295
296 s->nmi_release = timer_new_ms(QEMU_CLOCK_VIRTUAL, glue_nmi_release, s);
297}
298
299static void glue_class_init(ObjectClass *klass, void *data)
300{
301 DeviceClass *dc = DEVICE_CLASS(klass);
302 NMIClass *nc = NMI_CLASS(klass);
303
304 dc->vmsd = &vmstate_glue;
305 dc->reset = glue_reset;
306 device_class_set_props(dc, glue_properties);
307 nc->nmi_monitor_handler = glue_nmi;
308}
309
310static const TypeInfo glue_info = {
311 .name = TYPE_GLUE,
312 .parent = TYPE_SYS_BUS_DEVICE,
313 .instance_size = sizeof(GLUEState),
314 .instance_init = glue_init,
315 .instance_finalize = glue_finalize,
316 .class_init = glue_class_init,
317 .interfaces = (InterfaceInfo[]) {
318 { TYPE_NMI },
319 { }
320 },
321};
322
323static void main_cpu_reset(void *opaque)
324{
325 M68kCPU *cpu = opaque;
326 CPUState *cs = CPU(cpu);
327
328 cpu_reset(cs);
329 cpu->env.aregs[7] = ldl_phys(cs->as, 0);
330 cpu->env.pc = ldl_phys(cs->as, 4);
331}
332
333static uint8_t fake_mac_rom[] = {
334 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
335
336
337
338
339 0x20, 0x7C, 0x50, 0xF0, 0x24, 0x00,
340 0x10, 0x10,
341 0x00, 0x00, 0x00, 0x04,
342 0x10, 0x80,
343
344
345 0x20, 0x7C, 0x50, 0xF0, 0x20, 0x00,
346 0x10, 0x10,
347 0x02, 0x00, 0xFF, 0xFB,
348 0x10, 0x80,
349
350
351 0x60, 0xFE
352};
353
354static void q800_init(MachineState *machine)
355{
356 M68kCPU *cpu = NULL;
357 int linux_boot;
358 int32_t kernel_size;
359 uint64_t elf_entry;
360 char *filename;
361 int bios_size;
362 ram_addr_t initrd_base;
363 int32_t initrd_size;
364 MemoryRegion *rom;
365 MemoryRegion *io;
366 MemoryRegion *dp8393x_prom = g_new(MemoryRegion, 1);
367 uint8_t *prom;
368 const int io_slice_nb = (IO_SIZE / IO_SLICE) - 1;
369 int i, checksum;
370 MacFbMode *macfb_mode;
371 ram_addr_t ram_size = machine->ram_size;
372 const char *kernel_filename = machine->kernel_filename;
373 const char *initrd_filename = machine->initrd_filename;
374 const char *kernel_cmdline = machine->kernel_cmdline;
375 const char *bios_name = machine->firmware ?: MACROM_FILENAME;
376 hwaddr parameters_base;
377 CPUState *cs;
378 DeviceState *dev;
379 DeviceState *via1_dev, *via2_dev;
380 DeviceState *escc_orgate;
381 SysBusESPState *sysbus_esp;
382 ESPState *esp;
383 SysBusDevice *sysbus;
384 BusState *adb_bus;
385 NubusBus *nubus;
386 DeviceState *glue;
387 DriveInfo *dinfo;
388
389 linux_boot = (kernel_filename != NULL);
390
391 if (ram_size > 1 * GiB) {
392 error_report("Too much memory for this machine: %" PRId64 " MiB, "
393 "maximum 1024 MiB", ram_size / MiB);
394 exit(1);
395 }
396
397
398 cpu = M68K_CPU(cpu_create(machine->cpu_type));
399 qemu_register_reset(main_cpu_reset, cpu);
400
401
402 memory_region_add_subregion(get_system_memory(), 0, machine->ram);
403
404
405
406
407
408 io = g_new(MemoryRegion, io_slice_nb);
409 for (i = 0; i < io_slice_nb; i++) {
410 char *name = g_strdup_printf("mac_m68k.io[%d]", i + 1);
411
412 memory_region_init_alias(&io[i], NULL, name, get_system_memory(),
413 IO_BASE, IO_SLICE);
414 memory_region_add_subregion(get_system_memory(),
415 IO_BASE + (i + 1) * IO_SLICE, &io[i]);
416 g_free(name);
417 }
418
419
420 glue = qdev_new(TYPE_GLUE);
421 object_property_set_link(OBJECT(glue), "cpu", OBJECT(cpu), &error_abort);
422 sysbus_realize_and_unref(SYS_BUS_DEVICE(glue), &error_fatal);
423
424
425 via1_dev = qdev_new(TYPE_MOS6522_Q800_VIA1);
426 dinfo = drive_get(IF_MTD, 0, 0);
427 if (dinfo) {
428 qdev_prop_set_drive(via1_dev, "drive", blk_by_legacy_dinfo(dinfo));
429 }
430 sysbus = SYS_BUS_DEVICE(via1_dev);
431 sysbus_realize_and_unref(sysbus, &error_fatal);
432 sysbus_mmio_map(sysbus, 1, VIA_BASE);
433 sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(glue, GLUE_IRQ_IN_VIA1));
434
435 qdev_connect_gpio_out(via1_dev, 0,
436 qdev_get_gpio_in_named(glue, "auxmode", 0));
437
438 adb_bus = qdev_get_child_bus(via1_dev, "adb.0");
439 dev = qdev_new(TYPE_ADB_KEYBOARD);
440 qdev_realize_and_unref(dev, adb_bus, &error_fatal);
441 dev = qdev_new(TYPE_ADB_MOUSE);
442 qdev_realize_and_unref(dev, adb_bus, &error_fatal);
443
444
445 via2_dev = qdev_new(TYPE_MOS6522_Q800_VIA2);
446 sysbus = SYS_BUS_DEVICE(via2_dev);
447 sysbus_realize_and_unref(sysbus, &error_fatal);
448 sysbus_mmio_map(sysbus, 1, VIA_BASE + VIA_SIZE);
449 sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(glue, GLUE_IRQ_IN_VIA2));
450
451
452
453 if (nb_nics > 1) {
454 error_report("q800 can only have one ethernet interface");
455 exit(1);
456 }
457
458 qemu_check_nic_model(&nd_table[0], "dp83932");
459
460
461
462
463
464
465
466
467
468
469 nd_table[0].macaddr.a[0] = 0x08;
470 nd_table[0].macaddr.a[1] = 0x00;
471 nd_table[0].macaddr.a[2] = 0x07;
472
473 dev = qdev_new("dp8393x");
474 qdev_set_nic_properties(dev, &nd_table[0]);
475 qdev_prop_set_uint8(dev, "it_shift", 2);
476 qdev_prop_set_bit(dev, "big_endian", true);
477 object_property_set_link(OBJECT(dev), "dma_mr",
478 OBJECT(get_system_memory()), &error_abort);
479 sysbus = SYS_BUS_DEVICE(dev);
480 sysbus_realize_and_unref(sysbus, &error_fatal);
481 sysbus_mmio_map(sysbus, 0, SONIC_BASE);
482 sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(glue, GLUE_IRQ_IN_SONIC));
483
484 memory_region_init_rom(dp8393x_prom, NULL, "dp8393x-q800.prom",
485 SONIC_PROM_SIZE, &error_fatal);
486 memory_region_add_subregion(get_system_memory(), SONIC_PROM_BASE,
487 dp8393x_prom);
488
489
490 prom = memory_region_get_ram_ptr(dp8393x_prom);
491 checksum = 0;
492 for (i = 0; i < 6; i++) {
493 prom[i] = revbit8(nd_table[0].macaddr.a[i]);
494 checksum ^= prom[i];
495 }
496 prom[7] = 0xff - checksum;
497
498
499
500 dev = qdev_new(TYPE_ESCC);
501 qdev_prop_set_uint32(dev, "disabled", 0);
502 qdev_prop_set_uint32(dev, "frequency", MAC_CLOCK);
503 qdev_prop_set_uint32(dev, "it_shift", 1);
504 qdev_prop_set_bit(dev, "bit_swap", true);
505 qdev_prop_set_chr(dev, "chrA", serial_hd(0));
506 qdev_prop_set_chr(dev, "chrB", serial_hd(1));
507 qdev_prop_set_uint32(dev, "chnBtype", 0);
508 qdev_prop_set_uint32(dev, "chnAtype", 0);
509 sysbus = SYS_BUS_DEVICE(dev);
510 sysbus_realize_and_unref(sysbus, &error_fatal);
511
512
513 escc_orgate = DEVICE(object_new(TYPE_OR_IRQ));
514 object_property_set_int(OBJECT(escc_orgate), "num-lines", 2, &error_fatal);
515 qdev_realize_and_unref(escc_orgate, NULL, &error_fatal);
516 sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(escc_orgate, 0));
517 sysbus_connect_irq(sysbus, 1, qdev_get_gpio_in(escc_orgate, 1));
518 qdev_connect_gpio_out(DEVICE(escc_orgate), 0,
519 qdev_get_gpio_in(glue, GLUE_IRQ_IN_ESCC));
520 sysbus_mmio_map(sysbus, 0, SCC_BASE);
521
522
523
524 dev = qdev_new(TYPE_SYSBUS_ESP);
525 sysbus_esp = SYSBUS_ESP(dev);
526 esp = &sysbus_esp->esp;
527 esp->dma_memory_read = NULL;
528 esp->dma_memory_write = NULL;
529 esp->dma_opaque = NULL;
530 sysbus_esp->it_shift = 4;
531 esp->dma_enabled = 1;
532
533 sysbus = SYS_BUS_DEVICE(dev);
534 sysbus_realize_and_unref(sysbus, &error_fatal);
535
536 sysbus_connect_irq(sysbus, 0, qemu_irq_invert(qdev_get_gpio_in(via2_dev,
537 VIA2_IRQ_SCSI_BIT)));
538 sysbus_connect_irq(sysbus, 1, qemu_irq_invert(qdev_get_gpio_in(via2_dev,
539 VIA2_IRQ_SCSI_DATA_BIT)));
540 sysbus_mmio_map(sysbus, 0, ESP_BASE);
541 sysbus_mmio_map(sysbus, 1, ESP_PDMA);
542
543 scsi_bus_legacy_handle_cmdline(&esp->bus);
544
545
546
547 dev = qdev_new(TYPE_SWIM);
548 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
549 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, SWIM_BASE);
550
551
552
553 dev = qdev_new(TYPE_MAC_NUBUS_BRIDGE);
554 qdev_prop_set_uint32(dev, "slot-available-mask",
555 Q800_NUBUS_SLOTS_AVAILABLE);
556 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
557 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0,
558 MAC_NUBUS_FIRST_SLOT * NUBUS_SUPER_SLOT_SIZE);
559 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, NUBUS_SLOT_BASE +
560 MAC_NUBUS_FIRST_SLOT * NUBUS_SLOT_SIZE);
561 qdev_connect_gpio_out(dev, 9,
562 qdev_get_gpio_in_named(via2_dev, "nubus-irq",
563 VIA2_NUBUS_IRQ_INTVIDEO));
564 for (i = 1; i < VIA2_NUBUS_IRQ_NB; i++) {
565 qdev_connect_gpio_out(dev, 9 + i,
566 qdev_get_gpio_in_named(via2_dev, "nubus-irq",
567 VIA2_NUBUS_IRQ_9 + i));
568 }
569
570
571
572
573
574 qdev_connect_gpio_out(glue, GLUE_IRQ_NUBUS_9,
575 qdev_get_gpio_in_named(via2_dev, "nubus-irq",
576 VIA2_NUBUS_IRQ_9));
577
578 nubus = &NUBUS_BRIDGE(dev)->bus;
579
580
581
582 dev = qdev_new(TYPE_NUBUS_MACFB);
583 qdev_prop_set_uint32(dev, "slot", 9);
584 qdev_prop_set_uint32(dev, "width", graphic_width);
585 qdev_prop_set_uint32(dev, "height", graphic_height);
586 qdev_prop_set_uint8(dev, "depth", graphic_depth);
587 if (graphic_width == 1152 && graphic_height == 870) {
588 qdev_prop_set_uint8(dev, "display", MACFB_DISPLAY_APPLE_21_COLOR);
589 } else {
590 qdev_prop_set_uint8(dev, "display", MACFB_DISPLAY_VGA);
591 }
592 qdev_realize_and_unref(dev, BUS(nubus), &error_fatal);
593
594 macfb_mode = (NUBUS_MACFB(dev)->macfb).mode;
595
596 cs = CPU(cpu);
597 if (linux_boot) {
598 uint64_t high;
599 kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
600 &elf_entry, NULL, &high, NULL, 1,
601 EM_68K, 0, 0);
602 if (kernel_size < 0) {
603 error_report("could not load kernel '%s'", kernel_filename);
604 exit(1);
605 }
606 stl_phys(cs->as, 4, elf_entry);
607 parameters_base = (high + 1) & ~1;
608
609 BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_MAC);
610 BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040);
611 BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040);
612 BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040);
613 BOOTINFO1(cs->as, parameters_base, BI_MAC_CPUID, CPUB_68040);
614 BOOTINFO1(cs->as, parameters_base, BI_MAC_MODEL, MAC_MODEL_Q800);
615 BOOTINFO1(cs->as, parameters_base,
616 BI_MAC_MEMSIZE, ram_size >> 20);
617 BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size);
618 BOOTINFO1(cs->as, parameters_base, BI_MAC_VADDR,
619 VIDEO_BASE + macfb_mode->offset);
620 BOOTINFO1(cs->as, parameters_base, BI_MAC_VDEPTH, graphic_depth);
621 BOOTINFO1(cs->as, parameters_base, BI_MAC_VDIM,
622 (graphic_height << 16) | graphic_width);
623 BOOTINFO1(cs->as, parameters_base, BI_MAC_VROW, macfb_mode->stride);
624 BOOTINFO1(cs->as, parameters_base, BI_MAC_SCCBASE, SCC_BASE);
625
626 rom = g_malloc(sizeof(*rom));
627 memory_region_init_ram_ptr(rom, NULL, "m68k_fake_mac.rom",
628 sizeof(fake_mac_rom), fake_mac_rom);
629 memory_region_set_readonly(rom, true);
630 memory_region_add_subregion(get_system_memory(), MACROM_ADDR, rom);
631
632 if (kernel_cmdline) {
633 BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE,
634 kernel_cmdline);
635 }
636
637
638 if (initrd_filename) {
639 initrd_size = get_image_size(initrd_filename);
640 if (initrd_size < 0) {
641 error_report("could not load initial ram disk '%s'",
642 initrd_filename);
643 exit(1);
644 }
645
646 initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
647 load_image_targphys(initrd_filename, initrd_base,
648 ram_size - initrd_base);
649 BOOTINFO2(cs->as, parameters_base, BI_RAMDISK, initrd_base,
650 initrd_size);
651 } else {
652 initrd_base = 0;
653 initrd_size = 0;
654 }
655 BOOTINFO0(cs->as, parameters_base, BI_LAST);
656 } else {
657 uint8_t *ptr;
658
659 rom = g_malloc(sizeof(*rom));
660 memory_region_init_rom(rom, NULL, "m68k_mac.rom", MACROM_SIZE,
661 &error_abort);
662 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
663 memory_region_add_subregion(get_system_memory(), MACROM_ADDR, rom);
664
665
666 if (filename) {
667 bios_size = load_image_targphys(filename, MACROM_ADDR, MACROM_SIZE);
668 g_free(filename);
669 } else {
670 bios_size = -1;
671 }
672
673
674 if (!qtest_enabled()) {
675 if (bios_size <= 0 || bios_size > MACROM_SIZE) {
676 error_report("could not load MacROM '%s'", bios_name);
677 exit(1);
678 }
679
680 ptr = rom_ptr(MACROM_ADDR, bios_size);
681 assert(ptr != NULL);
682 stl_phys(cs->as, 0, ldl_p(ptr));
683 stl_phys(cs->as, 4,
684 MACROM_ADDR + ldl_p(ptr + 4));
685 }
686 }
687}
688
689static GlobalProperty hw_compat_q800[] = {
690 { "scsi-hd", "quirk_mode_page_vendor_specific_apple", "on"},
691 { "scsi-hd", "vendor", " SEAGATE" },
692 { "scsi-hd", "product", " ST225N" },
693 { "scsi-hd", "ver", "1.0 " },
694 { "scsi-cd", "quirk_mode_page_apple_vendor", "on"},
695 { "scsi-cd", "quirk_mode_sense_rom_use_dbd", "on"},
696 { "scsi-cd", "quirk_mode_page_vendor_specific_apple", "on"},
697 { "scsi-cd", "quirk_mode_page_truncated", "on"},
698 { "scsi-cd", "vendor", "MATSHITA" },
699 { "scsi-cd", "product", "CD-ROM CR-8005" },
700 { "scsi-cd", "ver", "1.0k" },
701};
702static const size_t hw_compat_q800_len = G_N_ELEMENTS(hw_compat_q800);
703
704static void q800_machine_class_init(ObjectClass *oc, void *data)
705{
706 MachineClass *mc = MACHINE_CLASS(oc);
707 mc->desc = "Macintosh Quadra 800";
708 mc->init = q800_init;
709 mc->default_cpu_type = M68K_CPU_TYPE_NAME("m68040");
710 mc->max_cpus = 1;
711 mc->block_default_type = IF_SCSI;
712 mc->default_ram_id = "m68k_mac.ram";
713 compat_props_add(mc->compat_props, hw_compat_q800, hw_compat_q800_len);
714}
715
716static const TypeInfo q800_machine_typeinfo = {
717 .name = MACHINE_TYPE_NAME("q800"),
718 .parent = TYPE_MACHINE,
719 .class_init = q800_machine_class_init,
720};
721
722static void q800_machine_register_types(void)
723{
724 type_register_static(&q800_machine_typeinfo);
725 type_register_static(&glue_info);
726}
727
728type_init(q800_machine_register_types)
729