1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49#include "qemu/osdep.h"
50#include "qapi/error.h"
51#include "hw/hw.h"
52#include "hw/ppc/ppc.h"
53#include "hw/ppc/mac.h"
54#include "hw/input/adb.h"
55#include "hw/ppc/mac_dbdma.h"
56#include "hw/timer/m48t59.h"
57#include "hw/pci/pci.h"
58#include "net/net.h"
59#include "sysemu/sysemu.h"
60#include "hw/boards.h"
61#include "hw/nvram/fw_cfg.h"
62#include "hw/char/escc.h"
63#include "hw/ppc/openpic.h"
64#include "hw/ide.h"
65#include "hw/loader.h"
66#include "elf.h"
67#include "qemu/error-report.h"
68#include "sysemu/kvm.h"
69#include "kvm_ppc.h"
70#include "hw/usb.h"
71#include "sysemu/block-backend.h"
72#include "exec/address-spaces.h"
73#include "hw/sysbus.h"
74#include "qemu/cutils.h"
75#include "trace.h"
76
77#define MAX_IDE_BUS 2
78#define CFG_ADDR 0xf0000510
79#define TBFREQ (100UL * 1000UL * 1000UL)
80#define CLOCKFREQ (900UL * 1000UL * 1000UL)
81#define BUSFREQ (100UL * 1000UL * 1000UL)
82
83#define NDRV_VGA_FILENAME "qemu_vga.ndrv"
84
85
86static void unin_write(void *opaque, hwaddr addr, uint64_t value,
87 unsigned size)
88{
89 trace_mac99_uninorth_write(addr, value);
90 if (addr == 0x0) {
91 *(int*)opaque = value;
92 }
93}
94
95static uint64_t unin_read(void *opaque, hwaddr addr, unsigned size)
96{
97 uint32_t value;
98
99 value = 0;
100 switch (addr) {
101 case 0:
102 value = *(int*)opaque;
103 }
104
105 trace_mac99_uninorth_read(addr, value);
106
107 return value;
108}
109
110static const MemoryRegionOps unin_ops = {
111 .read = unin_read,
112 .write = unin_write,
113 .endianness = DEVICE_NATIVE_ENDIAN,
114};
115
116static void fw_cfg_boot_set(void *opaque, const char *boot_device,
117 Error **errp)
118{
119 fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
120}
121
122static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
123{
124 return (addr & 0x0fffffff) + KERNEL_LOAD_ADDR;
125}
126
127static void ppc_core99_reset(void *opaque)
128{
129 PowerPCCPU *cpu = opaque;
130
131 cpu_reset(CPU(cpu));
132
133 cpu->env.nip = PROM_ADDR + 0x100;
134}
135
136
137static void ppc_core99_init(MachineState *machine)
138{
139 ram_addr_t ram_size = machine->ram_size;
140 const char *kernel_filename = machine->kernel_filename;
141 const char *kernel_cmdline = machine->kernel_cmdline;
142 const char *initrd_filename = machine->initrd_filename;
143 const char *boot_device = machine->boot_order;
144 PowerPCCPU *cpu = NULL;
145 CPUPPCState *env = NULL;
146 char *filename;
147 qemu_irq *pic, **openpic_irqs;
148 MemoryRegion *isa = g_new(MemoryRegion, 1);
149 MemoryRegion *unin_memory = g_new(MemoryRegion, 1);
150 MemoryRegion *unin2_memory = g_new(MemoryRegion, 1);
151 int linux_boot, i, j, k;
152 MemoryRegion *ram = g_new(MemoryRegion, 1), *bios = g_new(MemoryRegion, 1);
153 hwaddr kernel_base, initrd_base, cmdline_base = 0;
154 long kernel_size, initrd_size;
155 PCIBus *pci_bus;
156 PCIDevice *macio;
157 MACIOIDEState *macio_ide;
158 BusState *adb_bus;
159 MacIONVRAMState *nvr;
160 int bios_size, ndrv_size;
161 uint8_t *ndrv_file;
162 MemoryRegion *pic_mem, *escc_mem;
163 MemoryRegion *escc_bar = g_new(MemoryRegion, 1);
164 int ppc_boot_device;
165 DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
166 void *fw_cfg;
167 int machine_arch;
168 SysBusDevice *s;
169 DeviceState *dev;
170 int *token = g_new(int, 1);
171 hwaddr nvram_addr = 0xFFF04000;
172 uint64_t tbfreq;
173
174 linux_boot = (kernel_filename != NULL);
175
176
177 for (i = 0; i < smp_cpus; i++) {
178 cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
179 env = &cpu->env;
180
181
182 cpu_ppc_tb_init(env, TBFREQ);
183 qemu_register_reset(ppc_core99_reset, cpu);
184 }
185
186
187 memory_region_allocate_system_memory(ram, NULL, "ppc_core99.ram", ram_size);
188 memory_region_add_subregion(get_system_memory(), 0, ram);
189
190
191 memory_region_init_ram(bios, NULL, "ppc_core99.bios", BIOS_SIZE,
192 &error_fatal);
193
194 if (bios_name == NULL)
195 bios_name = PROM_FILENAME;
196 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
197 memory_region_set_readonly(bios, true);
198 memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios);
199
200
201 if (filename) {
202 bios_size = load_elf(filename, NULL, NULL, NULL,
203 NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0);
204
205 g_free(filename);
206 } else {
207 bios_size = -1;
208 }
209 if (bios_size < 0 || bios_size > BIOS_SIZE) {
210 error_report("could not load PowerPC bios '%s'", bios_name);
211 exit(1);
212 }
213
214 if (linux_boot) {
215 uint64_t lowaddr = 0;
216 int bswap_needed;
217
218#ifdef BSWAP_NEEDED
219 bswap_needed = 1;
220#else
221 bswap_needed = 0;
222#endif
223 kernel_base = KERNEL_LOAD_ADDR;
224
225 kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
226 NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE,
227 0, 0);
228 if (kernel_size < 0)
229 kernel_size = load_aout(kernel_filename, kernel_base,
230 ram_size - kernel_base, bswap_needed,
231 TARGET_PAGE_SIZE);
232 if (kernel_size < 0)
233 kernel_size = load_image_targphys(kernel_filename,
234 kernel_base,
235 ram_size - kernel_base);
236 if (kernel_size < 0) {
237 error_report("could not load kernel '%s'", kernel_filename);
238 exit(1);
239 }
240
241 if (initrd_filename) {
242 initrd_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP);
243 initrd_size = load_image_targphys(initrd_filename, initrd_base,
244 ram_size - initrd_base);
245 if (initrd_size < 0) {
246 error_report("could not load initial ram disk '%s'",
247 initrd_filename);
248 exit(1);
249 }
250 cmdline_base = TARGET_PAGE_ALIGN(initrd_base + initrd_size);
251 } else {
252 initrd_base = 0;
253 initrd_size = 0;
254 cmdline_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP);
255 }
256 ppc_boot_device = 'm';
257 } else {
258 kernel_base = 0;
259 kernel_size = 0;
260 initrd_base = 0;
261 initrd_size = 0;
262 ppc_boot_device = '\0';
263
264
265
266 for (i = 0; boot_device[i] != '\0'; i++) {
267 if (boot_device[i] >= 'c' && boot_device[i] <= 'f') {
268 ppc_boot_device = boot_device[i];
269 break;
270 }
271 }
272 if (ppc_boot_device == '\0') {
273 fprintf(stderr, "No valid boot device for Mac99 machine\n");
274 exit(1);
275 }
276 }
277
278
279 memory_region_init_alias(isa, NULL, "isa_mmio",
280 get_system_io(), 0, 0x00800000);
281 memory_region_add_subregion(get_system_memory(), 0xf2000000, isa);
282
283
284 memory_region_init_io(unin_memory, NULL, &unin_ops, token, "unin", 0x1000);
285 memory_region_add_subregion(get_system_memory(), 0xf8000000, unin_memory);
286
287 memory_region_init_io(unin2_memory, NULL, &unin_ops, token, "unin", 0x1000);
288 memory_region_add_subregion(get_system_memory(), 0xf3000000, unin2_memory);
289
290 openpic_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
291 openpic_irqs[0] =
292 g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
293 for (i = 0; i < smp_cpus; i++) {
294
295
296
297 switch (PPC_INPUT(env)) {
298 case PPC_FLAGS_INPUT_6xx:
299 openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);
300 openpic_irqs[i][OPENPIC_OUTPUT_INT] =
301 ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
302 openpic_irqs[i][OPENPIC_OUTPUT_CINT] =
303 ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
304 openpic_irqs[i][OPENPIC_OUTPUT_MCK] =
305 ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_MCP];
306
307 openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;
308
309 openpic_irqs[i][OPENPIC_OUTPUT_RESET] =
310 ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_HRESET];
311 break;
312#if defined(TARGET_PPC64)
313 case PPC_FLAGS_INPUT_970:
314 openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);
315 openpic_irqs[i][OPENPIC_OUTPUT_INT] =
316 ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
317 openpic_irqs[i][OPENPIC_OUTPUT_CINT] =
318 ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
319 openpic_irqs[i][OPENPIC_OUTPUT_MCK] =
320 ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_MCP];
321
322 openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;
323
324 openpic_irqs[i][OPENPIC_OUTPUT_RESET] =
325 ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_HRESET];
326 break;
327#endif
328 default:
329 error_report("Bus model not supported on mac99 machine");
330 exit(1);
331 }
332 }
333
334 pic = g_new0(qemu_irq, 64);
335
336 dev = qdev_create(NULL, TYPE_OPENPIC);
337 qdev_prop_set_uint32(dev, "model", OPENPIC_MODEL_KEYLARGO);
338 qdev_init_nofail(dev);
339 s = SYS_BUS_DEVICE(dev);
340 pic_mem = s->mmio[0].memory;
341 k = 0;
342 for (i = 0; i < smp_cpus; i++) {
343 for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
344 sysbus_connect_irq(s, k++, openpic_irqs[i][j]);
345 }
346 }
347
348 for (i = 0; i < 64; i++) {
349 pic[i] = qdev_get_gpio_in(dev, i);
350 }
351
352 if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) {
353
354 pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io());
355 machine_arch = ARCH_MAC99_U3;
356 } else {
357 pci_bus = pci_pmac_init(pic, get_system_memory(), get_system_io());
358 machine_arch = ARCH_MAC99;
359 }
360 object_property_set_bool(OBJECT(pci_bus), true, "realized", &error_abort);
361
362 machine->usb |= defaults_enabled() && !machine->usb_disabled;
363
364
365 if (kvm_enabled()) {
366 tbfreq = kvmppc_get_tbfreq();
367 } else {
368 tbfreq = TBFREQ;
369 }
370
371
372 escc_mem = escc_init(0, pic[0x25], pic[0x24],
373 serial_hds[0], serial_hds[1], ESCC_CLOCK, 4);
374 memory_region_init_alias(escc_bar, NULL, "escc-bar",
375 escc_mem, 0, memory_region_size(escc_mem));
376
377 macio = pci_create(pci_bus, -1, TYPE_NEWWORLD_MACIO);
378 dev = DEVICE(macio);
379 qdev_connect_gpio_out(dev, 0, pic[0x19]);
380 qdev_connect_gpio_out(dev, 1, pic[0x0d]);
381 qdev_connect_gpio_out(dev, 2, pic[0x02]);
382 qdev_connect_gpio_out(dev, 3, pic[0x0e]);
383 qdev_connect_gpio_out(dev, 4, pic[0x03]);
384 qdev_prop_set_uint64(dev, "frequency", tbfreq);
385 macio_init(macio, pic_mem, escc_bar);
386
387
388 ide_drive_get(hd, ARRAY_SIZE(hd));
389
390 macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
391 "ide[0]"));
392 macio_ide_init_drives(macio_ide, hd);
393
394 macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
395 "ide[1]"));
396 macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]);
397
398 dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda"));
399 adb_bus = qdev_get_child_bus(dev, "adb.0");
400 dev = qdev_create(adb_bus, TYPE_ADB_KEYBOARD);
401 qdev_init_nofail(dev);
402 dev = qdev_create(adb_bus, TYPE_ADB_MOUSE);
403 qdev_init_nofail(dev);
404
405 if (machine->usb) {
406 pci_create_simple(pci_bus, -1, "pci-ohci");
407
408
409
410 if (machine_arch == ARCH_MAC99_U3) {
411 USBBus *usb_bus = usb_bus_find(-1);
412
413 usb_create_simple(usb_bus, "usb-kbd");
414 usb_create_simple(usb_bus, "usb-mouse");
415 }
416 }
417
418 pci_vga_init(pci_bus);
419
420 if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) {
421 graphic_depth = 15;
422 }
423
424 for (i = 0; i < nb_nics; i++) {
425 pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL);
426 }
427
428
429#ifdef CONFIG_KVM
430 if (kvm_enabled() && getpagesize() > 4096) {
431
432
433 nvram_addr = 0xFFE00000;
434 }
435#endif
436 dev = qdev_create(NULL, TYPE_MACIO_NVRAM);
437 qdev_prop_set_uint32(dev, "size", 0x2000);
438 qdev_prop_set_uint32(dev, "it_shift", 1);
439 qdev_init_nofail(dev);
440 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, nvram_addr);
441 nvr = MACIO_NVRAM(dev);
442 pmac_format_nvram_partition(nvr, 0x2000);
443
444
445 fw_cfg = fw_cfg_init_mem(CFG_ADDR, CFG_ADDR + 2);
446 fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
447 fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
448 fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
449 fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch);
450 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
451 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
452 if (kernel_cmdline) {
453 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base);
454 pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline);
455 } else {
456 fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
457 }
458 fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base);
459 fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
460 fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device);
461
462 fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width);
463 fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height);
464 fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth);
465
466 fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
467 if (kvm_enabled()) {
468#ifdef CONFIG_KVM
469 uint8_t *hypercall;
470
471 hypercall = g_malloc(16);
472 kvmppc_get_hypercall(env, hypercall, 16);
473 fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
474 fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
475#endif
476 }
477 fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, tbfreq);
478
479 fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_CLOCKFREQ, CLOCKFREQ);
480 fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_BUSFREQ, BUSFREQ);
481 fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_NVRAM_ADDR, nvram_addr);
482
483
484 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, NDRV_VGA_FILENAME);
485 if (filename) {
486 ndrv_size = get_image_size(filename);
487 if (ndrv_size != -1) {
488 ndrv_file = g_malloc(ndrv_size);
489 ndrv_size = load_image(filename, ndrv_file);
490
491 fw_cfg_add_file(fw_cfg, "ndrv/qemu_vga.ndrv", ndrv_file, ndrv_size);
492 }
493 g_free(filename);
494 }
495
496 qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
497}
498
499static int core99_kvm_type(const char *arg)
500{
501
502 return 2;
503}
504
505static void core99_machine_class_init(ObjectClass *oc, void *data)
506{
507 MachineClass *mc = MACHINE_CLASS(oc);
508
509 mc->desc = "Mac99 based PowerMAC";
510 mc->init = ppc_core99_init;
511 mc->block_default_type = IF_IDE;
512 mc->max_cpus = MAX_CPUS;
513 mc->default_boot_order = "cd";
514 mc->kvm_type = core99_kvm_type;
515#ifdef TARGET_PPC64
516 mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("970fx_v3.1");
517#else
518 mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("7400_v2.9");
519#endif
520}
521
522static const TypeInfo core99_machine_info = {
523 .name = MACHINE_TYPE_NAME("mac99"),
524 .parent = TYPE_MACHINE,
525 .class_init = core99_machine_class_init,
526};
527
528static void mac_machine_register_types(void)
529{
530 type_register_static(&core99_machine_info);
531}
532
533type_init(mac_machine_register_types)
534