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 "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 NUBUS_SUPER_SLOT_BASE 0x60000000
71#define NUBUS_SLOT_BASE 0xf0000000
72
73#define SONIC_PROM_SIZE 0x1000
74
75
76
77
78
79
80#define VIDEO_BASE 0xf9001000
81
82#define MAC_CLOCK 3686418
83
84
85
86
87
88
89
90
91
92#define TYPE_GLUE "q800-glue"
93OBJECT_DECLARE_SIMPLE_TYPE(GLUEState, GLUE)
94
95struct GLUEState {
96 SysBusDevice parent_obj;
97 M68kCPU *cpu;
98 uint8_t ipr;
99};
100
101static void GLUE_set_irq(void *opaque, int irq, int level)
102{
103 GLUEState *s = opaque;
104 int i;
105
106 if (level) {
107 s->ipr |= 1 << irq;
108 } else {
109 s->ipr &= ~(1 << irq);
110 }
111
112 for (i = 7; i >= 0; i--) {
113 if ((s->ipr >> i) & 1) {
114 m68k_set_irq_level(s->cpu, i + 1, i + 25);
115 return;
116 }
117 }
118 m68k_set_irq_level(s->cpu, 0, 0);
119}
120
121static void glue_reset(DeviceState *dev)
122{
123 GLUEState *s = GLUE(dev);
124
125 s->ipr = 0;
126}
127
128static const VMStateDescription vmstate_glue = {
129 .name = "q800-glue",
130 .version_id = 0,
131 .minimum_version_id = 0,
132 .fields = (VMStateField[]) {
133 VMSTATE_UINT8(ipr, GLUEState),
134 VMSTATE_END_OF_LIST(),
135 },
136};
137
138
139
140
141
142
143
144static Property glue_properties[] = {
145 DEFINE_PROP_LINK("cpu", GLUEState, cpu, TYPE_M68K_CPU, M68kCPU *),
146 DEFINE_PROP_END_OF_LIST(),
147};
148
149static void glue_init(Object *obj)
150{
151 DeviceState *dev = DEVICE(obj);
152
153 qdev_init_gpio_in(dev, GLUE_set_irq, 8);
154}
155
156static void glue_class_init(ObjectClass *klass, void *data)
157{
158 DeviceClass *dc = DEVICE_CLASS(klass);
159
160 dc->vmsd = &vmstate_glue;
161 dc->reset = glue_reset;
162 device_class_set_props(dc, glue_properties);
163}
164
165static const TypeInfo glue_info = {
166 .name = TYPE_GLUE,
167 .parent = TYPE_SYS_BUS_DEVICE,
168 .instance_size = sizeof(GLUEState),
169 .instance_init = glue_init,
170 .class_init = glue_class_init,
171};
172
173static void main_cpu_reset(void *opaque)
174{
175 M68kCPU *cpu = opaque;
176 CPUState *cs = CPU(cpu);
177
178 cpu_reset(cs);
179 cpu->env.aregs[7] = ldl_phys(cs->as, 0);
180 cpu->env.pc = ldl_phys(cs->as, 4);
181}
182
183static uint8_t fake_mac_rom[] = {
184 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
185
186
187
188
189 0x20, 0x7C, 0x50, 0xF0, 0x24, 0x00,
190 0x10, 0x10,
191 0x00, 0x00, 0x00, 0x04,
192 0x10, 0x80,
193
194
195 0x20, 0x7C, 0x50, 0xF0, 0x20, 0x00,
196 0x10, 0x10,
197 0x02, 0x00, 0xFF, 0xFB,
198 0x10, 0x80,
199
200
201 0x60, 0xFE
202};
203
204static void q800_init(MachineState *machine)
205{
206 M68kCPU *cpu = NULL;
207 int linux_boot;
208 int32_t kernel_size;
209 uint64_t elf_entry;
210 char *filename;
211 int bios_size;
212 ram_addr_t initrd_base;
213 int32_t initrd_size;
214 MemoryRegion *rom;
215 MemoryRegion *io;
216 MemoryRegion *dp8393x_prom = g_new(MemoryRegion, 1);
217 uint8_t *prom;
218 const int io_slice_nb = (IO_SIZE / IO_SLICE) - 1;
219 int i, checksum;
220 ram_addr_t ram_size = machine->ram_size;
221 const char *kernel_filename = machine->kernel_filename;
222 const char *initrd_filename = machine->initrd_filename;
223 const char *kernel_cmdline = machine->kernel_cmdline;
224 const char *bios_name = machine->firmware ?: MACROM_FILENAME;
225 hwaddr parameters_base;
226 CPUState *cs;
227 DeviceState *dev;
228 DeviceState *via_dev;
229 DeviceState *escc_orgate;
230 SysBusESPState *sysbus_esp;
231 ESPState *esp;
232 SysBusDevice *sysbus;
233 BusState *adb_bus;
234 NubusBus *nubus;
235 DeviceState *glue;
236 DriveInfo *dinfo;
237
238 linux_boot = (kernel_filename != NULL);
239
240 if (ram_size > 1 * GiB) {
241 error_report("Too much memory for this machine: %" PRId64 " MiB, "
242 "maximum 1024 MiB", ram_size / MiB);
243 exit(1);
244 }
245
246
247 cpu = M68K_CPU(cpu_create(machine->cpu_type));
248 qemu_register_reset(main_cpu_reset, cpu);
249
250
251 memory_region_add_subregion(get_system_memory(), 0, machine->ram);
252
253
254
255
256
257 io = g_new(MemoryRegion, io_slice_nb);
258 for (i = 0; i < io_slice_nb; i++) {
259 char *name = g_strdup_printf("mac_m68k.io[%d]", i + 1);
260
261 memory_region_init_alias(&io[i], NULL, name, get_system_memory(),
262 IO_BASE, IO_SLICE);
263 memory_region_add_subregion(get_system_memory(),
264 IO_BASE + (i + 1) * IO_SLICE, &io[i]);
265 g_free(name);
266 }
267
268
269 glue = qdev_new(TYPE_GLUE);
270 object_property_set_link(OBJECT(glue), "cpu", OBJECT(cpu), &error_abort);
271 sysbus_realize_and_unref(SYS_BUS_DEVICE(glue), &error_fatal);
272
273
274
275 via_dev = qdev_new(TYPE_MAC_VIA);
276 dinfo = drive_get(IF_MTD, 0, 0);
277 if (dinfo) {
278 qdev_prop_set_drive(via_dev, "drive", blk_by_legacy_dinfo(dinfo));
279 }
280 sysbus = SYS_BUS_DEVICE(via_dev);
281 sysbus_realize_and_unref(sysbus, &error_fatal);
282 sysbus_mmio_map(sysbus, 0, VIA_BASE);
283 qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 0,
284 qdev_get_gpio_in(glue, 0));
285 qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 1,
286 qdev_get_gpio_in(glue, 1));
287
288
289 adb_bus = qdev_get_child_bus(via_dev, "adb.0");
290 dev = qdev_new(TYPE_ADB_KEYBOARD);
291 qdev_realize_and_unref(dev, adb_bus, &error_fatal);
292 dev = qdev_new(TYPE_ADB_MOUSE);
293 qdev_realize_and_unref(dev, adb_bus, &error_fatal);
294
295
296
297 if (nb_nics > 1) {
298 error_report("q800 can only have one ethernet interface");
299 exit(1);
300 }
301
302 qemu_check_nic_model(&nd_table[0], "dp83932");
303
304
305
306
307
308
309
310
311
312
313 nd_table[0].macaddr.a[0] = 0x08;
314 nd_table[0].macaddr.a[1] = 0x00;
315 nd_table[0].macaddr.a[2] = 0x07;
316
317 dev = qdev_new("dp8393x");
318 qdev_set_nic_properties(dev, &nd_table[0]);
319 qdev_prop_set_uint8(dev, "it_shift", 2);
320 qdev_prop_set_bit(dev, "big_endian", true);
321 object_property_set_link(OBJECT(dev), "dma_mr",
322 OBJECT(get_system_memory()), &error_abort);
323 sysbus = SYS_BUS_DEVICE(dev);
324 sysbus_realize_and_unref(sysbus, &error_fatal);
325 sysbus_mmio_map(sysbus, 0, SONIC_BASE);
326 sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(glue, 2));
327
328 memory_region_init_rom(dp8393x_prom, NULL, "dp8393x-q800.prom",
329 SONIC_PROM_SIZE, &error_fatal);
330 memory_region_add_subregion(get_system_memory(), SONIC_PROM_BASE,
331 dp8393x_prom);
332
333
334 prom = memory_region_get_ram_ptr(dp8393x_prom);
335 checksum = 0;
336 for (i = 0; i < 6; i++) {
337 prom[i] = revbit8(nd_table[0].macaddr.a[i]);
338 checksum ^= prom[i];
339 }
340 prom[7] = 0xff - checksum;
341
342
343
344 dev = qdev_new(TYPE_ESCC);
345 qdev_prop_set_uint32(dev, "disabled", 0);
346 qdev_prop_set_uint32(dev, "frequency", MAC_CLOCK);
347 qdev_prop_set_uint32(dev, "it_shift", 1);
348 qdev_prop_set_bit(dev, "bit_swap", true);
349 qdev_prop_set_chr(dev, "chrA", serial_hd(0));
350 qdev_prop_set_chr(dev, "chrB", serial_hd(1));
351 qdev_prop_set_uint32(dev, "chnBtype", 0);
352 qdev_prop_set_uint32(dev, "chnAtype", 0);
353 sysbus = SYS_BUS_DEVICE(dev);
354 sysbus_realize_and_unref(sysbus, &error_fatal);
355
356
357 escc_orgate = DEVICE(object_new(TYPE_OR_IRQ));
358 object_property_set_int(OBJECT(escc_orgate), "num-lines", 2, &error_fatal);
359 qdev_realize_and_unref(escc_orgate, NULL, &error_fatal);
360 sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(escc_orgate, 0));
361 sysbus_connect_irq(sysbus, 1, qdev_get_gpio_in(escc_orgate, 1));
362 qdev_connect_gpio_out(DEVICE(escc_orgate), 0, qdev_get_gpio_in(glue, 3));
363 sysbus_mmio_map(sysbus, 0, SCC_BASE);
364
365
366
367 dev = qdev_new(TYPE_SYSBUS_ESP);
368 sysbus_esp = SYSBUS_ESP(dev);
369 esp = &sysbus_esp->esp;
370 esp->dma_memory_read = NULL;
371 esp->dma_memory_write = NULL;
372 esp->dma_opaque = NULL;
373 sysbus_esp->it_shift = 4;
374 esp->dma_enabled = 1;
375
376 sysbus = SYS_BUS_DEVICE(dev);
377 sysbus_realize_and_unref(sysbus, &error_fatal);
378 sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in_named(via_dev,
379 "via2-irq",
380 VIA2_IRQ_SCSI_BIT));
381 sysbus_connect_irq(sysbus, 1,
382 qdev_get_gpio_in_named(via_dev, "via2-irq",
383 VIA2_IRQ_SCSI_DATA_BIT));
384 sysbus_mmio_map(sysbus, 0, ESP_BASE);
385 sysbus_mmio_map(sysbus, 1, ESP_PDMA);
386
387 scsi_bus_legacy_handle_cmdline(&esp->bus);
388
389
390
391 dev = qdev_new(TYPE_SWIM);
392 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
393 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, SWIM_BASE);
394
395
396
397 dev = qdev_new(TYPE_MAC_NUBUS_BRIDGE);
398 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
399 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, NUBUS_SUPER_SLOT_BASE);
400 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, NUBUS_SLOT_BASE);
401
402 nubus = MAC_NUBUS_BRIDGE(dev)->bus;
403
404
405
406 dev = qdev_new(TYPE_NUBUS_MACFB);
407 qdev_prop_set_uint32(dev, "width", graphic_width);
408 qdev_prop_set_uint32(dev, "height", graphic_height);
409 qdev_prop_set_uint8(dev, "depth", graphic_depth);
410 qdev_realize_and_unref(dev, BUS(nubus), &error_fatal);
411
412 cs = CPU(cpu);
413 if (linux_boot) {
414 uint64_t high;
415 kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
416 &elf_entry, NULL, &high, NULL, 1,
417 EM_68K, 0, 0);
418 if (kernel_size < 0) {
419 error_report("could not load kernel '%s'", kernel_filename);
420 exit(1);
421 }
422 stl_phys(cs->as, 4, elf_entry);
423 parameters_base = (high + 1) & ~1;
424
425 BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_MAC);
426 BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040);
427 BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040);
428 BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040);
429 BOOTINFO1(cs->as, parameters_base, BI_MAC_CPUID, CPUB_68040);
430 BOOTINFO1(cs->as, parameters_base, BI_MAC_MODEL, MAC_MODEL_Q800);
431 BOOTINFO1(cs->as, parameters_base,
432 BI_MAC_MEMSIZE, ram_size >> 20);
433 BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size);
434 BOOTINFO1(cs->as, parameters_base, BI_MAC_VADDR, VIDEO_BASE);
435 BOOTINFO1(cs->as, parameters_base, BI_MAC_VDEPTH, graphic_depth);
436 BOOTINFO1(cs->as, parameters_base, BI_MAC_VDIM,
437 (graphic_height << 16) | graphic_width);
438 BOOTINFO1(cs->as, parameters_base, BI_MAC_VROW,
439 (graphic_width * graphic_depth + 7) / 8);
440 BOOTINFO1(cs->as, parameters_base, BI_MAC_SCCBASE, SCC_BASE);
441
442 rom = g_malloc(sizeof(*rom));
443 memory_region_init_ram_ptr(rom, NULL, "m68k_fake_mac.rom",
444 sizeof(fake_mac_rom), fake_mac_rom);
445 memory_region_set_readonly(rom, true);
446 memory_region_add_subregion(get_system_memory(), MACROM_ADDR, rom);
447
448 if (kernel_cmdline) {
449 BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE,
450 kernel_cmdline);
451 }
452
453
454 if (initrd_filename) {
455 initrd_size = get_image_size(initrd_filename);
456 if (initrd_size < 0) {
457 error_report("could not load initial ram disk '%s'",
458 initrd_filename);
459 exit(1);
460 }
461
462 initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
463 load_image_targphys(initrd_filename, initrd_base,
464 ram_size - initrd_base);
465 BOOTINFO2(cs->as, parameters_base, BI_RAMDISK, initrd_base,
466 initrd_size);
467 } else {
468 initrd_base = 0;
469 initrd_size = 0;
470 }
471 BOOTINFO0(cs->as, parameters_base, BI_LAST);
472 } else {
473 uint8_t *ptr;
474
475 rom = g_malloc(sizeof(*rom));
476 memory_region_init_rom(rom, NULL, "m68k_mac.rom", MACROM_SIZE,
477 &error_abort);
478 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
479 memory_region_add_subregion(get_system_memory(), MACROM_ADDR, rom);
480
481
482 if (filename) {
483 bios_size = load_image_targphys(filename, MACROM_ADDR, MACROM_SIZE);
484 g_free(filename);
485 } else {
486 bios_size = -1;
487 }
488
489
490 if (!qtest_enabled()) {
491 if (bios_size < 0 || bios_size > MACROM_SIZE) {
492 error_report("could not load MacROM '%s'", bios_name);
493 exit(1);
494 }
495
496 ptr = rom_ptr(MACROM_ADDR, MACROM_SIZE);
497 stl_phys(cs->as, 0, ldl_p(ptr));
498 stl_phys(cs->as, 4,
499 MACROM_ADDR + ldl_p(ptr + 4));
500 }
501 }
502}
503
504static void q800_machine_class_init(ObjectClass *oc, void *data)
505{
506 MachineClass *mc = MACHINE_CLASS(oc);
507 mc->desc = "Macintosh Quadra 800";
508 mc->init = q800_init;
509 mc->default_cpu_type = M68K_CPU_TYPE_NAME("m68040");
510 mc->max_cpus = 1;
511 mc->block_default_type = IF_SCSI;
512 mc->default_ram_id = "m68k_mac.ram";
513}
514
515static const TypeInfo q800_machine_typeinfo = {
516 .name = MACHINE_TYPE_NAME("q800"),
517 .parent = TYPE_MACHINE,
518 .class_init = q800_machine_class_init,
519};
520
521static void q800_machine_register_types(void)
522{
523 type_register_static(&q800_machine_typeinfo);
524 type_register_static(&glue_info);
525}
526
527type_init(q800_machine_register_types)
528