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