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