/* PowerPC PREP hardware initialisation */ static void ppc_prep_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; const char *cpu_model = machine->cpu_model; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; const char *boot_device = machine->boot_order; MemoryRegion *sysmem = get_system_memory(); PowerPCCPU *cpu = NULL; CPUPPCState *env = NULL; nvram_t nvram; M48t59State *m48t59; #if 0 MemoryRegion *xcsr = g_new(MemoryRegion, 1); #endif int linux_boot, i, nb_nics1; MemoryRegion *ram = g_new(MemoryRegion, 1); uint32_t kernel_base, initrd_base; long kernel_size, initrd_size; DeviceState *dev; PCIHostState *pcihost; PCIBus *pci_bus; PCIDevice *pci; ISABus *isa_bus; ISADevice *isa; qemu_irq *cpu_exit_irq; int ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; sysctrl = g_malloc0(sizeof(sysctrl_t)); linux_boot = (kernel_filename != NULL); /* init CPUs */ if (cpu_model == NULL) cpu_model = "602"; for (i = 0; i < smp_cpus; i++) { cpu = cpu_ppc_init(cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to find PowerPC CPU definition\n"); exit(1); } env = &cpu->env; if (env->flags & POWERPC_FLAG_RTC_CLK) { /* POWER / PowerPC 601 RTC clock frequency is 7.8125 MHz */ cpu_ppc_tb_init(env, 7812500UL); } else { /* Set time-base frequency to 100 Mhz */ cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL); } qemu_register_reset(ppc_prep_reset, cpu); } /* allocate RAM */ memory_region_allocate_system_memory(ram, NULL, "ppc_prep.ram", ram_size); memory_region_add_subregion(sysmem, 0, ram); if (linux_boot) { kernel_base = KERNEL_LOAD_ADDR; /* now we can load the kernel */ kernel_size = load_image_targphys(kernel_filename, kernel_base, ram_size - kernel_base); if (kernel_size < 0) { hw_error("qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } /* load initrd */ if (initrd_filename) { initrd_base = INITRD_LOAD_ADDR; initrd_size = load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); if (initrd_size < 0) { hw_error("qemu: could not load initial ram disk '%s'\n", initrd_filename); } } else { initrd_base = 0; initrd_size = 0; } ppc_boot_device = 'm'; } else { kernel_base = 0; kernel_size = 0; initrd_base = 0; initrd_size = 0; ppc_boot_device = '\0'; /* For now, OHW cannot boot from the network. */ for (i = 0; boot_device[i] != '\0'; i++) { if (boot_device[i] >= 'a' && boot_device[i] <= 'f') { ppc_boot_device = boot_device[i]; break; } } if (ppc_boot_device == '\0') { fprintf(stderr, "No valid boot device for Mac99 machine\n"); exit(1); } } if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) { hw_error("Only 6xx bus is supported on PREP machine\n"); } dev = qdev_create(NULL, "raven-pcihost"); if (bios_name == NULL) { bios_name = BIOS_FILENAME; } qdev_prop_set_string(dev, "bios-name", bios_name); qdev_prop_set_uint32(dev, "elf-machine", ELF_MACHINE); pcihost = PCI_HOST_BRIDGE(dev); object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev), NULL); qdev_init_nofail(dev); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0"); if (pci_bus == NULL) { fprintf(stderr, "Couldn't create PCI host controller.\n"); exit(1); } sysctrl->contiguous_map_irq = qdev_get_gpio_in(dev, 0); /* PCI -> ISA bridge */ pci = pci_create_simple(pci_bus, PCI_DEVFN(1, 0), "i82378"); cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); cpu = POWERPC_CPU(first_cpu); qdev_connect_gpio_out(&pci->qdev, 0, cpu->env.irq_inputs[PPC6xx_INPUT_INT]); qdev_connect_gpio_out(&pci->qdev, 1, *cpu_exit_irq); sysbus_connect_irq(&pcihost->busdev, 0, qdev_get_gpio_in(&pci->qdev, 9)); sysbus_connect_irq(&pcihost->busdev, 1, qdev_get_gpio_in(&pci->qdev, 11)); sysbus_connect_irq(&pcihost->busdev, 2, qdev_get_gpio_in(&pci->qdev, 9)); sysbus_connect_irq(&pcihost->busdev, 3, qdev_get_gpio_in(&pci->qdev, 11)); isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(pci), "isa.0")); /* Super I/O (parallel + serial ports) */ isa = isa_create(isa_bus, TYPE_PC87312); dev = DEVICE(isa); qdev_prop_set_uint8(dev, "config", 13); /* fdc, ser0, ser1, par0 */ qdev_init_nofail(dev); /* init basic PC hardware */ pci_vga_init(pci_bus); nb_nics1 = nb_nics; if (nb_nics1 > NE2000_NB_MAX) nb_nics1 = NE2000_NB_MAX; for(i = 0; i < nb_nics1; i++) { if (nd_table[i].model == NULL) { nd_table[i].model = g_strdup("ne2k_isa"); } if (strcmp(nd_table[i].model, "ne2k_isa") == 0) { isa_ne2000_init(isa_bus, ne2000_io[i], ne2000_irq[i], &nd_table[i]); } else { pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL); } } ide_drive_get(hd, ARRAY_SIZE(hd)); for(i = 0; i < MAX_IDE_BUS; i++) { isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i], hd[2 * i], hd[2 * i + 1]); } isa_create_simple(isa_bus, "i8042"); cpu = POWERPC_CPU(first_cpu); sysctrl->reset_irq = cpu->env.irq_inputs[PPC6xx_INPUT_HRESET]; portio_list_init(&prep_port_list, NULL, prep_portio_list, sysctrl, "prep"); portio_list_add(&prep_port_list, isa_address_space_io(isa), 0x0); /* PowerPC control and status register group */ #if 0 memory_region_init_io(xcsr, NULL, &PPC_XCSR_ops, NULL, "ppc-xcsr", 0x1000); memory_region_add_subregion(sysmem, 0xFEFF0000, xcsr); #endif if (usb_enabled(false)) { pci_create_simple(pci_bus, -1, "pci-ohci"); } m48t59 = m48t59_init_isa(isa_bus, 0x0074, NVRAM_SIZE, 59); if (m48t59 == NULL) return; sysctrl->nvram = m48t59; /* Initialise NVRAM */ nvram.opaque = m48t59; nvram.read_fn = &m48t59_read; nvram.write_fn = &m48t59_write; PPC_NVRAM_set_params(&nvram, NVRAM_SIZE, "PREP", ram_size, ppc_boot_device, kernel_base, kernel_size, kernel_cmdline, initrd_base, initrd_size, /* XXX: need an option to load a NVRAM image */ 0, graphic_width, graphic_height, graphic_depth); }
static void bamboo_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 }; PCIBus *pcibus; CPUState *env; uint64_t elf_entry; uint64_t elf_lowaddr; target_phys_addr_t entry = 0; target_phys_addr_t loadaddr = 0; target_long kernel_size = 0; target_ulong initrd_base = 0; target_long initrd_size = 0; target_ulong dt_base = 0; void *fdt; int i; /* Setup CPU. */ env = ppc440ep_init(&ram_size, &pcibus, pci_irq_nrs, 1, cpu_model); if (pcibus) { /* Register network interfaces. */ for (i = 0; i < nb_nics; i++) { /* There are no PCI NICs on the Bamboo board, but there are * PCI slots, so we can pick whatever default model we want. */ pci_nic_init_nofail(&nd_table[i], "e1000", NULL); } } /* Load kernel. */ if (kernel_filename) { kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL); if (kernel_size < 0) { kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_lowaddr, NULL, 1, ELF_MACHINE, 0); entry = elf_entry; loadaddr = elf_lowaddr; } /* XXX try again as binary */ if (kernel_size < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } } /* Load initrd. */ if (initrd_filename) { initrd_base = kernel_size + loadaddr; initrd_size = load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); if (initrd_size < 0) { fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", initrd_filename); exit(1); } } /* If we're loading a kernel directly, we must load the device tree too. */ if (kernel_filename) { if (initrd_base) dt_base = initrd_base + initrd_size; else dt_base = kernel_size + loadaddr; fdt = bamboo_load_device_tree(dt_base, ram_size, initrd_base, initrd_size, kernel_cmdline); if (fdt == NULL) { fprintf(stderr, "couldn't load device tree\n"); exit(1); } /* Set initial guest state. */ env->gpr[1] = (16<<20) - 8; env->gpr[3] = dt_base; env->nip = entry; /* XXX we currently depend on KVM to create some initial TLB entries. */ } if (kvm_enabled()) kvmppc_init(); }
/* PowerPC Mac99 hardware initialisation */ static void ppc_core99_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; const char *boot_device = machine->boot_order; Core99MachineState *core99_machine = CORE99_MACHINE(machine); PowerPCCPU *cpu = NULL; CPUPPCState *env = NULL; char *filename; IrqLines *openpic_irqs; int linux_boot, i, j, k; MemoryRegion *ram = g_new(MemoryRegion, 1), *bios = g_new(MemoryRegion, 1); hwaddr kernel_base, initrd_base, cmdline_base = 0; long kernel_size, initrd_size; UNINHostState *uninorth_pci; PCIBus *pci_bus; NewWorldMacIOState *macio; bool has_pmu, has_adb; MACIOIDEState *macio_ide; BusState *adb_bus; MacIONVRAMState *nvr; int bios_size; int ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; int machine_arch; SysBusDevice *s; DeviceState *dev, *pic_dev; hwaddr nvram_addr = 0xFFF04000; uint64_t tbfreq; linux_boot = (kernel_filename != NULL); /* init CPUs */ for (i = 0; i < smp_cpus; i++) { cpu = POWERPC_CPU(cpu_create(machine->cpu_type)); env = &cpu->env; /* Set time-base frequency to 100 Mhz */ cpu_ppc_tb_init(env, TBFREQ); qemu_register_reset(ppc_core99_reset, cpu); } /* allocate RAM */ memory_region_allocate_system_memory(ram, NULL, "ppc_core99.ram", ram_size); memory_region_add_subregion(get_system_memory(), 0, ram); /* allocate and load BIOS */ memory_region_init_ram(bios, NULL, "ppc_core99.bios", BIOS_SIZE, &error_fatal); if (bios_name == NULL) bios_name = PROM_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); memory_region_set_readonly(bios, true); memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios); /* Load OpenBIOS (ELF) */ if (filename) { bios_size = load_elf(filename, NULL, NULL, NULL, NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0); g_free(filename); } else { bios_size = -1; } if (bios_size < 0 || bios_size > BIOS_SIZE) { error_report("could not load PowerPC bios '%s'", bios_name); exit(1); } if (linux_boot) { uint64_t lowaddr = 0; int bswap_needed; #ifdef BSWAP_NEEDED bswap_needed = 1; #else bswap_needed = 0; #endif kernel_base = KERNEL_LOAD_ADDR; kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE, 0, 0); if (kernel_size < 0) kernel_size = load_aout(kernel_filename, kernel_base, ram_size - kernel_base, bswap_needed, TARGET_PAGE_SIZE); if (kernel_size < 0) kernel_size = load_image_targphys(kernel_filename, kernel_base, ram_size - kernel_base); if (kernel_size < 0) { error_report("could not load kernel '%s'", kernel_filename); exit(1); } /* load initrd */ if (initrd_filename) { initrd_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP); initrd_size = load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); if (initrd_size < 0) { error_report("could not load initial ram disk '%s'", initrd_filename); exit(1); } cmdline_base = TARGET_PAGE_ALIGN(initrd_base + initrd_size); } else { initrd_base = 0; initrd_size = 0; cmdline_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP); } ppc_boot_device = 'm'; } else { kernel_base = 0; kernel_size = 0; initrd_base = 0; initrd_size = 0; ppc_boot_device = '\0'; /* We consider that NewWorld PowerMac never have any floppy drive * For now, OHW cannot boot from the network. */ for (i = 0; boot_device[i] != '\0'; i++) { if (boot_device[i] >= 'c' && boot_device[i] <= 'f') { ppc_boot_device = boot_device[i]; break; } } if (ppc_boot_device == '\0') { error_report("No valid boot device for Mac99 machine"); exit(1); } } /* UniN init */ dev = qdev_create(NULL, TYPE_UNI_NORTH); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); memory_region_add_subregion(get_system_memory(), 0xf8000000, sysbus_mmio_get_region(s, 0)); openpic_irqs = g_new0(IrqLines, smp_cpus); for (i = 0; i < smp_cpus; i++) { /* Mac99 IRQ connection between OpenPIC outputs pins * and PowerPC input pins */ switch (PPC_INPUT(env)) { case PPC_FLAGS_INPUT_6xx: openpic_irqs[i].irq[OPENPIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; openpic_irqs[i].irq[OPENPIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; openpic_irqs[i].irq[OPENPIC_OUTPUT_MCK] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_MCP]; /* Not connected ? */ openpic_irqs[i].irq[OPENPIC_OUTPUT_DEBUG] = NULL; /* Check this */ openpic_irqs[i].irq[OPENPIC_OUTPUT_RESET] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_HRESET]; break; #if defined(TARGET_PPC64) case PPC_FLAGS_INPUT_970: openpic_irqs[i].irq[OPENPIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT]; openpic_irqs[i].irq[OPENPIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT]; openpic_irqs[i].irq[OPENPIC_OUTPUT_MCK] = ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_MCP]; /* Not connected ? */ openpic_irqs[i].irq[OPENPIC_OUTPUT_DEBUG] = NULL; /* Check this */ openpic_irqs[i].irq[OPENPIC_OUTPUT_RESET] = ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_HRESET]; break; #endif /* defined(TARGET_PPC64) */ default: error_report("Bus model not supported on mac99 machine"); exit(1); } } pic_dev = qdev_create(NULL, TYPE_OPENPIC); qdev_prop_set_uint32(pic_dev, "model", OPENPIC_MODEL_KEYLARGO); qdev_init_nofail(pic_dev); s = SYS_BUS_DEVICE(pic_dev); k = 0; for (i = 0; i < smp_cpus; i++) { for (j = 0; j < OPENPIC_OUTPUT_NB; j++) { sysbus_connect_irq(s, k++, openpic_irqs[i].irq[j]); } } g_free(openpic_irqs); if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) { /* 970 gets a U3 bus */ /* Uninorth AGP bus */ dev = qdev_create(NULL, TYPE_U3_AGP_HOST_BRIDGE); object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", &error_abort); qdev_init_nofail(dev); uninorth_pci = U3_AGP_HOST_BRIDGE(dev); s = SYS_BUS_DEVICE(dev); /* PCI hole */ memory_region_add_subregion(get_system_memory(), 0x80000000ULL, sysbus_mmio_get_region(s, 2)); /* Register 8 MB of ISA IO space */ memory_region_add_subregion(get_system_memory(), 0xf2000000, sysbus_mmio_get_region(s, 3)); sysbus_mmio_map(s, 0, 0xf0800000); sysbus_mmio_map(s, 1, 0xf0c00000); machine_arch = ARCH_MAC99_U3; } else { /* Use values found on a real PowerMac */ /* Uninorth AGP bus */ dev = qdev_create(NULL, TYPE_UNI_NORTH_AGP_HOST_BRIDGE); object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", &error_abort); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); sysbus_mmio_map(s, 0, 0xf0800000); sysbus_mmio_map(s, 1, 0xf0c00000); /* Uninorth internal bus */ dev = qdev_create(NULL, TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE); object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", &error_abort); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); sysbus_mmio_map(s, 0, 0xf4800000); sysbus_mmio_map(s, 1, 0xf4c00000); /* Uninorth main bus */ dev = qdev_create(NULL, TYPE_UNI_NORTH_PCI_HOST_BRIDGE); qdev_prop_set_uint32(dev, "ofw-addr", 0xf2000000); object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", &error_abort); qdev_init_nofail(dev); uninorth_pci = UNI_NORTH_PCI_HOST_BRIDGE(dev); s = SYS_BUS_DEVICE(dev); /* PCI hole */ memory_region_add_subregion(get_system_memory(), 0x80000000ULL, sysbus_mmio_get_region(s, 2)); /* Register 8 MB of ISA IO space */ memory_region_add_subregion(get_system_memory(), 0xf2000000, sysbus_mmio_get_region(s, 3)); sysbus_mmio_map(s, 0, 0xf2800000); sysbus_mmio_map(s, 1, 0xf2c00000); machine_arch = ARCH_MAC99; } machine->usb |= defaults_enabled() && !machine->usb_disabled; has_pmu = (core99_machine->via_config != CORE99_VIA_CONFIG_CUDA); has_adb = (core99_machine->via_config == CORE99_VIA_CONFIG_CUDA || core99_machine->via_config == CORE99_VIA_CONFIG_PMU_ADB); /* Timebase Frequency */ if (kvm_enabled()) { tbfreq = kvmppc_get_tbfreq(); } else { tbfreq = TBFREQ; } /* init basic PC hardware */ pci_bus = PCI_HOST_BRIDGE(uninorth_pci)->bus; /* MacIO */ macio = NEWWORLD_MACIO(pci_create(pci_bus, -1, TYPE_NEWWORLD_MACIO)); dev = DEVICE(macio); qdev_prop_set_uint64(dev, "frequency", tbfreq); qdev_prop_set_bit(dev, "has-pmu", has_pmu); qdev_prop_set_bit(dev, "has-adb", has_adb); object_property_set_link(OBJECT(macio), OBJECT(pic_dev), "pic", &error_abort); qdev_init_nofail(dev); /* We only emulate 2 out of 3 IDE controllers for now */ ide_drive_get(hd, ARRAY_SIZE(hd)); macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), "ide[0]")); macio_ide_init_drives(macio_ide, hd); macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), "ide[1]")); macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]); if (has_adb) { if (has_pmu) { dev = DEVICE(object_resolve_path_component(OBJECT(macio), "pmu")); } else { dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda")); } adb_bus = qdev_get_child_bus(dev, "adb.0"); dev = qdev_create(adb_bus, TYPE_ADB_KEYBOARD); qdev_prop_set_bit(dev, "disable-direct-reg3-writes", true); qdev_init_nofail(dev); dev = qdev_create(adb_bus, TYPE_ADB_MOUSE); qdev_prop_set_bit(dev, "disable-direct-reg3-writes", true); qdev_init_nofail(dev); } if (machine->usb) { pci_create_simple(pci_bus, -1, "pci-ohci"); /* U3 needs to use USB for input because Linux doesn't support via-cuda on PPC64 */ if (!has_adb || machine_arch == ARCH_MAC99_U3) { USBBus *usb_bus = usb_bus_find(-1); usb_create_simple(usb_bus, "usb-kbd"); usb_create_simple(usb_bus, "usb-mouse"); } } pci_vga_init(pci_bus); if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) { graphic_depth = 15; } for (i = 0; i < nb_nics; i++) { pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL); } /* The NewWorld NVRAM is not located in the MacIO device */ #ifdef CONFIG_KVM if (kvm_enabled() && getpagesize() > 4096) { /* We can't combine read-write and read-only in a single page, so move the NVRAM out of ROM again for KVM */ nvram_addr = 0xFFE00000; } #endif dev = qdev_create(NULL, TYPE_MACIO_NVRAM); qdev_prop_set_uint32(dev, "size", 0x2000); qdev_prop_set_uint32(dev, "it_shift", 1); qdev_init_nofail(dev); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, nvram_addr); nvr = MACIO_NVRAM(dev); pmac_format_nvram_partition(nvr, 0x2000); /* No PCI init: the BIOS will do it */ dev = qdev_create(NULL, TYPE_FW_CFG_MEM); fw_cfg = FW_CFG(dev); qdev_prop_set_uint32(dev, "data_width", 1); qdev_prop_set_bit(dev, "dma_enabled", false); object_property_add_child(OBJECT(qdev_get_machine()), TYPE_FW_CFG, OBJECT(fw_cfg), NULL); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); sysbus_mmio_map(s, 0, CFG_ADDR); sysbus_mmio_map(s, 1, CFG_ADDR + 2); fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); if (kernel_cmdline) { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base); pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline); } else { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0); } fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base); fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_VIACONFIG, core99_machine->via_config); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled()); if (kvm_enabled()) { #ifdef CONFIG_KVM uint8_t *hypercall; hypercall = g_malloc(16); kvmppc_get_hypercall(env, hypercall, 16); fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid()); #endif } fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, tbfreq); /* Mac OS X requires a "known good" clock-frequency value; pass it one. */ fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_CLOCKFREQ, CLOCKFREQ); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_BUSFREQ, BUSFREQ); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_NVRAM_ADDR, nvram_addr); /* MacOS NDRV VGA driver */ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, NDRV_VGA_FILENAME); if (filename) { gchar *ndrv_file; gsize ndrv_size; if (g_file_get_contents(filename, &ndrv_file, &ndrv_size, NULL)) { fw_cfg_add_file(fw_cfg, "ndrv/qemu_vga.ndrv", ndrv_file, ndrv_size); } g_free(filename); } qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); }
static void mpc8544ds_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { PCIBus *pci_bus; CPUState *env; uint64_t elf_entry; uint64_t elf_lowaddr; target_phys_addr_t entry=0; target_phys_addr_t loadaddr=UIMAGE_LOAD_BASE; target_long kernel_size=0; target_ulong dt_base = 0; target_ulong initrd_base = 0; target_long initrd_size=0; int i=0; unsigned int pci_irq_nrs[4] = {1, 2, 3, 4}; qemu_irq *irqs, *mpic, *pci_irqs; SerialState * serial[2]; /* Setup CPU */ env = cpu_ppc_init("e500v2_v30"); if (!env) { fprintf(stderr, "Unable to initialize CPU!\n"); exit(1); } /* Fixup Memory size on a alignment boundary */ ram_size &= ~(RAM_SIZES_ALIGN - 1); /* Register Memory */ cpu_register_physical_memory(0, ram_size, qemu_ram_alloc(NULL, "mpc8544ds.ram", ram_size)); /* MPIC */ irqs = qemu_mallocz(sizeof(qemu_irq) * OPENPIC_OUTPUT_NB); irqs[OPENPIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPCE500_INPUT_INT]; irqs[OPENPIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPCE500_INPUT_CINT]; mpic = mpic_init(MPC8544_MPIC_REGS_BASE, 1, &irqs, NULL); /* Serial */ if (serial_hds[0]) { serial[0] = serial_mm_init(MPC8544_SERIAL0_REGS_BASE, 0, mpic[12+26], 399193, serial_hds[0], 1, 1); } if (serial_hds[1]) { serial[0] = serial_mm_init(MPC8544_SERIAL1_REGS_BASE, 0, mpic[12+26], 399193, serial_hds[0], 1, 1); } /* PCI */ pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4); pci_irqs[0] = mpic[pci_irq_nrs[0]]; pci_irqs[1] = mpic[pci_irq_nrs[1]]; pci_irqs[2] = mpic[pci_irq_nrs[2]]; pci_irqs[3] = mpic[pci_irq_nrs[3]]; pci_bus = ppce500_pci_init(pci_irqs, MPC8544_PCI_REGS_BASE); if (!pci_bus) printf("couldn't create PCI controller!\n"); isa_mmio_init(MPC8544_PCI_IO, MPC8544_PCI_IOLEN, 1); if (pci_bus) { /* Register network interfaces. */ for (i = 0; i < nb_nics; i++) { pci_nic_init_nofail(&nd_table[i], "virtio", NULL); } } /* Load kernel. */ if (kernel_filename) { kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL); if (kernel_size < 0) { kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry, &elf_lowaddr, NULL, 1, ELF_MACHINE, 0); entry = elf_entry; loadaddr = elf_lowaddr; } /* XXX try again as binary */ if (kernel_size < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } } /* Load initrd. */ if (initrd_filename) { initrd_base = (kernel_size + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK; initrd_size = load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); if (initrd_size < 0) { fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", initrd_filename); exit(1); } } /* If we're loading a kernel directly, we must load the device tree too. */ if (kernel_filename) { dt_base = (kernel_size + DTC_LOAD_PAD) & ~DTC_PAD_MASK; if (mpc8544_load_device_tree(dt_base, ram_size, initrd_base, initrd_size, kernel_cmdline) < 0) { fprintf(stderr, "couldn't load device tree\n"); exit(1); } cpu_synchronize_state(env); /* Set initial guest state. */ env->gpr[1] = (16<<20) - 8; env->gpr[3] = dt_base; env->nip = entry; /* XXX we currently depend on KVM to create some initial TLB entries. */ } if (kvm_enabled()) kvmppc_init(); return; }
static void ppc_heathrow_init(QEMUMachineInitArgs *args) { ram_addr_t ram_size = args->ram_size; const char *cpu_model = args->cpu_model; const char *kernel_filename = args->kernel_filename; const char *kernel_cmdline = args->kernel_cmdline; const char *initrd_filename = args->initrd_filename; const char *boot_device = args->boot_device; MemoryRegion *sysmem = get_system_memory(); PowerPCCPU *cpu = NULL; CPUPPCState *env = NULL; char *filename; qemu_irq *pic, **heathrow_irqs; int linux_boot, i; MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *bios = g_new(MemoryRegion, 1); uint32_t kernel_base, initrd_base, cmdline_base = 0; int32_t kernel_size, initrd_size; PCIBus *pci_bus; PCIDevice *macio; MACIOIDEState *macio_ide; DeviceState *dev; BusState *adb_bus; int bios_size; MemoryRegion *pic_mem; MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1); uint16_t ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; linux_boot = (kernel_filename != NULL); /* init CPUs */ if (cpu_model == NULL) cpu_model = "G3"; for (i = 0; i < smp_cpus; i++) { cpu = cpu_ppc_init(cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to find PowerPC CPU definition\n"); exit(1); } env = &cpu->env; /* Set time-base frequency to 16.6 Mhz */ cpu_ppc_tb_init(env, 16600000UL); qemu_register_reset(ppc_heathrow_reset, cpu); } /* allocate RAM */ if (ram_size > (2047 << 20)) { fprintf(stderr, "qemu: Too much memory for this machine: %d MB, maximum 2047 MB\n", ((unsigned int)ram_size / (1 << 20))); exit(1); } memory_region_init_ram(ram, "ppc_heathrow.ram", ram_size); vmstate_register_ram_global(ram); memory_region_add_subregion(sysmem, 0, ram); /* allocate and load BIOS */ memory_region_init_ram(bios, "ppc_heathrow.bios", BIOS_SIZE); vmstate_register_ram_global(bios); if (bios_name == NULL) bios_name = PROM_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); memory_region_set_readonly(bios, true); memory_region_add_subregion(sysmem, PROM_ADDR, bios); /* Load OpenBIOS (ELF) */ if (filename) { bios_size = load_elf(filename, 0, NULL, NULL, NULL, NULL, 1, ELF_MACHINE, 0); g_free(filename); } else { bios_size = -1; } if (bios_size < 0 || bios_size > BIOS_SIZE) { hw_error("qemu: could not load PowerPC bios '%s'\n", bios_name); exit(1); } if (linux_boot) { uint64_t lowaddr = 0; int bswap_needed; #ifdef BSWAP_NEEDED bswap_needed = 1; #else bswap_needed = 0; #endif kernel_base = KERNEL_LOAD_ADDR; kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0); if (kernel_size < 0) kernel_size = load_aout(kernel_filename, kernel_base, ram_size - kernel_base, bswap_needed, TARGET_PAGE_SIZE); if (kernel_size < 0) kernel_size = load_image_targphys(kernel_filename, kernel_base, ram_size - kernel_base); if (kernel_size < 0) { hw_error("qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } /* load initrd */ if (initrd_filename) { initrd_base = round_page(kernel_base + kernel_size + KERNEL_GAP); initrd_size = load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); if (initrd_size < 0) { hw_error("qemu: could not load initial ram disk '%s'\n", initrd_filename); exit(1); } cmdline_base = round_page(initrd_base + initrd_size); } else { initrd_base = 0; initrd_size = 0; cmdline_base = round_page(kernel_base + kernel_size + KERNEL_GAP); } ppc_boot_device = 'm'; } else { kernel_base = 0; kernel_size = 0; initrd_base = 0; initrd_size = 0; ppc_boot_device = '\0'; for (i = 0; boot_device[i] != '\0'; i++) { /* TOFIX: for now, the second IDE channel is not properly * used by OHW. The Mac floppy disk are not emulated. * For now, OHW cannot boot from the network. */ #if 0 if (boot_device[i] >= 'a' && boot_device[i] <= 'f') { ppc_boot_device = boot_device[i]; break; } #else if (boot_device[i] >= 'c' && boot_device[i] <= 'd') { ppc_boot_device = boot_device[i]; break; } #endif } if (ppc_boot_device == '\0') { fprintf(stderr, "No valid boot device for G3 Beige machine\n"); exit(1); } } /* Register 2 MB of ISA IO space */ isa_mmio_init(0xfe000000, 0x00200000); /* XXX: we register only 1 output pin for heathrow PIC */ heathrow_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); heathrow_irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * 1); /* Connect the heathrow PIC outputs to the 6xx bus */ for (i = 0; i < smp_cpus; i++) { switch (PPC_INPUT(env)) { case PPC_FLAGS_INPUT_6xx: heathrow_irqs[i] = heathrow_irqs[0] + (i * 1); heathrow_irqs[i][0] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; break; default: hw_error("Bus model not supported on OldWorld Mac machine\n"); } } /* init basic PC hardware */ if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) { hw_error("Only 6xx bus is supported on heathrow machine\n"); } pic = heathrow_pic_init(&pic_mem, 1, heathrow_irqs); pci_bus = pci_grackle_init(0xfec00000, pic, get_system_memory(), get_system_io()); pci_vga_init(pci_bus); escc_mem = escc_init(0, pic[0x0f], pic[0x10], serial_hds[0], serial_hds[1], ESCC_CLOCK, 4); memory_region_init_alias(escc_bar, "escc-bar", escc_mem, 0, memory_region_size(escc_mem)); for(i = 0; i < nb_nics; i++) pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL); ide_drive_get(hd, MAX_IDE_BUS); macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO); dev = DEVICE(macio); qdev_connect_gpio_out(dev, 0, pic[0x12]); /* CUDA */ qdev_connect_gpio_out(dev, 1, pic[0x0D]); /* IDE */ qdev_connect_gpio_out(dev, 2, pic[0x02]); /* IDE DMA */ macio_init(macio, pic_mem, escc_bar); /* First IDE channel is a MAC IDE on the MacIO bus */ macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), "ide")); macio_ide_init_drives(macio_ide, hd); /* Second IDE channel is a CMD646 on the PCI bus */ hd[0] = hd[MAX_IDE_DEVS]; hd[1] = hd[MAX_IDE_DEVS + 1]; hd[3] = hd[2] = NULL; pci_cmd646_ide_init(pci_bus, hd, 0); dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda")); adb_bus = qdev_get_child_bus(dev, "adb.0"); dev = qdev_create(adb_bus, TYPE_ADB_KEYBOARD); qdev_init_nofail(dev); dev = qdev_create(adb_bus, TYPE_ADB_MOUSE); qdev_init_nofail(dev); if (usb_enabled(false)) { pci_create_simple(pci_bus, -1, "pci-ohci"); } if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) graphic_depth = 15; /* No PCI init: the BIOS will do it */ fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2); fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); if (kernel_cmdline) { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base); pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline); } else { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0); } fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base); fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled()); if (kvm_enabled()) { #ifdef CONFIG_KVM uint8_t *hypercall; fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq()); hypercall = g_malloc(16); kvmppc_get_hypercall(env, hypercall, 16); fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid()); #endif } else { fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec()); } qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); }
static void mpc8544ds_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); PCIBus *pci_bus; CPUPPCState *env = NULL; uint64_t elf_entry; uint64_t elf_lowaddr; target_phys_addr_t entry=0; target_phys_addr_t loadaddr=UIMAGE_LOAD_BASE; target_long kernel_size=0; target_ulong dt_base = 0; target_ulong initrd_base = 0; target_long initrd_size=0; int i=0; unsigned int pci_irq_nrs[4] = {1, 2, 3, 4}; qemu_irq **irqs, *mpic; DeviceState *dev; CPUPPCState *firstenv = NULL; /* Setup CPUs */ if (cpu_model == NULL) { cpu_model = "e500v2_v30"; } irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB); for (i = 0; i < smp_cpus; i++) { PowerPCCPU *cpu; qemu_irq *input; cpu = cpu_ppc_init(cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to initialize CPU!\n"); exit(1); } env = &cpu->env; if (!firstenv) { firstenv = env; } irqs[i] = irqs[0] + (i * OPENPIC_OUTPUT_NB); input = (qemu_irq *)env->irq_inputs; irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT]; irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT]; env->spr[SPR_BOOKE_PIR] = env->cpu_index = i; ppc_booke_timers_init(env, 400000000, PPC_TIMER_E500); /* Register reset handler */ if (!i) { /* Primary CPU */ struct boot_info *boot_info; boot_info = g_malloc0(sizeof(struct boot_info)); qemu_register_reset(mpc8544ds_cpu_reset, cpu); env->load_info = boot_info; } else { /* Secondary CPUs */ qemu_register_reset(mpc8544ds_cpu_reset_sec, cpu); } } env = firstenv; /* Fixup Memory size on a alignment boundary */ ram_size &= ~(RAM_SIZES_ALIGN - 1); /* Register Memory */ memory_region_init_ram(ram, "mpc8544ds.ram", ram_size); vmstate_register_ram_global(ram); memory_region_add_subregion(address_space_mem, 0, ram); /* MPIC */ mpic = mpic_init(address_space_mem, MPC8544_MPIC_REGS_BASE, smp_cpus, irqs, NULL); if (!mpic) { cpu_abort(env, "MPIC failed to initialize\n"); } /* Serial */ if (serial_hds[0]) { serial_mm_init(address_space_mem, MPC8544_SERIAL0_REGS_BASE, 0, mpic[12+26], 399193, serial_hds[0], DEVICE_BIG_ENDIAN); } if (serial_hds[1]) { serial_mm_init(address_space_mem, MPC8544_SERIAL1_REGS_BASE, 0, mpic[12+26], 399193, serial_hds[0], DEVICE_BIG_ENDIAN); } /* General Utility device */ sysbus_create_simple("mpc8544-guts", MPC8544_UTIL_BASE, NULL); /* PCI */ dev = sysbus_create_varargs("e500-pcihost", MPC8544_PCI_REGS_BASE, mpic[pci_irq_nrs[0]], mpic[pci_irq_nrs[1]], mpic[pci_irq_nrs[2]], mpic[pci_irq_nrs[3]], NULL); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0"); if (!pci_bus) printf("couldn't create PCI controller!\n"); isa_mmio_init(MPC8544_PCI_IO, MPC8544_PCI_IOLEN); if (pci_bus) { /* Register network interfaces. */ for (i = 0; i < nb_nics; i++) { pci_nic_init_nofail(&nd_table[i], "virtio", NULL); } } /* Register spinning region */ sysbus_create_simple("e500-spin", MPC8544_SPIN_BASE, NULL); /* Load kernel. */ if (kernel_filename) { kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL); if (kernel_size < 0) { kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry, &elf_lowaddr, NULL, 1, ELF_MACHINE, 0); entry = elf_entry; loadaddr = elf_lowaddr; } /* XXX try again as binary */ if (kernel_size < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } } /* Load initrd. */ if (initrd_filename) { initrd_base = (kernel_size + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK; initrd_size = load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); if (initrd_size < 0) { fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", initrd_filename); exit(1); } } /* If we're loading a kernel directly, we must load the device tree too. */ if (kernel_filename) { struct boot_info *boot_info; #ifndef CONFIG_FDT cpu_abort(env, "Compiled without FDT support - can't load kernel\n"); #endif dt_base = (kernel_size + DTC_LOAD_PAD) & ~DTC_PAD_MASK; if (mpc8544_load_device_tree(env, dt_base, ram_size, initrd_base, initrd_size, kernel_cmdline) < 0) { fprintf(stderr, "couldn't load device tree\n"); exit(1); } boot_info = env->load_info; boot_info->entry = entry; boot_info->dt_base = dt_base; } if (kvm_enabled()) { kvmppc_init(); } }
/* PC hardware initialisation */ static void pc_init1(MemoryRegion *system_memory, ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, int pci_enabled, int kvmclock_enabled) { int i; ram_addr_t below_4g_mem_size, above_4g_mem_size; PCIBus *pci_bus; PCII440FXState *i440fx_state; int piix3_devfn = -1; qemu_irq *cpu_irq; qemu_irq *isa_irq; qemu_irq *i8259; qemu_irq *cmos_s3; qemu_irq *smi_irq; IsaIrqState *isa_irq_state; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; BusState *idebus[MAX_IDE_BUS]; ISADevice *rtc_state; pc_cpus_init(cpu_model); if (kvmclock_enabled) { kvmclock_create(); } if (ram_size >= 0xe0000000 ) { above_4g_mem_size = ram_size - 0xe0000000; below_4g_mem_size = 0xe0000000; } else { above_4g_mem_size = 0; below_4g_mem_size = ram_size; } /* allocate ram and load rom/bios */ if (!xen_enabled()) { pc_memory_init(system_memory, kernel_filename, kernel_cmdline, initrd_filename, below_4g_mem_size, above_4g_mem_size); } if (!xen_enabled()) { cpu_irq = pc_allocate_cpu_irq(); i8259 = i8259_init(cpu_irq[0]); } else { i8259 = xen_interrupt_controller_init(); } isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state)); isa_irq_state->i8259 = i8259; if (pci_enabled) { ioapic_init(isa_irq_state); } isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24); if (pci_enabled) { pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, system_memory, ram_size); } else { pci_bus = NULL; i440fx_state = NULL; isa_bus_new(NULL); } isa_bus_irqs(isa_irq); pc_register_ferr_irq(isa_get_irq(13)); pc_vga_init(pci_enabled? pci_bus: NULL); if (xen_enabled()) { pci_create_simple(pci_bus, -1, "xen-platform"); } /* init basic PC hardware */ pc_basic_device_init(isa_irq, &rtc_state, xen_enabled()); for(i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0)) pc_init_ne2k_isa(nd); else pci_nic_init_nofail(nd, "e1000", NULL); } ide_drive_get(hd, MAX_IDE_BUS); if (pci_enabled) { PCIDevice *dev; if (xen_enabled()) { dev = pci_piix3_xen_ide_init(pci_bus, hd, piix3_devfn + 1); } else { dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1); } idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0"); idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1"); } else { for(i = 0; i < MAX_IDE_BUS; i++) { ISADevice *dev; dev = isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i], hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]); idebus[i] = qdev_get_child_bus(&dev->qdev, "ide.0"); } } audio_init(isa_irq, pci_enabled ? pci_bus : NULL); pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, idebus[0], idebus[1], rtc_state); if (pci_enabled && usb_enabled) { usb_uhci_piix3_init(pci_bus, piix3_devfn + 2); } if (pci_enabled && acpi_enabled) { i2c_bus *smbus; if (!xen_enabled()) { cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1); } else { cmos_s3 = qemu_allocate_irqs(xen_cmos_set_s3_resume, rtc_state, 1); } smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1); /* TODO: Populate SPD eeprom data. */ smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, isa_get_irq(9), *cmos_s3, *smi_irq, kvm_enabled()); smbus_eeprom_init(smbus, 8, NULL, 0); } if (i440fx_state) { i440fx_init_memory_mappings(i440fx_state); } if (pci_enabled) { pc_pci_device_init(pci_bus); } }
static void realview_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, enum realview_board_type board_type) { ARMCPU *cpu = NULL; CPUARMState *env; MemoryRegion *sysmem = get_system_memory(); MemoryRegion *ram_lo = g_new(MemoryRegion, 1); MemoryRegion *ram_hi = g_new(MemoryRegion, 1); MemoryRegion *ram_alias = g_new(MemoryRegion, 1); MemoryRegion *ram_hack = g_new(MemoryRegion, 1); DeviceState *dev, *sysctl, *gpio2, *pl041; SysBusDevice *busdev; qemu_irq *irqp; qemu_irq pic[64]; qemu_irq mmc_irq[2]; PCIBus *pci_bus; NICInfo *nd; i2c_bus *i2c; int n; int done_nic = 0; qemu_irq cpu_irq[4]; int is_mpcore = 0; int is_pb = 0; uint32_t proc_id = 0; uint32_t sys_id; ram_addr_t low_ram_size; switch (board_type) { case BOARD_EB: break; case BOARD_EB_MPCORE: is_mpcore = 1; break; case BOARD_PB_A8: is_pb = 1; break; case BOARD_PBX_A9: is_mpcore = 1; is_pb = 1; break; } for (n = 0; n < smp_cpus; n++) { cpu = cpu_arm_init(cpu_model); if (!cpu) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } irqp = arm_pic_init_cpu(cpu); cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ]; } env = &cpu->env; if (arm_feature(env, ARM_FEATURE_V7)) { if (is_mpcore) { proc_id = 0x0c000000; } else { proc_id = 0x0e000000; } } else if (arm_feature(env, ARM_FEATURE_V6K)) { proc_id = 0x06000000; } else if (arm_feature(env, ARM_FEATURE_V6)) { proc_id = 0x04000000; } else { proc_id = 0x02000000; } if (is_pb && ram_size > 0x20000000) { /* Core tile RAM. */ low_ram_size = ram_size - 0x20000000; ram_size = 0x20000000; memory_region_init_ram(ram_lo, "realview.lowmem", low_ram_size); vmstate_register_ram_global(ram_lo); memory_region_add_subregion(sysmem, 0x20000000, ram_lo); } memory_region_init_ram(ram_hi, "realview.highmem", ram_size); vmstate_register_ram_global(ram_hi); low_ram_size = ram_size; if (low_ram_size > 0x10000000) low_ram_size = 0x10000000; /* SDRAM at address zero. */ memory_region_init_alias(ram_alias, "realview.alias", ram_hi, 0, low_ram_size); memory_region_add_subregion(sysmem, 0, ram_alias); if (is_pb) { /* And again at a high address. */ memory_region_add_subregion(sysmem, 0x70000000, ram_hi); } else { ram_size = low_ram_size; } sys_id = is_pb ? 0x01780500 : 0xc1400400; sysctl = qdev_create(NULL, "realview_sysctl"); qdev_prop_set_uint32(sysctl, "sys_id", sys_id); qdev_prop_set_uint32(sysctl, "proc_id", proc_id); qdev_init_nofail(sysctl); sysbus_mmio_map(sysbus_from_qdev(sysctl), 0, 0x10000000); if (is_mpcore) { target_phys_addr_t periphbase; dev = qdev_create(NULL, is_pb ? "a9mpcore_priv": "realview_mpcore"); qdev_prop_set_uint32(dev, "num-cpu", smp_cpus); qdev_init_nofail(dev); busdev = sysbus_from_qdev(dev); if (is_pb) { periphbase = 0x1f000000; } else { periphbase = 0x10100000; } sysbus_mmio_map(busdev, 0, periphbase); for (n = 0; n < smp_cpus; n++) { sysbus_connect_irq(busdev, n, cpu_irq[n]); } sysbus_create_varargs("l2x0", periphbase + 0x2000, NULL); /* Both A9 and 11MPCore put the GIC CPU i/f at base + 0x100 */ realview_binfo.gic_cpu_if_addr = periphbase + 0x100; } else { uint32_t gic_addr = is_pb ? 0x1e000000 : 0x10040000; /* For now just create the nIRQ GIC, and ignore the others. */ dev = sysbus_create_simple("realview_gic", gic_addr, cpu_irq[0]); } for (n = 0; n < 64; n++) { pic[n] = qdev_get_gpio_in(dev, n); } pl041 = qdev_create(NULL, "pl041"); qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512); qdev_init_nofail(pl041); sysbus_mmio_map(sysbus_from_qdev(pl041), 0, 0x10004000); sysbus_connect_irq(sysbus_from_qdev(pl041), 0, pic[19]); sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]); sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]); sysbus_create_simple("pl011", 0x10009000, pic[12]); sysbus_create_simple("pl011", 0x1000a000, pic[13]); sysbus_create_simple("pl011", 0x1000b000, pic[14]); sysbus_create_simple("pl011", 0x1000c000, pic[15]); /* DMA controller is optional, apparently. */ sysbus_create_simple("pl081", 0x10030000, pic[24]); sysbus_create_simple("sp804", 0x10011000, pic[4]); sysbus_create_simple("sp804", 0x10012000, pic[5]); sysbus_create_simple("pl061", 0x10013000, pic[6]); sysbus_create_simple("pl061", 0x10014000, pic[7]); gpio2 = sysbus_create_simple("pl061", 0x10015000, pic[8]); sysbus_create_simple("pl111", 0x10020000, pic[23]); dev = sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL); /* Wire up MMC card detect and read-only signals. These have * to go to both the PL061 GPIO and the sysctl register. * Note that the PL181 orders these lines (readonly,inserted) * and the PL061 has them the other way about. Also the card * detect line is inverted. */ mmc_irq[0] = qemu_irq_split( qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT), qdev_get_gpio_in(gpio2, 1)); mmc_irq[1] = qemu_irq_split( qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN), qemu_irq_invert(qdev_get_gpio_in(gpio2, 0))); qdev_connect_gpio_out(dev, 0, mmc_irq[0]); qdev_connect_gpio_out(dev, 1, mmc_irq[1]); sysbus_create_simple("pl031", 0x10017000, pic[10]); if (!is_pb) { dev = qdev_create(NULL, "realview_pci"); busdev = sysbus_from_qdev(dev); qdev_init_nofail(dev); sysbus_mmio_map(busdev, 0, 0x61000000); /* PCI self-config */ sysbus_mmio_map(busdev, 1, 0x62000000); /* PCI config */ sysbus_mmio_map(busdev, 2, 0x63000000); /* PCI I/O */ sysbus_connect_irq(busdev, 0, pic[48]); sysbus_connect_irq(busdev, 1, pic[49]); sysbus_connect_irq(busdev, 2, pic[50]); sysbus_connect_irq(busdev, 3, pic[51]); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci"); if (usb_enabled) { pci_create_simple(pci_bus, -1, "pci-ohci"); } n = drive_get_max_bus(IF_SCSI); while (n >= 0) { pci_create_simple(pci_bus, -1, "lsi53c895a"); n--; } } for(n = 0; n < nb_nics; n++) { nd = &nd_table[n]; if (!done_nic && (!nd->model || strcmp(nd->model, is_pb ? "lan9118" : "smc91c111") == 0)) { if (is_pb) { lan9118_init(nd, 0x4e000000, pic[28]); } else { smc91c111_init(nd, 0x4e000000, pic[28]); } done_nic = 1; } else { pci_nic_init_nofail(nd, "rtl8139", NULL); } } dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL); i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); i2c_create_slave(i2c, "ds1338", 0x68); /* Memory map for RealView Emulation Baseboard: */ /* 0x10000000 System registers. */ /* 0x10001000 System controller. */ /* 0x10002000 Two-Wire Serial Bus. */ /* 0x10003000 Reserved. */ /* 0x10004000 AACI. */ /* 0x10005000 MCI. */ /* 0x10006000 KMI0. */ /* 0x10007000 KMI1. */ /* 0x10008000 Character LCD. (EB) */ /* 0x10009000 UART0. */ /* 0x1000a000 UART1. */ /* 0x1000b000 UART2. */ /* 0x1000c000 UART3. */ /* 0x1000d000 SSPI. */ /* 0x1000e000 SCI. */ /* 0x1000f000 Reserved. */ /* 0x10010000 Watchdog. */ /* 0x10011000 Timer 0+1. */ /* 0x10012000 Timer 2+3. */ /* 0x10013000 GPIO 0. */ /* 0x10014000 GPIO 1. */ /* 0x10015000 GPIO 2. */ /* 0x10002000 Two-Wire Serial Bus - DVI. (PB) */ /* 0x10017000 RTC. */ /* 0x10018000 DMC. */ /* 0x10019000 PCI controller config. */ /* 0x10020000 CLCD. */ /* 0x10030000 DMA Controller. */ /* 0x10040000 GIC1. (EB) */ /* 0x10050000 GIC2. (EB) */ /* 0x10060000 GIC3. (EB) */ /* 0x10070000 GIC4. (EB) */ /* 0x10080000 SMC. */ /* 0x1e000000 GIC1. (PB) */ /* 0x1e001000 GIC2. (PB) */ /* 0x1e002000 GIC3. (PB) */ /* 0x1e003000 GIC4. (PB) */ /* 0x40000000 NOR flash. */ /* 0x44000000 DoC flash. */ /* 0x48000000 SRAM. */ /* 0x4c000000 Configuration flash. */ /* 0x4e000000 Ethernet. */ /* 0x4f000000 USB. */ /* 0x50000000 PISMO. */ /* 0x54000000 PISMO. */ /* 0x58000000 PISMO. */ /* 0x5c000000 PISMO. */ /* 0x60000000 PCI. */ /* 0x61000000 PCI Self Config. */ /* 0x62000000 PCI Config. */ /* 0x63000000 PCI IO. */ /* 0x64000000 PCI mem 0. */ /* 0x68000000 PCI mem 1. */ /* 0x6c000000 PCI mem 2. */ /* ??? Hack to map an additional page of ram for the secondary CPU startup code. I guess this works on real hardware because the BootROM happens to be in ROM/flash or in memory that isn't clobbered until after Linux boots the secondary CPUs. */ memory_region_init_ram(ram_hack, "realview.hack", 0x1000); vmstate_register_ram_global(ram_hack); memory_region_add_subregion(sysmem, SMP_BOOT_ADDR, ram_hack); realview_binfo.ram_size = ram_size; realview_binfo.kernel_filename = kernel_filename; realview_binfo.kernel_cmdline = kernel_cmdline; realview_binfo.initrd_filename = initrd_filename; realview_binfo.nb_cpus = smp_cpus; realview_binfo.board_id = realview_board_id[board_type]; realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0); arm_load_kernel(arm_env_get_cpu(first_cpu), &realview_binfo); }
static void realview_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, enum realview_board_type board_type) { CPUState *env = NULL; ram_addr_t ram_offset; DeviceState *dev; SysBusDevice *busdev; qemu_irq *irqp; qemu_irq pic[64]; PCIBus *pci_bus; NICInfo *nd; i2c_bus *i2c; DriveInfo *ide,*ide2; int n; int done_nic = 0; qemu_irq cpu_irq[4]; int is_mpcore = 0; int is_pb = 0; uint32_t proc_id = 0; uint32_t sys_id; ram_addr_t low_ram_size; switch (board_type) { case BOARD_EB: break; case BOARD_EB_MPCORE: is_mpcore = 1; break; case BOARD_PB_A8: is_pb = 1; break; case BOARD_PBX_A9: is_mpcore = 1; is_pb = 1; break; } for (n = 0; n < smp_cpus; n++) { env = cpu_init(cpu_model); if (!env) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } irqp = arm_pic_init_cpu(env); cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ]; if (n > 0) { qemu_register_reset(secondary_cpu_reset, env); } } if (arm_feature(env, ARM_FEATURE_V7)) { if (is_mpcore) { proc_id = 0x0c000000; } else { proc_id = 0x0e000000; } } else if (arm_feature(env, ARM_FEATURE_V6K)) { proc_id = 0x06000000; } else if (arm_feature(env, ARM_FEATURE_V6)) { proc_id = 0x04000000; } else { proc_id = 0x02000000; } if (is_pb && ram_size > 0x20000000) { /* Core tile RAM. */ low_ram_size = ram_size - 0x20000000; ram_size = 0x20000000; ram_offset = qemu_ram_alloc(NULL, "realview.lowmem", low_ram_size); cpu_register_physical_memory(0x20000000, low_ram_size, ram_offset | IO_MEM_RAM); } ram_offset = qemu_ram_alloc(NULL, "realview.highmem", ram_size); low_ram_size = ram_size; if (low_ram_size > 0x10000000) low_ram_size = 0x10000000; /* SDRAM at address zero. */ cpu_register_physical_memory(0, low_ram_size, ram_offset | IO_MEM_RAM); if (is_pb) { /* And again at a high address. */ cpu_register_physical_memory(0x70000000, ram_size, ram_offset | IO_MEM_RAM); } else { ram_size = low_ram_size; } sys_id = is_pb ? 0x01780500 : 0xc1400400; arm_sysctl_init(0x10000000, sys_id, proc_id); if (is_mpcore) { dev = qdev_create(NULL, is_pb ? "a9mpcore_priv": "realview_mpcore"); qdev_prop_set_uint32(dev, "num-cpu", smp_cpus); qdev_init_nofail(dev); busdev = sysbus_from_qdev(dev); if (is_pb) { realview_binfo.smp_priv_base = 0x1f000000; } else { realview_binfo.smp_priv_base = 0x10100000; } sysbus_mmio_map(busdev, 0, realview_binfo.smp_priv_base); for (n = 0; n < smp_cpus; n++) { sysbus_connect_irq(busdev, n, cpu_irq[n]); } } else { uint32_t gic_addr = is_pb ? 0x1e000000 : 0x10040000; /* For now just create the nIRQ GIC, and ignore the others. */ dev = sysbus_create_simple("realview_gic", gic_addr, cpu_irq[0]); } for (n = 0; n < 64; n++) { pic[n] = qdev_get_gpio_in(dev, n); } sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]); sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]); sysbus_create_simple("pl011", 0x10009000, pic[12]); sysbus_create_simple("pl011", 0x1000a000, pic[13]); sysbus_create_simple("pl011", 0x1000b000, pic[14]); sysbus_create_simple("pl011", 0x1000c000, pic[15]); /* DMA controller is optional, apparently. */ sysbus_create_simple("pl081", 0x10030000, pic[24]); sysbus_create_simple("sp804", 0x10011000, pic[4]); sysbus_create_simple("sp804", 0x10012000, pic[5]); sysbus_create_simple("pl110_versatile", 0x10020000, pic[23]); sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL); sysbus_create_simple("pl031", 0x10017000, pic[10]); if (!is_pb) { dev = sysbus_create_varargs("realview_pci", 0x60000000, pic[48], pic[49], pic[50], pic[51], NULL); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci"); if (usb_enabled) { usb_ohci_init_pci(pci_bus, -1); } n = drive_get_max_bus(IF_SCSI); while (n >= 0) { pci_create_simple(pci_bus, -1, "lsi53c895a"); n--; } } for(n = 0; n < nb_nics; n++) { nd = &nd_table[n]; if ((!nd->model && !done_nic) || strcmp(nd->model, is_pb ? "lan9118" : "smc91c111") == 0) { if (is_pb) { lan9118_init(nd, 0x4e000000, pic[28]); } else { smc91c111_init(nd, 0x4e000000, pic[28]); } done_nic = 1; } else { pci_nic_init_nofail(nd, "rtl8139", NULL); } } dev = sysbus_create_simple("realview_i2c", 0x10002000, NULL); i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); i2c_create_slave(i2c, "ds1338", 0x68); ide = drive_get(IF_IDE, 0, 0); ide2 = drive_get(IF_IDE, 0, 1); mmio_ide_init(0x18000000, 0x18000100, 0, 1, ide, ide2); /* Memory map for RealView Emulation Baseboard: */ /* 0x10000000 System registers. */ /* 0x10001000 System controller. */ /* 0x10002000 Two-Wire Serial Bus. */ /* 0x10003000 Reserved. */ /* 0x10004000 AACI. */ /* 0x10005000 MCI. */ /* 0x10006000 KMI0. */ /* 0x10007000 KMI1. */ /* 0x10008000 Character LCD. (EB) */ /* 0x10009000 UART0. */ /* 0x1000a000 UART1. */ /* 0x1000b000 UART2. */ /* 0x1000c000 UART3. */ /* 0x1000d000 SSPI. */ /* 0x1000e000 SCI. */ /* 0x1000f000 Reserved. */ /* 0x10010000 Watchdog. */ /* 0x10011000 Timer 0+1. */ /* 0x10012000 Timer 2+3. */ /* 0x10013000 GPIO 0. */ /* 0x10014000 GPIO 1. */ /* 0x10015000 GPIO 2. */ /* 0x10002000 Two-Wire Serial Bus - DVI. (PB) */ /* 0x10017000 RTC. */ /* 0x10018000 DMC. */ /* 0x10019000 PCI controller config. */ /* 0x10020000 CLCD. */ /* 0x10030000 DMA Controller. */ /* 0x10040000 GIC1. (EB) */ /* 0x10050000 GIC2. (EB) */ /* 0x10060000 GIC3. (EB) */ /* 0x10070000 GIC4. (EB) */ /* 0x10080000 SMC. */ /* 0x1e000000 GIC1. (PB) */ /* 0x1e001000 GIC2. (PB) */ /* 0x1e002000 GIC3. (PB) */ /* 0x1e003000 GIC4. (PB) */ /* 0x40000000 NOR flash. */ /* 0x44000000 DoC flash. */ /* 0x48000000 SRAM. */ /* 0x4c000000 Configuration flash. */ /* 0x4e000000 Ethernet. */ /* 0x4f000000 USB. */ /* 0x50000000 PISMO. */ /* 0x54000000 PISMO. */ /* 0x58000000 PISMO. */ /* 0x5c000000 PISMO. */ /* 0x60000000 PCI. */ /* 0x61000000 PCI Self Config. */ /* 0x62000000 PCI Config. */ /* 0x63000000 PCI IO. */ /* 0x64000000 PCI mem 0. */ /* 0x68000000 PCI mem 1. */ /* 0x6c000000 PCI mem 2. */ /* ??? Hack to map an additional page of ram for the secondary CPU startup code. I guess this works on real hardware because the BootROM happens to be in ROM/flash or in memory that isn't clobbered until after Linux boots the secondary CPUs. */ ram_offset = qemu_ram_alloc(NULL, "realview.hack", 0x1000); cpu_register_physical_memory(SMP_BOOT_ADDR, 0x1000, ram_offset | IO_MEM_RAM); realview_binfo.ram_size = ram_size; realview_binfo.kernel_filename = kernel_filename; realview_binfo.kernel_cmdline = kernel_cmdline; realview_binfo.initrd_filename = initrd_filename; realview_binfo.nb_cpus = smp_cpus; realview_binfo.board_id = realview_board_id[board_type]; realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0); arm_load_kernel(first_cpu, &realview_binfo); }
/* PC hardware initialisation */ static void pc_init1(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, int pci_enabled) { int i; ram_addr_t below_4g_mem_size, above_4g_mem_size; PCIBus *pci_bus; PCII440FXState *i440fx_state; int piix3_devfn = -1; qemu_irq *cpu_irq; qemu_irq *isa_irq; qemu_irq *i8259; qemu_irq *cmos_s3; qemu_irq *smi_irq; IsaIrqState *isa_irq_state; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; FDCtrl *floppy_controller; BusState *idebus[MAX_IDE_BUS]; ISADevice *rtc_state; pc_cpus_init(cpu_model); vmport_init(); /* allocate ram and load rom/bios */ pc_memory_init(ram_size, kernel_filename, kernel_cmdline, initrd_filename, &below_4g_mem_size, &above_4g_mem_size); cpu_irq = pc_allocate_cpu_irq(); i8259 = i8259_init(cpu_irq[0]); isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state)); isa_irq_state->i8259 = i8259; if (pci_enabled) { ioapic_init(isa_irq_state); } isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24); if (pci_enabled) { pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size); } else { pci_bus = NULL; i440fx_state = NULL; isa_bus_new(NULL); } isa_bus_irqs(isa_irq); pc_register_ferr_irq(isa_reserve_irq(13)); pc_vga_init(pci_enabled? pci_bus: NULL); /* init basic PC hardware */ pc_basic_device_init(isa_irq, &floppy_controller, &rtc_state); for(i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0)) pc_init_ne2k_isa(nd); else pci_nic_init_nofail(nd, "e1000", NULL); } if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { fprintf(stderr, "qemu: too many IDE bus\n"); exit(1); } for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) { hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); } if (pci_enabled) { PCIDevice *dev; dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1); idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0"); idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1"); } else { for(i = 0; i < MAX_IDE_BUS; i++) { ISADevice *dev; dev = isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i], hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]); idebus[i] = qdev_get_child_bus(&dev->qdev, "ide.0"); } } audio_init(isa_irq, pci_enabled ? pci_bus : NULL); pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, idebus[0], idebus[1], floppy_controller, rtc_state); if (pci_enabled && usb_enabled) { usb_uhci_piix3_init(pci_bus, piix3_devfn + 2); } if (pci_enabled && acpi_enabled) { uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */ i2c_bus *smbus; cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1); smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1); /* TODO: Populate SPD eeprom data. */ smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, isa_reserve_irq(9), *cmos_s3, *smi_irq, kvm_enabled()); for (i = 0; i < 8; i++) { DeviceState *eeprom; eeprom = qdev_create((BusState *)smbus, "smbus-eeprom"); qdev_prop_set_uint8(eeprom, "address", 0x50 + i); qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256)); qdev_init_nofail(eeprom); } } if (i440fx_state) { i440fx_init_memory_mappings(i440fx_state); } if (pci_enabled) { pc_pci_device_init(pci_bus); } }
static void r2d_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { CPUState *env; struct SH7750State *s; ram_addr_t sdram_addr; qemu_irq *irq; PCIBus *pci; DriveInfo *dinfo; int i; if (!cpu_model) cpu_model = "SH7751R"; env = cpu_init(cpu_model); if (!env) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } /* Allocate memory space */ sdram_addr = qemu_ram_alloc(SDRAM_SIZE); cpu_register_physical_memory(SDRAM_BASE, SDRAM_SIZE, sdram_addr); /* Register peripherals */ s = sh7750_init(env); irq = r2d_fpga_init(0x04000000, sh7750_irl(s)); pci = sh_pci_register_bus(r2d_pci_set_irq, r2d_pci_map_irq, irq, 0, 4); sm501_init(0x10000000, SM501_VRAM_SIZE, irq[SM501], serial_hds[2]); /* onboard CF (True IDE mode, Master only). */ if ((dinfo = drive_get(IF_IDE, 0, 0)) != NULL) mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1, dinfo, NULL); /* NIC: rtl8139 on-board, and 2 slots. */ for (i = 0; i < nb_nics; i++) pci_nic_init_nofail(&nd_table[i], "rtl8139", i==0 ? "2" : NULL); /* Todo: register on board registers */ if (kernel_filename) { int kernel_size; /* initialization which should be done by firmware */ stl_phys(SH7750_BCR1, 1<<3); /* cs3 SDRAM */ stw_phys(SH7750_BCR2, 3<<(3*2)); /* cs3 32bit */ if (kernel_cmdline) { kernel_size = load_image_targphys(kernel_filename, SDRAM_BASE + LINUX_LOAD_OFFSET, SDRAM_SIZE - LINUX_LOAD_OFFSET); env->pc = (SDRAM_BASE + LINUX_LOAD_OFFSET) | 0xa0000000; pstrcpy_targphys("cmdline", SDRAM_BASE + 0x10100, 256, kernel_cmdline); } else { kernel_size = load_image_targphys(kernel_filename, SDRAM_BASE, SDRAM_SIZE); env->pc = SDRAM_BASE | 0xa0000000; /* Start from P2 area */ } if (kernel_size < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } } }
static void r2d_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { CPUState *env; struct SH7750State *s; ram_addr_t sdram_addr; qemu_irq *irq; DriveInfo *dinfo; int i; if (!cpu_model) cpu_model = "SH7751R"; env = cpu_init(cpu_model); if (!env) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } /* Allocate memory space */ sdram_addr = qemu_ram_alloc(NULL, "r2d.sdram", SDRAM_SIZE); cpu_register_physical_memory(SDRAM_BASE, SDRAM_SIZE, sdram_addr); /* Register peripherals */ s = sh7750_init(env); irq = r2d_fpga_init(0x04000000, sh7750_irl(s)); sh_pci_register_bus(r2d_pci_set_irq, r2d_pci_map_irq, irq, 0, 4); sm501_init(0x10000000, SM501_VRAM_SIZE, irq[SM501], serial_hds[2]); /* onboard CF (True IDE mode, Master only). */ dinfo = drive_get(IF_IDE, 0, 0); mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1, dinfo, NULL); /* onboard flash memory */ dinfo = drive_get(IF_PFLASH, 0, 0); pflash_cfi02_register(0x0, qemu_ram_alloc(NULL, "r2d.flash", FLASH_SIZE), dinfo ? dinfo->bdrv : NULL, (16 * 1024), FLASH_SIZE >> 16, 1, 4, 0x0000, 0x0000, 0x0000, 0x0000, 0x555, 0x2aa, 0); /* NIC: rtl8139 on-board, and 2 slots. */ for (i = 0; i < nb_nics; i++) pci_nic_init_nofail(&nd_table[i], "rtl8139", i==0 ? "2" : NULL); /* USB keyboard */ usbdevice_create("keyboard"); /* Todo: register on board registers */ memset(&boot_params, 0, sizeof(boot_params)); if (kernel_filename) { int kernel_size; kernel_size = load_image_targphys(kernel_filename, SDRAM_BASE + LINUX_LOAD_OFFSET, INITRD_LOAD_OFFSET - LINUX_LOAD_OFFSET); if (kernel_size < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } /* initialization which should be done by firmware */ stl_phys(SH7750_BCR1, 1<<3); /* cs3 SDRAM */ stw_phys(SH7750_BCR2, 3<<(3*2)); /* cs3 32bit */ env->pc = (SDRAM_BASE + LINUX_LOAD_OFFSET) | 0xa0000000; /* Start from P2 area */ } if (initrd_filename) { int initrd_size; initrd_size = load_image_targphys(initrd_filename, SDRAM_BASE + INITRD_LOAD_OFFSET, SDRAM_SIZE - INITRD_LOAD_OFFSET); if (initrd_size < 0) { fprintf(stderr, "qemu: could not load initrd '%s'\n", initrd_filename); exit(1); } /* initialization which should be done by firmware */ boot_params.loader_type = 1; boot_params.initrd_start = INITRD_LOAD_OFFSET; boot_params.initrd_size = initrd_size; } if (kernel_cmdline) { strncpy(boot_params.kernel_cmdline, kernel_cmdline, sizeof(boot_params.kernel_cmdline)); } rom_add_blob_fixed("boot_params", &boot_params, sizeof(boot_params), SDRAM_BASE + BOOT_PARAMS_OFFSET); }
static void ppc_heathrow_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; const char *boot_device = machine->boot_order; MemoryRegion *sysmem = get_system_memory(); PowerPCCPU *cpu = NULL; CPUPPCState *env = NULL; char *filename; int linux_boot, i; MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *bios = g_new(MemoryRegion, 1); uint32_t kernel_base, initrd_base, cmdline_base = 0; int32_t kernel_size, initrd_size; PCIBus *pci_bus; OldWorldMacIOState *macio; MACIOIDEState *macio_ide; SysBusDevice *s; DeviceState *dev, *pic_dev; BusState *adb_bus; int bios_size; uint16_t ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; uint64_t tbfreq; linux_boot = (kernel_filename != NULL); /* init CPUs */ for (i = 0; i < smp_cpus; i++) { cpu = POWERPC_CPU(cpu_create(machine->cpu_type)); env = &cpu->env; /* Set time-base frequency to 16.6 Mhz */ cpu_ppc_tb_init(env, TBFREQ); qemu_register_reset(ppc_heathrow_reset, cpu); } /* allocate RAM */ if (ram_size > 2047 * MiB) { error_report("Too much memory for this machine: %" PRId64 " MB, " "maximum 2047 MB", ram_size / MiB); exit(1); } memory_region_allocate_system_memory(ram, NULL, "ppc_heathrow.ram", ram_size); memory_region_add_subregion(sysmem, 0, ram); /* allocate and load BIOS */ memory_region_init_ram(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE, &error_fatal); if (bios_name == NULL) bios_name = PROM_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); memory_region_set_readonly(bios, true); memory_region_add_subregion(sysmem, PROM_ADDR, bios); /* Load OpenBIOS (ELF) */ if (filename) { bios_size = load_elf(filename, NULL, 0, NULL, NULL, NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0); g_free(filename); } else { bios_size = -1; } if (bios_size < 0 || bios_size > BIOS_SIZE) { error_report("could not load PowerPC bios '%s'", bios_name); exit(1); } if (linux_boot) { uint64_t lowaddr = 0; int bswap_needed; #ifdef BSWAP_NEEDED bswap_needed = 1; #else bswap_needed = 0; #endif kernel_base = KERNEL_LOAD_ADDR; kernel_size = load_elf(kernel_filename, NULL, translate_kernel_address, NULL, NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE, 0, 0); if (kernel_size < 0) kernel_size = load_aout(kernel_filename, kernel_base, ram_size - kernel_base, bswap_needed, TARGET_PAGE_SIZE); if (kernel_size < 0) kernel_size = load_image_targphys(kernel_filename, kernel_base, ram_size - kernel_base); if (kernel_size < 0) { error_report("could not load kernel '%s'", kernel_filename); exit(1); } /* load initrd */ if (initrd_filename) { initrd_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP); initrd_size = load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); if (initrd_size < 0) { error_report("could not load initial ram disk '%s'", initrd_filename); exit(1); } cmdline_base = TARGET_PAGE_ALIGN(initrd_base + initrd_size); } else { initrd_base = 0; initrd_size = 0; cmdline_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP); } ppc_boot_device = 'm'; } else { kernel_base = 0; kernel_size = 0; initrd_base = 0; initrd_size = 0; ppc_boot_device = '\0'; for (i = 0; boot_device[i] != '\0'; i++) { /* TOFIX: for now, the second IDE channel is not properly * used by OHW. The Mac floppy disk are not emulated. * For now, OHW cannot boot from the network. */ #if 0 if (boot_device[i] >= 'a' && boot_device[i] <= 'f') { ppc_boot_device = boot_device[i]; break; } #else if (boot_device[i] >= 'c' && boot_device[i] <= 'd') { ppc_boot_device = boot_device[i]; break; } #endif } if (ppc_boot_device == '\0') { error_report("No valid boot device for G3 Beige machine"); exit(1); } } /* XXX: we register only 1 output pin for heathrow PIC */ pic_dev = qdev_create(NULL, TYPE_HEATHROW); qdev_init_nofail(pic_dev); /* Connect the heathrow PIC outputs to the 6xx bus */ for (i = 0; i < smp_cpus; i++) { switch (PPC_INPUT(env)) { case PPC_FLAGS_INPUT_6xx: qdev_connect_gpio_out(pic_dev, 0, ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]); break; default: error_report("Bus model not supported on OldWorld Mac machine"); exit(1); } } /* Timebase Frequency */ if (kvm_enabled()) { tbfreq = kvmppc_get_tbfreq(); } else { tbfreq = TBFREQ; } /* init basic PC hardware */ if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) { error_report("Only 6xx bus is supported on heathrow machine"); exit(1); } /* Grackle PCI host bridge */ dev = qdev_create(NULL, TYPE_GRACKLE_PCI_HOST_BRIDGE); qdev_prop_set_uint32(dev, "ofw-addr", 0x80000000); object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", &error_abort); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); sysbus_mmio_map(s, 0, GRACKLE_BASE); sysbus_mmio_map(s, 1, GRACKLE_BASE + 0x200000); /* PCI hole */ memory_region_add_subregion(get_system_memory(), 0x80000000ULL, sysbus_mmio_get_region(s, 2)); /* Register 2 MB of ISA IO space */ memory_region_add_subregion(get_system_memory(), 0xfe000000, sysbus_mmio_get_region(s, 3)); pci_bus = PCI_HOST_BRIDGE(dev)->bus; pci_vga_init(pci_bus); for (i = 0; i < nb_nics; i++) { pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL); } ide_drive_get(hd, ARRAY_SIZE(hd)); /* MacIO */ macio = OLDWORLD_MACIO(pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO)); dev = DEVICE(macio); qdev_prop_set_uint64(dev, "frequency", tbfreq); object_property_set_link(OBJECT(macio), OBJECT(pic_dev), "pic", &error_abort); qdev_init_nofail(dev); macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), "ide[0]")); macio_ide_init_drives(macio_ide, hd); macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), "ide[1]")); macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]); dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda")); adb_bus = qdev_get_child_bus(dev, "adb.0"); dev = qdev_create(adb_bus, TYPE_ADB_KEYBOARD); qdev_init_nofail(dev); dev = qdev_create(adb_bus, TYPE_ADB_MOUSE); qdev_init_nofail(dev); if (machine_usb(machine)) { pci_create_simple(pci_bus, -1, "pci-ohci"); } if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) graphic_depth = 15; /* No PCI init: the BIOS will do it */ dev = qdev_create(NULL, TYPE_FW_CFG_MEM); fw_cfg = FW_CFG(dev); qdev_prop_set_uint32(dev, "data_width", 1); qdev_prop_set_bit(dev, "dma_enabled", false); object_property_add_child(OBJECT(qdev_get_machine()), TYPE_FW_CFG, OBJECT(fw_cfg), NULL); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); sysbus_mmio_map(s, 0, CFG_ADDR); sysbus_mmio_map(s, 1, CFG_ADDR + 2); fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); if (kernel_cmdline) { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base); pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline); } else { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0); } fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base); fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled()); if (kvm_enabled()) { #ifdef CONFIG_KVM uint8_t *hypercall; hypercall = g_malloc(16); kvmppc_get_hypercall(env, hypercall, 16); fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid()); #endif } fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, tbfreq); /* Mac OS X requires a "known good" clock-frequency value; pass it one. */ fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_CLOCKFREQ, CLOCKFREQ); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_BUSFREQ, BUSFREQ); /* MacOS NDRV VGA driver */ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, NDRV_VGA_FILENAME); if (filename) { gchar *ndrv_file; gsize ndrv_size; if (g_file_get_contents(filename, &ndrv_file, &ndrv_size, NULL)) { fw_cfg_add_file(fw_cfg, "ndrv/qemu_vga.ndrv", ndrv_file, ndrv_size); } g_free(filename); } qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); }
void ppce500_init(QEMUMachineInitArgs *args, PPCE500Params *params) { MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); PCIBus *pci_bus; CPUPPCState *env = NULL; uint64_t elf_entry; uint64_t elf_lowaddr; hwaddr entry=0; hwaddr loadaddr=UIMAGE_LOAD_BASE; target_long kernel_size=0; target_ulong dt_base = 0; target_ulong initrd_base = 0; target_long initrd_size = 0; target_ulong cur_base = 0; int i; unsigned int pci_irq_nrs[4] = {1, 2, 3, 4}; qemu_irq **irqs, *mpic; DeviceState *dev; CPUPPCState *firstenv = NULL; MemoryRegion *ccsr_addr_space; SysBusDevice *s; PPCE500CCSRState *ccsr; /* Setup CPUs */ if (args->cpu_model == NULL) { args->cpu_model = "e500v2_v30"; } irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB); for (i = 0; i < smp_cpus; i++) { PowerPCCPU *cpu; CPUState *cs; qemu_irq *input; cpu = cpu_ppc_init(args->cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to initialize CPU!\n"); exit(1); } env = &cpu->env; cs = CPU(cpu); if (!firstenv) { firstenv = env; } irqs[i] = irqs[0] + (i * OPENPIC_OUTPUT_NB); input = (qemu_irq *)env->irq_inputs; irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT]; irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT]; env->spr[SPR_BOOKE_PIR] = cs->cpu_index = i; env->mpic_iack = MPC8544_CCSRBAR_BASE + MPC8544_MPIC_REGS_OFFSET + 0xa0; ppc_booke_timers_init(cpu, 400000000, PPC_TIMER_E500); /* Register reset handler */ if (!i) { /* Primary CPU */ struct boot_info *boot_info; boot_info = g_malloc0(sizeof(struct boot_info)); qemu_register_reset(ppce500_cpu_reset, cpu); env->load_info = boot_info; } else { /* Secondary CPUs */ qemu_register_reset(ppce500_cpu_reset_sec, cpu); } } env = firstenv; /* Fixup Memory size on a alignment boundary */ ram_size &= ~(RAM_SIZES_ALIGN - 1); args->ram_size = ram_size; /* Register Memory */ memory_region_init_ram(ram, NULL, "mpc8544ds.ram", ram_size); vmstate_register_ram_global(ram); memory_region_add_subregion(address_space_mem, 0, ram); dev = qdev_create(NULL, "e500-ccsr"); object_property_add_child(qdev_get_machine(), "e500-ccsr", OBJECT(dev), NULL); qdev_init_nofail(dev); ccsr = CCSR(dev); ccsr_addr_space = &ccsr->ccsr_space; memory_region_add_subregion(address_space_mem, MPC8544_CCSRBAR_BASE, ccsr_addr_space); mpic = ppce500_init_mpic(params, ccsr_addr_space, irqs); /* Serial */ if (serial_hds[0]) { serial_mm_init(ccsr_addr_space, MPC8544_SERIAL0_REGS_OFFSET, 0, mpic[42], 399193, serial_hds[0], DEVICE_BIG_ENDIAN); } if (serial_hds[1]) { serial_mm_init(ccsr_addr_space, MPC8544_SERIAL1_REGS_OFFSET, 0, mpic[42], 399193, serial_hds[1], DEVICE_BIG_ENDIAN); } /* General Utility device */ dev = qdev_create(NULL, "mpc8544-guts"); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); memory_region_add_subregion(ccsr_addr_space, MPC8544_UTIL_OFFSET, sysbus_mmio_get_region(s, 0)); /* PCI */ dev = qdev_create(NULL, "e500-pcihost"); qdev_prop_set_uint32(dev, "first_slot", params->pci_first_slot); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); sysbus_connect_irq(s, 0, mpic[pci_irq_nrs[0]]); sysbus_connect_irq(s, 1, mpic[pci_irq_nrs[1]]); sysbus_connect_irq(s, 2, mpic[pci_irq_nrs[2]]); sysbus_connect_irq(s, 3, mpic[pci_irq_nrs[3]]); memory_region_add_subregion(ccsr_addr_space, MPC8544_PCI_REGS_OFFSET, sysbus_mmio_get_region(s, 0)); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0"); if (!pci_bus) printf("couldn't create PCI controller!\n"); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, MPC8544_PCI_IO); if (pci_bus) { /* Register network interfaces. */ for (i = 0; i < nb_nics; i++) { pci_nic_init_nofail(&nd_table[i], pci_bus, "virtio", NULL); } } /* Register spinning region */ sysbus_create_simple("e500-spin", MPC8544_SPIN_BASE, NULL); /* Load kernel. */ if (args->kernel_filename) { kernel_size = load_uimage(args->kernel_filename, &entry, &loadaddr, NULL); if (kernel_size < 0) { kernel_size = load_elf(args->kernel_filename, NULL, NULL, &elf_entry, &elf_lowaddr, NULL, 1, ELF_MACHINE, 0); entry = elf_entry; loadaddr = elf_lowaddr; } /* XXX try again as binary */ if (kernel_size < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", args->kernel_filename); exit(1); } cur_base = loadaddr + kernel_size; /* Reserve space for dtb */ dt_base = (cur_base + DTC_LOAD_PAD) & ~DTC_PAD_MASK; cur_base += DTB_MAX_SIZE; } /* Load initrd. */ if (args->initrd_filename) { initrd_base = (cur_base + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK; initrd_size = load_image_targphys(args->initrd_filename, initrd_base, ram_size - initrd_base); if (initrd_size < 0) { fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", args->initrd_filename); exit(1); } cur_base = initrd_base + initrd_size; } /* If we're loading a kernel directly, we must load the device tree too. */ if (args->kernel_filename) { struct boot_info *boot_info; int dt_size; dt_size = ppce500_prep_device_tree(args, params, dt_base, initrd_base, initrd_size); if (dt_size < 0) { fprintf(stderr, "couldn't load device tree\n"); exit(1); } assert(dt_size < DTB_MAX_SIZE); boot_info = env->load_info; boot_info->entry = entry; boot_info->dt_base = dt_base; boot_info->dt_size = dt_size; } if (kvm_enabled()) { kvmppc_init(); } }
/* PC hardware initialisation */ static void pc_init1(MemoryRegion *system_memory, MemoryRegion *system_io, ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, int pci_enabled, int kvmclock_enabled) { int i; ram_addr_t below_4g_mem_size, above_4g_mem_size; PCIBus *pci_bus; ISABus *isa_bus; PCII440FXState *i440fx_state; int piix3_devfn = -1; qemu_irq *cpu_irq; qemu_irq *gsi; qemu_irq *i8259; qemu_irq *cmos_s3; qemu_irq *smi_irq; GSIState *gsi_state; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; BusState *idebus[MAX_IDE_BUS]; ISADevice *rtc_state; ISADevice *floppy; MemoryRegion *ram_memory; MemoryRegion *pci_memory; MemoryRegion *rom_memory; DeviceState *dev; pc_cpus_init(cpu_model); if (kvmclock_enabled) { kvmclock_create(); } if (ram_size >= 0xe0000000 ) { above_4g_mem_size = ram_size - 0xe0000000; below_4g_mem_size = 0xe0000000; } else { above_4g_mem_size = 0; below_4g_mem_size = ram_size; } if (pci_enabled) { pci_memory = g_new(MemoryRegion, 1); memory_region_init(pci_memory, "pci", INT64_MAX); rom_memory = pci_memory; } else { pci_memory = NULL; rom_memory = system_memory; } /* allocate ram and load rom/bios */ if (!xen_enabled()) { pc_memory_init(system_memory, kernel_filename, kernel_cmdline, initrd_filename, below_4g_mem_size, above_4g_mem_size, pci_enabled ? rom_memory : system_memory, &ram_memory); } gsi_state = g_malloc0(sizeof(*gsi_state)); if (kvm_enabled() && kvm_irqchip_in_kernel()) { kvm_piix3_setup_irq_routing(pci_enabled); gsi = qemu_allocate_irqs(kvm_piix3_gsi_handler, gsi_state, GSI_NUM_PINS); } else { gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS); } if (pci_enabled) { pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, &isa_bus, gsi, system_memory, system_io, ram_size, below_4g_mem_size, 0x100000000ULL - below_4g_mem_size, 0x100000000ULL + above_4g_mem_size, (sizeof(target_phys_addr_t) == 4 ? 0 : ((uint64_t)1 << 62)), pci_memory, ram_memory); } else { pci_bus = NULL; i440fx_state = NULL; isa_bus = isa_bus_new(NULL, system_io); no_hpet = 1; } isa_bus_irqs(isa_bus, gsi); if (kvm_enabled() && kvm_irqchip_in_kernel()) { i8259 = kvm_i8259_init(isa_bus); } else if (xen_enabled()) { i8259 = xen_interrupt_controller_init(); } else { cpu_irq = pc_allocate_cpu_irq(); i8259 = i8259_init(isa_bus, cpu_irq[0]); } for (i = 0; i < ISA_NUM_IRQS; i++) { gsi_state->i8259_irq[i] = i8259[i]; } if (pci_enabled) { ioapic_init(gsi_state); } pc_register_ferr_irq(gsi[13]); dev = pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL); if (dev) { qdev_property_add_child(qdev_get_root(), "vga", dev, NULL); } if (xen_enabled()) { pci_create_simple(pci_bus, -1, "xen-platform"); } /* init basic PC hardware */ pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, xen_enabled()); for(i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0)) pc_init_ne2k_isa(isa_bus, nd); else pci_nic_init_nofail(nd, "e1000", NULL); } ide_drive_get(hd, MAX_IDE_BUS); if (pci_enabled) { PCIDevice *dev; if (xen_enabled()) { dev = pci_piix3_xen_ide_init(pci_bus, hd, piix3_devfn + 1); } else { dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1); } idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0"); idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1"); /* FIXME there's some major spaghetti here. Somehow we create the * devices on the PIIX before we actually create it. We create the * PIIX3 deep in the recess of the i440fx creation too and then lose * the DeviceState. * * For now, let's "fix" this by making judicious use of paths. This * is not generally the right way to do this. */ qdev_property_add_child(qdev_resolve_path("/i440fx/piix3", NULL), "rtc", (DeviceState *)rtc_state, NULL); } else { for(i = 0; i < MAX_IDE_BUS; i++) { ISADevice *dev; dev = isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i], hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]); idebus[i] = qdev_get_child_bus(&dev->qdev, "ide.0"); } } audio_init(isa_bus, pci_enabled ? pci_bus : NULL); pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, floppy, idebus[0], idebus[1], rtc_state); if (pci_enabled && usb_enabled) { usb_uhci_piix3_init(pci_bus, piix3_devfn + 2); } if (pci_enabled && acpi_enabled) { i2c_bus *smbus; if (!xen_enabled()) { cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1); } else { cmos_s3 = qemu_allocate_irqs(xen_cmos_set_s3_resume, rtc_state, 1); } smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1); /* TODO: Populate SPD eeprom data. */ smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, gsi[9], *cmos_s3, *smi_irq, kvm_enabled()); smbus_eeprom_init(smbus, 8, NULL, 0); } if (pci_enabled) { pc_pci_device_init(pci_bus); } }
/* PC hardware initialisation */ static void pc_init1(MemoryRegion *system_memory, MemoryRegion *system_io, ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, int pci_enabled, int kvmclock_enabled) { int i; ram_addr_t below_4g_mem_size, above_4g_mem_size; PCIBus *pci_bus; ISABus *isa_bus; PCII440FXState *i440fx_state; int piix3_devfn = -1; qemu_irq *cpu_irq; qemu_irq *gsi; qemu_irq *i8259; qemu_irq *smi_irq; GSIState *gsi_state; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; BusState *idebus[MAX_IDE_BUS]; ISADevice *rtc_state; ISADevice *floppy; MemoryRegion *ram_memory; MemoryRegion *pci_memory; MemoryRegion *rom_memory; void *fw_cfg = NULL; pc_cpus_init(cpu_model); if (kvmclock_enabled) { kvmclock_create(); } if (ram_size >= 0xe0000000 ) { above_4g_mem_size = ram_size - 0xe0000000; below_4g_mem_size = 0xe0000000; } else { above_4g_mem_size = 0; below_4g_mem_size = ram_size; } if (pci_enabled) { pci_memory = g_new(MemoryRegion, 1); memory_region_init(pci_memory, "pci", INT64_MAX); rom_memory = pci_memory; } else { pci_memory = NULL; rom_memory = system_memory; } /* allocate ram and load rom/bios */ if (!xen_enabled()) { fw_cfg = pc_memory_init(system_memory, kernel_filename, kernel_cmdline, initrd_filename, below_4g_mem_size, above_4g_mem_size, pci_enabled ? rom_memory : system_memory, &ram_memory); } gsi_state = g_malloc0(sizeof(*gsi_state)); if (kvm_irqchip_in_kernel()) { kvm_piix3_setup_irq_routing(pci_enabled); gsi = qemu_allocate_irqs(kvm_piix3_gsi_handler, gsi_state, GSI_NUM_PINS); } else { gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS); } if (pci_enabled) { pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, &isa_bus, gsi, system_memory, system_io, ram_size, below_4g_mem_size, 0x100000000ULL - below_4g_mem_size, 0x100000000ULL + above_4g_mem_size, (sizeof(target_phys_addr_t) == 4 ? 0 : ((uint64_t)1 << 62)), pci_memory, ram_memory); } else { pci_bus = NULL; i440fx_state = NULL; isa_bus = isa_bus_new(NULL, system_io); no_hpet = 1; } isa_bus_irqs(isa_bus, gsi); if (kvm_irqchip_in_kernel()) { i8259 = kvm_i8259_init(isa_bus); } else if (xen_enabled()) { i8259 = xen_interrupt_controller_init(); } else { cpu_irq = pc_allocate_cpu_irq(); i8259 = i8259_init(isa_bus, cpu_irq[0]); } for (i = 0; i < ISA_NUM_IRQS; i++) { gsi_state->i8259_irq[i] = i8259[i]; } if (pci_enabled) { ioapic_init(gsi_state); } pc_register_ferr_irq(gsi[13]); pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL); if (xen_enabled()) { pci_create_simple(pci_bus, -1, "xen-platform"); } if (pci_enabled && vmsocket_enabled) pci_vmsocket_init(pci_bus); /* init basic PC hardware */ pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, xen_enabled()); for(i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0)) pc_init_ne2k_isa(isa_bus, nd); else pci_nic_init_nofail(nd, "e1000", NULL); } ide_drive_get(hd, MAX_IDE_BUS); if (pci_enabled) { PCIDevice *dev; if (xen_enabled()) { dev = pci_piix3_xen_ide_init(pci_bus, hd, piix3_devfn + 1); } else { dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1); } idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0"); idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1"); } else { for(i = 0; i < MAX_IDE_BUS; i++) { ISADevice *dev; dev = isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i], hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]); idebus[i] = qdev_get_child_bus(&dev->qdev, "ide.0"); } } audio_init(isa_bus, pci_enabled ? pci_bus : NULL); pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, floppy, idebus[0], idebus[1], rtc_state); if (pci_enabled && usb_enabled) { pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci"); } if (pci_enabled && acpi_enabled) { i2c_bus *smbus; smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1); /* TODO: Populate SPD eeprom data. */ smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, gsi[9], *smi_irq, kvm_enabled(), fw_cfg); smbus_eeprom_init(smbus, 8, NULL, 0); } if (pci_enabled) { pc_pci_device_init(pci_bus); } }
static void sun4uv_init(MemoryRegion *address_space_mem, MachineState *machine, const struct hwdef *hwdef) { SPARCCPU *cpu; Nvram *nvram; unsigned int i; uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry; PCIBus *pci_bus, *pci_bus2, *pci_bus3; ISABus *isa_bus; SysBusDevice *s; qemu_irq *ivec_irqs, *pbm_irqs; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; DriveInfo *fd[MAX_FD]; FWCfgState *fw_cfg; /* init CPUs */ cpu = cpu_devinit(machine->cpu_model, hwdef); /* set up devices */ ram_init(0, machine->ram_size); prom_init(hwdef->prom_addr, bios_name); ivec_irqs = qemu_allocate_irqs(cpu_set_ivec_irq, cpu, IVEC_MAX); pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, ivec_irqs, &pci_bus2, &pci_bus3, &pbm_irqs); pci_vga_init(pci_bus); // XXX Should be pci_bus3 isa_bus = pci_ebus_init(pci_bus, -1, pbm_irqs); i = 0; if (hwdef->console_serial_base) { serial_mm_init(address_space_mem, hwdef->console_serial_base, 0, NULL, 115200, serial_hds[i], DEVICE_BIG_ENDIAN); i++; } serial_hds_isa_init(isa_bus, MAX_SERIAL_PORTS); parallel_hds_isa_init(isa_bus, MAX_PARALLEL_PORTS); for(i = 0; i < nb_nics; i++) pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL); ide_drive_get(hd, ARRAY_SIZE(hd)); pci_cmd646_ide_init(pci_bus, hd, 1); isa_create_simple(isa_bus, "i8042"); for(i = 0; i < MAX_FD; i++) { fd[i] = drive_get(IF_FLOPPY, 0, i); } fdctrl_init_isa(isa_bus, fd); /* Map NVRAM into I/O (ebus) space */ nvram = m48t59_init(NULL, 0, 0, NVRAM_SIZE, 1968, 59); s = SYS_BUS_DEVICE(nvram); memory_region_add_subregion(get_system_io(), 0x2000, sysbus_mmio_get_region(s, 0)); initrd_size = 0; initrd_addr = 0; kernel_size = sun4u_load_kernel(machine->kernel_filename, machine->initrd_filename, ram_size, &initrd_size, &initrd_addr, &kernel_addr, &kernel_entry); sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", machine->ram_size, machine->boot_order, kernel_addr, kernel_size, machine->kernel_cmdline, initrd_addr, initrd_size, /* XXX: need an option to load a NVRAM image */ 0, graphic_width, graphic_height, graphic_depth, (uint8_t *)&nd_table[0].macaddr); fw_cfg = fw_cfg_init_io(BIOS_CFG_IOPORT); fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id); fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_entry); fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); if (machine->kernel_cmdline) { fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(machine->kernel_cmdline) + 1); fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, machine->kernel_cmdline); } else { fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 0); } fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr); fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, machine->boot_order[0]); fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_WIDTH, graphic_width); fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_HEIGHT, graphic_height); fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_DEPTH, graphic_depth); qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); }
/* PowerPC Mac99 hardware initialisation */ static void ppc_core99_init (ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { PowerPCCPU *cpu = NULL; CPUPPCState *env = NULL; char *filename; qemu_irq *pic, **openpic_irqs; MemoryRegion *unin_memory = g_new(MemoryRegion, 1); int linux_boot, i; MemoryRegion *ram = g_new(MemoryRegion, 1), *bios = g_new(MemoryRegion, 1); target_phys_addr_t kernel_base, initrd_base, cmdline_base = 0; long kernel_size, initrd_size; PCIBus *pci_bus; MacIONVRAMState *nvr; int bios_size; MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem, *escc_mem; MemoryRegion *escc_bar = g_new(MemoryRegion, 1); MemoryRegion *ide_mem[3]; int ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; void *dbdma; int machine_arch; linux_boot = (kernel_filename != NULL); /* init CPUs */ if (cpu_model == NULL) #ifdef TARGET_PPC64 cpu_model = "970fx"; #else cpu_model = "G4"; #endif for (i = 0; i < smp_cpus; i++) { cpu = cpu_ppc_init(cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to find PowerPC CPU definition\n"); exit(1); } env = &cpu->env; /* Set time-base frequency to 100 Mhz */ cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL); qemu_register_reset(ppc_core99_reset, cpu); } /* allocate RAM */ memory_region_init_ram(ram, "ppc_core99.ram", ram_size); vmstate_register_ram_global(ram); memory_region_add_subregion(get_system_memory(), 0, ram); /* allocate and load BIOS */ memory_region_init_ram(bios, "ppc_core99.bios", BIOS_SIZE); vmstate_register_ram_global(bios); if (bios_name == NULL) bios_name = PROM_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); memory_region_set_readonly(bios, true); memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios); /* Load OpenBIOS (ELF) */ if (filename) { bios_size = load_elf(filename, NULL, NULL, NULL, NULL, NULL, 1, ELF_MACHINE, 0); g_free(filename); } else { bios_size = -1; } if (bios_size < 0 || bios_size > BIOS_SIZE) { hw_error("qemu: could not load PowerPC bios '%s'\n", bios_name); exit(1); } if (linux_boot) { uint64_t lowaddr = 0; int bswap_needed; #ifdef BSWAP_NEEDED bswap_needed = 1; #else bswap_needed = 0; #endif kernel_base = KERNEL_LOAD_ADDR; kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0); if (kernel_size < 0) kernel_size = load_aout(kernel_filename, kernel_base, ram_size - kernel_base, bswap_needed, TARGET_PAGE_SIZE); if (kernel_size < 0) kernel_size = load_image_targphys(kernel_filename, kernel_base, ram_size - kernel_base); if (kernel_size < 0) { hw_error("qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } /* load initrd */ if (initrd_filename) { initrd_base = round_page(kernel_base + kernel_size + KERNEL_GAP); initrd_size = load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); if (initrd_size < 0) { hw_error("qemu: could not load initial ram disk '%s'\n", initrd_filename); exit(1); } cmdline_base = round_page(initrd_base + initrd_size); } else { initrd_base = 0; initrd_size = 0; cmdline_base = round_page(kernel_base + kernel_size + KERNEL_GAP); } ppc_boot_device = 'm'; } else { kernel_base = 0; kernel_size = 0; initrd_base = 0; initrd_size = 0; ppc_boot_device = '\0'; /* We consider that NewWorld PowerMac never have any floppy drive * For now, OHW cannot boot from the network. */ for (i = 0; boot_device[i] != '\0'; i++) { if (boot_device[i] >= 'c' && boot_device[i] <= 'f') { ppc_boot_device = boot_device[i]; break; } } if (ppc_boot_device == '\0') { fprintf(stderr, "No valid boot device for Mac99 machine\n"); exit(1); } } /* Register 8 MB of ISA IO space */ isa_mmio_init(0xf2000000, 0x00800000); /* UniN init */ memory_region_init_io(unin_memory, &unin_ops, NULL, "unin", 0x1000); memory_region_add_subregion(get_system_memory(), 0xf8000000, unin_memory); openpic_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); openpic_irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB); for (i = 0; i < smp_cpus; i++) { /* Mac99 IRQ connection between OpenPIC outputs pins * and PowerPC input pins */ switch (PPC_INPUT(env)) { case PPC_FLAGS_INPUT_6xx: openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB); openpic_irqs[i][OPENPIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; openpic_irqs[i][OPENPIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; openpic_irqs[i][OPENPIC_OUTPUT_MCK] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_MCP]; /* Not connected ? */ openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL; /* Check this */ openpic_irqs[i][OPENPIC_OUTPUT_RESET] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_HRESET]; break; #if defined(TARGET_PPC64) case PPC_FLAGS_INPUT_970: openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB); openpic_irqs[i][OPENPIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT]; openpic_irqs[i][OPENPIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT]; openpic_irqs[i][OPENPIC_OUTPUT_MCK] = ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_MCP]; /* Not connected ? */ openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL; /* Check this */ openpic_irqs[i][OPENPIC_OUTPUT_RESET] = ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_HRESET]; break; #endif /* defined(TARGET_PPC64) */ default: hw_error("Bus model not supported on mac99 machine\n"); exit(1); } } pic = openpic_init(&pic_mem, smp_cpus, openpic_irqs, NULL); if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) { /* 970 gets a U3 bus */ pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io()); machine_arch = ARCH_MAC99_U3; } else { pci_bus = pci_pmac_init(pic, get_system_memory(), get_system_io()); machine_arch = ARCH_MAC99; } /* init basic PC hardware */ pci_vga_init(pci_bus); escc_mem = escc_init(0, pic[0x25], pic[0x24], serial_hds[0], serial_hds[1], ESCC_CLOCK, 4); memory_region_init_alias(escc_bar, "escc-bar", escc_mem, 0, memory_region_size(escc_mem)); for(i = 0; i < nb_nics; i++) pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL); ide_drive_get(hd, MAX_IDE_BUS); dbdma = DBDMA_init(&dbdma_mem); /* We only emulate 2 out of 3 IDE controllers for now */ ide_mem[0] = NULL; ide_mem[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]); ide_mem[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]); /* cuda also initialize ADB */ if (machine_arch == ARCH_MAC99_U3) { usb_enabled = 1; } cuda_init(&cuda_mem, pic[0x19]); adb_kbd_init(&adb_bus); adb_mouse_init(&adb_bus); macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem, dbdma_mem, cuda_mem, NULL, 3, ide_mem, escc_bar); if (usb_enabled) { pci_create_simple(pci_bus, -1, "pci-ohci"); } /* U3 needs to use USB for input because Linux doesn't support via-cuda on PPC64 */ if (machine_arch == ARCH_MAC99_U3) { usbdevice_create("keyboard"); usbdevice_create("mouse"); } if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) graphic_depth = 15; /* The NewWorld NVRAM is not located in the MacIO device */ nvr = macio_nvram_init(0x2000, 1); pmac_format_nvram_partition(nvr, 0x2000); macio_nvram_setup_bar(nvr, get_system_memory(), 0xFFF04000); /* No PCI init: the BIOS will do it */ fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2); fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); if (kernel_cmdline) { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base); pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline); } else { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0); } fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base); fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled()); if (kvm_enabled()) { #ifdef CONFIG_KVM uint8_t *hypercall; fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq()); hypercall = g_malloc(16); kvmppc_get_hypercall(env, hypercall, 16); fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid()); #endif } else { fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec()); } qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); }
/* PowerPC Mac99 hardware initialisation */ static void ppc_core99_init (ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { CPUState *env = NULL, *envs[MAX_CPUS]; char *filename; qemu_irq *pic, **openpic_irqs; int unin_memory; int linux_boot, i; ram_addr_t ram_offset, bios_offset, vga_bios_offset; uint32_t kernel_base, kernel_size, initrd_base, initrd_size; PCIBus *pci_bus; MacIONVRAMState *nvr; int nvram_mem_index; int vga_bios_size, bios_size; int pic_mem_index, dbdma_mem_index, cuda_mem_index, escc_mem_index; int ide_mem_index[3]; int ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; void *dbdma; uint8_t *vga_bios_ptr; int machine_arch; linux_boot = (kernel_filename != NULL); /* init CPUs */ if (cpu_model == NULL) #ifdef TARGET_PPC64 cpu_model = "970fx"; #else cpu_model = "G4"; #endif for (i = 0; i < smp_cpus; i++) { env = cpu_init(cpu_model); if (!env) { fprintf(stderr, "Unable to find PowerPC CPU definition\n"); exit(1); } /* Set time-base frequency to 100 Mhz */ cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL); #if 0 env->osi_call = vga_osi_call; #endif qemu_register_reset((QEMUResetHandler*)&cpu_reset, env); envs[i] = env; } /* allocate RAM */ ram_offset = qemu_ram_alloc(NULL, "ppc_core99.ram", ram_size); cpu_register_physical_memory(0, ram_size, ram_offset); /* allocate and load BIOS */ bios_offset = qemu_ram_alloc(NULL, "ppc_core99.bios", BIOS_SIZE); if (bios_name == NULL) bios_name = PROM_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); cpu_register_physical_memory(PROM_ADDR, BIOS_SIZE, bios_offset | IO_MEM_ROM); /* Load OpenBIOS (ELF) */ if (filename) { bios_size = load_elf(filename, NULL, NULL, NULL, NULL, NULL, 1, ELF_MACHINE, 0); qemu_free(filename); } else { bios_size = -1; } if (bios_size < 0 || bios_size > BIOS_SIZE) { hw_error("qemu: could not load PowerPC bios '%s'\n", bios_name); exit(1); } /* allocate and load VGA BIOS */ vga_bios_offset = qemu_ram_alloc(NULL, "ppc_core99.vbios", VGA_BIOS_SIZE); vga_bios_ptr = qemu_get_ram_ptr(vga_bios_offset); filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, VGABIOS_FILENAME); if (filename) { vga_bios_size = load_image(filename, vga_bios_ptr + 8); qemu_free(filename); } else { vga_bios_size = -1; } if (vga_bios_size < 0) { /* if no bios is present, we can still work */ fprintf(stderr, "qemu: warning: could not load VGA bios '%s'\n", VGABIOS_FILENAME); vga_bios_size = 0; } else { /* set a specific header (XXX: find real Apple format for NDRV drivers) */ vga_bios_ptr[0] = 'N'; vga_bios_ptr[1] = 'D'; vga_bios_ptr[2] = 'R'; vga_bios_ptr[3] = 'V'; cpu_to_be32w((uint32_t *)(vga_bios_ptr + 4), vga_bios_size); vga_bios_size += 8; /* Round to page boundary */ vga_bios_size = (vga_bios_size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; } if (linux_boot) { uint64_t lowaddr = 0; int bswap_needed; #ifdef BSWAP_NEEDED bswap_needed = 1; #else bswap_needed = 0; #endif kernel_base = KERNEL_LOAD_ADDR; kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0); if (kernel_size < 0) kernel_size = load_aout(kernel_filename, kernel_base, ram_size - kernel_base, bswap_needed, TARGET_PAGE_SIZE); if (kernel_size < 0) kernel_size = load_image_targphys(kernel_filename, kernel_base, ram_size - kernel_base); if (kernel_size < 0) { hw_error("qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } /* load initrd */ if (initrd_filename) { initrd_base = INITRD_LOAD_ADDR; initrd_size = load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); if (initrd_size < 0) { hw_error("qemu: could not load initial ram disk '%s'\n", initrd_filename); exit(1); } } else { initrd_base = 0; initrd_size = 0; } ppc_boot_device = 'm'; } else { kernel_base = 0; kernel_size = 0; initrd_base = 0; initrd_size = 0; ppc_boot_device = '\0'; /* We consider that NewWorld PowerMac never have any floppy drive * For now, OHW cannot boot from the network. */ for (i = 0; boot_device[i] != '\0'; i++) { if (boot_device[i] >= 'c' && boot_device[i] <= 'f') { ppc_boot_device = boot_device[i]; break; } } if (ppc_boot_device == '\0') { fprintf(stderr, "No valid boot device for Mac99 machine\n"); exit(1); } } isa_mem_base = 0x80000000; /* Register 8 MB of ISA IO space */ isa_mmio_init(0xf2000000, 0x00800000, 1); /* UniN init */ unin_memory = cpu_register_io_memory(unin_read, unin_write, NULL); cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory); openpic_irqs = qemu_mallocz(smp_cpus * sizeof(qemu_irq *)); openpic_irqs[0] = qemu_mallocz(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB); for (i = 0; i < smp_cpus; i++) { /* Mac99 IRQ connection between OpenPIC outputs pins * and PowerPC input pins */ switch (PPC_INPUT(env)) { case PPC_FLAGS_INPUT_6xx: openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB); openpic_irqs[i][OPENPIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; openpic_irqs[i][OPENPIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; openpic_irqs[i][OPENPIC_OUTPUT_MCK] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_MCP]; /* Not connected ? */ openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL; /* Check this */ openpic_irqs[i][OPENPIC_OUTPUT_RESET] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_HRESET]; break; #if defined(TARGET_PPC64) case PPC_FLAGS_INPUT_970: openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB); openpic_irqs[i][OPENPIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT]; openpic_irqs[i][OPENPIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT]; openpic_irqs[i][OPENPIC_OUTPUT_MCK] = ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_MCP]; /* Not connected ? */ openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL; /* Check this */ openpic_irqs[i][OPENPIC_OUTPUT_RESET] = ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_HRESET]; break; #endif /* defined(TARGET_PPC64) */ default: hw_error("Bus model not supported on mac99 machine\n"); exit(1); } } pic = openpic_init(NULL, &pic_mem_index, smp_cpus, openpic_irqs, NULL); if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) { /* 970 gets a U3 bus */ pci_bus = pci_pmac_u3_init(pic); machine_arch = ARCH_MAC99_U3; } else { pci_bus = pci_pmac_init(pic); machine_arch = ARCH_MAC99; } /* init basic PC hardware */ pci_vga_init(pci_bus, vga_bios_offset, vga_bios_size); escc_mem_index = escc_init(0x80013000, pic[0x25], pic[0x24], serial_hds[0], serial_hds[1], ESCC_CLOCK, 4); for(i = 0; i < nb_nics; i++) pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL); if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { fprintf(stderr, "qemu: too many IDE bus\n"); exit(1); } dbdma = DBDMA_init(&dbdma_mem_index); /* We only emulate 2 out of 3 IDE controllers for now */ ide_mem_index[0] = -1; hd[0] = drive_get(IF_IDE, 0, 0); hd[1] = drive_get(IF_IDE, 0, 1); ide_mem_index[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]); hd[0] = drive_get(IF_IDE, 1, 0); hd[1] = drive_get(IF_IDE, 1, 1); ide_mem_index[2] = pmac_ide_init(hd, pic[0x0e], dbdma, 0x1a, pic[0x02]); /* cuda also initialize ADB */ if (machine_arch == ARCH_MAC99_U3) { usb_enabled = 1; } cuda_init(&cuda_mem_index, pic[0x19]); adb_kbd_init(&adb_bus); adb_mouse_init(&adb_bus); macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem_index, dbdma_mem_index, cuda_mem_index, NULL, 3, ide_mem_index, escc_mem_index); if (usb_enabled) { usb_ohci_init_pci(pci_bus, -1); } /* U3 needs to use USB for input because Linux doesn't support via-cuda on PPC64 */ if (machine_arch == ARCH_MAC99_U3) { usbdevice_create("keyboard"); usbdevice_create("mouse"); } if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) graphic_depth = 15; /* The NewWorld NVRAM is not located in the MacIO device */ nvr = macio_nvram_init(&nvram_mem_index, 0x2000, 1); pmac_format_nvram_partition(nvr, 0x2000); macio_nvram_map(nvr, 0xFFF04000); /* No PCI init: the BIOS will do it */ fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2); fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); if (kernel_cmdline) { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR); pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline); } else { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0); } fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base); fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled()); if (kvm_enabled()) { #ifdef CONFIG_KVM uint8_t *hypercall; fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq()); hypercall = qemu_malloc(16); kvmppc_get_hypercall(env, hypercall, 16); fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid()); #endif } else { fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec()); } qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); }
/* PowerPC Mac99 hardware initialisation */ static void ppc_core99_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; const char *boot_device = machine->boot_order; PowerPCCPU *cpu = NULL; CPUPPCState *env = NULL; char *filename; qemu_irq *pic, **openpic_irqs; MemoryRegion *isa = g_new(MemoryRegion, 1); MemoryRegion *unin_memory = g_new(MemoryRegion, 1); MemoryRegion *unin2_memory = g_new(MemoryRegion, 1); int linux_boot, i, j, k; MemoryRegion *ram = g_new(MemoryRegion, 1), *bios = g_new(MemoryRegion, 1); hwaddr kernel_base, initrd_base, cmdline_base = 0; long kernel_size, initrd_size; PCIBus *pci_bus; PCIDevice *macio; MACIOIDEState *macio_ide; BusState *adb_bus; MacIONVRAMState *nvr; int bios_size; MemoryRegion *pic_mem, *escc_mem; MemoryRegion *escc_bar = g_new(MemoryRegion, 1); int ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; int machine_arch; SysBusDevice *s; DeviceState *dev; int *token = g_new(int, 1); hwaddr nvram_addr = 0xFFF04000; uint64_t tbfreq; linux_boot = (kernel_filename != NULL); /* init CPUs */ if (machine->cpu_model == NULL) { #ifdef TARGET_PPC64 machine->cpu_model = "970fx"; #else machine->cpu_model = "G4"; #endif } for (i = 0; i < smp_cpus; i++) { cpu = cpu_ppc_init(machine->cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to find PowerPC CPU definition\n"); exit(1); } env = &cpu->env; /* Set time-base frequency to 100 Mhz */ cpu_ppc_tb_init(env, TBFREQ); qemu_register_reset(ppc_core99_reset, cpu); } /* allocate RAM */ memory_region_allocate_system_memory(ram, NULL, "ppc_core99.ram", ram_size); memory_region_add_subregion(get_system_memory(), 0, ram); /* allocate and load BIOS */ memory_region_init_ram(bios, NULL, "ppc_core99.bios", BIOS_SIZE, &error_fatal); vmstate_register_ram_global(bios); if (bios_name == NULL) bios_name = PROM_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); memory_region_set_readonly(bios, true); memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios); /* Load OpenBIOS (ELF) */ if (filename) { bios_size = load_elf(filename, NULL, NULL, NULL, NULL, NULL, 1, PPC_ELF_MACHINE, 0); g_free(filename); } else { bios_size = -1; } if (bios_size < 0 || bios_size > BIOS_SIZE) { error_report("could not load PowerPC bios '%s'", bios_name); exit(1); } if (linux_boot) { uint64_t lowaddr = 0; int bswap_needed; #ifdef BSWAP_NEEDED bswap_needed = 1; #else bswap_needed = 0; #endif kernel_base = KERNEL_LOAD_ADDR; kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE, 0); if (kernel_size < 0) kernel_size = load_aout(kernel_filename, kernel_base, ram_size - kernel_base, bswap_needed, TARGET_PAGE_SIZE); if (kernel_size < 0) kernel_size = load_image_targphys(kernel_filename, kernel_base, ram_size - kernel_base); if (kernel_size < 0) { error_report("could not load kernel '%s'", kernel_filename); exit(1); } /* load initrd */ if (initrd_filename) { initrd_base = round_page(kernel_base + kernel_size + KERNEL_GAP); initrd_size = load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); if (initrd_size < 0) { error_report("could not load initial ram disk '%s'", initrd_filename); exit(1); } cmdline_base = round_page(initrd_base + initrd_size); } else { initrd_base = 0; initrd_size = 0; cmdline_base = round_page(kernel_base + kernel_size + KERNEL_GAP); } ppc_boot_device = 'm'; } else { kernel_base = 0; kernel_size = 0; initrd_base = 0; initrd_size = 0; ppc_boot_device = '\0'; /* We consider that NewWorld PowerMac never have any floppy drive * For now, OHW cannot boot from the network. */ for (i = 0; boot_device[i] != '\0'; i++) { if (boot_device[i] >= 'c' && boot_device[i] <= 'f') { ppc_boot_device = boot_device[i]; break; } } if (ppc_boot_device == '\0') { fprintf(stderr, "No valid boot device for Mac99 machine\n"); exit(1); } } /* Register 8 MB of ISA IO space */ memory_region_init_alias(isa, NULL, "isa_mmio", get_system_io(), 0, 0x00800000); memory_region_add_subregion(get_system_memory(), 0xf2000000, isa); /* UniN init: XXX should be a real device */ memory_region_init_io(unin_memory, NULL, &unin_ops, token, "unin", 0x1000); memory_region_add_subregion(get_system_memory(), 0xf8000000, unin_memory); memory_region_init_io(unin2_memory, NULL, &unin_ops, token, "unin", 0x1000); memory_region_add_subregion(get_system_memory(), 0xf3000000, unin2_memory); openpic_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); openpic_irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB); for (i = 0; i < smp_cpus; i++) { /* Mac99 IRQ connection between OpenPIC outputs pins * and PowerPC input pins */ switch (PPC_INPUT(env)) { case PPC_FLAGS_INPUT_6xx: openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB); openpic_irqs[i][OPENPIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; openpic_irqs[i][OPENPIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; openpic_irqs[i][OPENPIC_OUTPUT_MCK] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_MCP]; /* Not connected ? */ openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL; /* Check this */ openpic_irqs[i][OPENPIC_OUTPUT_RESET] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_HRESET]; break; #if defined(TARGET_PPC64) case PPC_FLAGS_INPUT_970: openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB); openpic_irqs[i][OPENPIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT]; openpic_irqs[i][OPENPIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT]; openpic_irqs[i][OPENPIC_OUTPUT_MCK] = ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_MCP]; /* Not connected ? */ openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL; /* Check this */ openpic_irqs[i][OPENPIC_OUTPUT_RESET] = ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_HRESET]; break; #endif /* defined(TARGET_PPC64) */ default: error_report("Bus model not supported on mac99 machine"); exit(1); } } pic = g_new0(qemu_irq, 64); dev = qdev_create(NULL, TYPE_OPENPIC); qdev_prop_set_uint32(dev, "model", OPENPIC_MODEL_RAVEN); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); pic_mem = s->mmio[0].memory; k = 0; for (i = 0; i < smp_cpus; i++) { for (j = 0; j < OPENPIC_OUTPUT_NB; j++) { sysbus_connect_irq(s, k++, openpic_irqs[i][j]); } } for (i = 0; i < 64; i++) { pic[i] = qdev_get_gpio_in(dev, i); } if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) { /* 970 gets a U3 bus */ pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io()); machine_arch = ARCH_MAC99_U3; } else { pci_bus = pci_pmac_init(pic, get_system_memory(), get_system_io()); machine_arch = ARCH_MAC99; } machine->usb |= defaults_enabled() && !machine->usb_disabled; /* Timebase Frequency */ if (kvm_enabled()) { tbfreq = kvmppc_get_tbfreq(); } else { tbfreq = TBFREQ; } /* init basic PC hardware */ escc_mem = escc_init(0, pic[0x25], pic[0x24], serial_hds[0], serial_hds[1], ESCC_CLOCK, 4); memory_region_init_alias(escc_bar, NULL, "escc-bar", escc_mem, 0, memory_region_size(escc_mem)); macio = pci_create(pci_bus, -1, TYPE_NEWWORLD_MACIO); dev = DEVICE(macio); qdev_connect_gpio_out(dev, 0, pic[0x19]); /* CUDA */ qdev_connect_gpio_out(dev, 1, pic[0x0d]); /* IDE */ qdev_connect_gpio_out(dev, 2, pic[0x02]); /* IDE DMA */ qdev_connect_gpio_out(dev, 3, pic[0x0e]); /* IDE */ qdev_connect_gpio_out(dev, 4, pic[0x03]); /* IDE DMA */ qdev_prop_set_uint64(dev, "frequency", tbfreq); macio_init(macio, pic_mem, escc_bar); /* We only emulate 2 out of 3 IDE controllers for now */ ide_drive_get(hd, ARRAY_SIZE(hd)); macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), "ide[0]")); macio_ide_init_drives(macio_ide, hd); macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), "ide[1]")); macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]); dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda")); adb_bus = qdev_get_child_bus(dev, "adb.0"); dev = qdev_create(adb_bus, TYPE_ADB_KEYBOARD); qdev_init_nofail(dev); dev = qdev_create(adb_bus, TYPE_ADB_MOUSE); qdev_init_nofail(dev); if (machine->usb) { pci_create_simple(pci_bus, -1, "pci-ohci"); /* U3 needs to use USB for input because Linux doesn't support via-cuda on PPC64 */ if (machine_arch == ARCH_MAC99_U3) { USBBus *usb_bus = usb_bus_find(-1); usb_create_simple(usb_bus, "usb-kbd"); usb_create_simple(usb_bus, "usb-mouse"); } } pci_vga_init(pci_bus); if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) { graphic_depth = 15; } for (i = 0; i < nb_nics; i++) { pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL); } /* The NewWorld NVRAM is not located in the MacIO device */ #ifdef CONFIG_KVM if (kvm_enabled() && getpagesize() > 4096) { /* We can't combine read-write and read-only in a single page, so move the NVRAM out of ROM again for KVM */ nvram_addr = 0xFFE00000; } #endif dev = qdev_create(NULL, TYPE_MACIO_NVRAM); qdev_prop_set_uint32(dev, "size", 0x2000); qdev_prop_set_uint32(dev, "it_shift", 1); qdev_init_nofail(dev); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, nvram_addr); nvr = MACIO_NVRAM(dev); pmac_format_nvram_partition(nvr, 0x2000); /* No PCI init: the BIOS will do it */ fw_cfg = fw_cfg_init_mem(CFG_ADDR, CFG_ADDR + 2); fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); if (kernel_cmdline) { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base); pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline); } else { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0); } fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base); fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled()); if (kvm_enabled()) { #ifdef CONFIG_KVM uint8_t *hypercall; hypercall = g_malloc(16); kvmppc_get_hypercall(env, hypercall, 16); fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid()); #endif } fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, tbfreq); /* Mac OS X requires a "known good" clock-frequency value; pass it one. */ fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_CLOCKFREQ, CLOCKFREQ); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_BUSFREQ, BUSFREQ); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_NVRAM_ADDR, nvram_addr); qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); }
static void bamboo_init(QEMUMachineInitArgs *args) { ram_addr_t ram_size = args->ram_size; const char *cpu_model = args->cpu_model; const char *kernel_filename = args->kernel_filename; const char *kernel_cmdline = args->kernel_cmdline; const char *initrd_filename = args->initrd_filename; unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 }; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *isa = g_new(MemoryRegion, 1); MemoryRegion *ram_memories = g_malloc(PPC440EP_SDRAM_NR_BANKS * sizeof(*ram_memories)); hwaddr ram_bases[PPC440EP_SDRAM_NR_BANKS]; hwaddr ram_sizes[PPC440EP_SDRAM_NR_BANKS]; qemu_irq *pic; qemu_irq *irqs; PCIBus *pcibus; PowerPCCPU *cpu; CPUPPCState *env; uint64_t elf_entry; uint64_t elf_lowaddr; hwaddr loadaddr = 0; target_long initrd_size = 0; DeviceState *dev; int success; int i; /* Setup CPU. */ if (cpu_model == NULL) { cpu_model = "440EP"; } cpu = cpu_ppc_init(cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to initialize CPU!\n"); exit(1); } env = &cpu->env; qemu_register_reset(main_cpu_reset, cpu); ppc_booke_timers_init(cpu, 400000000, 0); ppc_dcr_init(env, NULL, NULL); /* interrupt controller */ irqs = g_malloc0(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB); irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT]; irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT]; pic = ppcuic_init(env, irqs, 0x0C0, 0, 1); /* SDRAM controller */ memset(ram_bases, 0, sizeof(ram_bases)); memset(ram_sizes, 0, sizeof(ram_sizes)); ram_size = ppc4xx_sdram_adjust(ram_size, PPC440EP_SDRAM_NR_BANKS, ram_memories, ram_bases, ram_sizes, ppc440ep_sdram_bank_sizes); /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */ ppc4xx_sdram_init(env, pic[14], PPC440EP_SDRAM_NR_BANKS, ram_memories, ram_bases, ram_sizes, 1); /* PCI */ dev = sysbus_create_varargs(TYPE_PPC4xx_PCI_HOST_BRIDGE, PPC440EP_PCI_CONFIG, pic[pci_irq_nrs[0]], pic[pci_irq_nrs[1]], pic[pci_irq_nrs[2]], pic[pci_irq_nrs[3]], NULL); pcibus = (PCIBus *)qdev_get_child_bus(dev, "pci.0"); if (!pcibus) { fprintf(stderr, "couldn't create PCI controller!\n"); exit(1); } memory_region_init_alias(isa, NULL, "isa_mmio", get_system_io(), 0, PPC440EP_PCI_IOLEN); memory_region_add_subregion(get_system_memory(), PPC440EP_PCI_IO, isa); if (serial_hds[0] != NULL) { serial_mm_init(address_space_mem, 0xef600300, 0, pic[0], PPC_SERIAL_MM_BAUDBASE, serial_hds[0], DEVICE_BIG_ENDIAN); } if (serial_hds[1] != NULL) { serial_mm_init(address_space_mem, 0xef600400, 0, pic[1], PPC_SERIAL_MM_BAUDBASE, serial_hds[1], DEVICE_BIG_ENDIAN); } if (pcibus) { /* Register network interfaces. */ for (i = 0; i < nb_nics; i++) { /* There are no PCI NICs on the Bamboo board, but there are * PCI slots, so we can pick whatever default model we want. */ pci_nic_init_nofail(&nd_table[i], pcibus, "e1000", NULL); } } /* Load kernel. */ if (kernel_filename) { success = load_uimage(kernel_filename, &entry, &loadaddr, NULL); if (success < 0) { success = load_elf(kernel_filename, NULL, NULL, &elf_entry, &elf_lowaddr, NULL, 1, ELF_MACHINE, 0); entry = elf_entry; loadaddr = elf_lowaddr; } /* XXX try again as binary */ if (success < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } } /* Load initrd. */ if (initrd_filename) { initrd_size = load_image_targphys(initrd_filename, RAMDISK_ADDR, ram_size - RAMDISK_ADDR); if (initrd_size < 0) { fprintf(stderr, "qemu: could not load ram disk '%s' at %x\n", initrd_filename, RAMDISK_ADDR); exit(1); } } /* If we're loading a kernel directly, we must load the device tree too. */ if (kernel_filename) { if (bamboo_load_device_tree(FDT_ADDR, ram_size, RAMDISK_ADDR, initrd_size, kernel_cmdline) < 0) { fprintf(stderr, "couldn't load device tree\n"); exit(1); } } if (kvm_enabled()) kvmppc_init(); }
static void sun4uv_init(MemoryRegion *address_space_mem, ram_addr_t RAM_size, const char *boot_devices, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, const struct hwdef *hwdef) { SPARCCPU *cpu; M48t59State *nvram; unsigned int i; uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry; PCIBus *pci_bus, *pci_bus2, *pci_bus3; ISABus *isa_bus; qemu_irq *ivec_irqs, *pbm_irqs; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; DriveInfo *fd[MAX_FD]; void *fw_cfg; /* init CPUs */ cpu = cpu_devinit(cpu_model, hwdef); /* set up devices */ ram_init(0, RAM_size); prom_init(hwdef->prom_addr, bios_name); ivec_irqs = qemu_allocate_irqs(cpu_set_ivec_irq, cpu, IVEC_MAX); pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, ivec_irqs, &pci_bus2, &pci_bus3, &pbm_irqs); pci_vga_init(pci_bus); // XXX Should be pci_bus3 isa_bus = pci_ebus_init(pci_bus, -1, pbm_irqs); i = 0; if (hwdef->console_serial_base) { serial_mm_init(address_space_mem, hwdef->console_serial_base, 0, NULL, 115200, serial_hds[i], DEVICE_BIG_ENDIAN); i++; } for(; i < MAX_SERIAL_PORTS; i++) { if (serial_hds[i]) { serial_isa_init(isa_bus, i, serial_hds[i]); } } for(i = 0; i < MAX_PARALLEL_PORTS; i++) { if (parallel_hds[i]) { parallel_init(isa_bus, i, parallel_hds[i]); } } for(i = 0; i < nb_nics; i++) pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL); ide_drive_get(hd, MAX_IDE_BUS); pci_cmd646_ide_init(pci_bus, hd, 1); isa_create_simple(isa_bus, "i8042"); for(i = 0; i < MAX_FD; i++) { fd[i] = drive_get(IF_FLOPPY, 0, i); } fdctrl_init_isa(isa_bus, fd); nvram = m48t59_init_isa(isa_bus, 0x0074, NVRAM_SIZE, 59); initrd_size = 0; initrd_addr = 0; kernel_size = sun4u_load_kernel(kernel_filename, initrd_filename, ram_size, &initrd_size, &initrd_addr, &kernel_addr, &kernel_entry); sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", RAM_size, boot_devices, kernel_addr, kernel_size, kernel_cmdline, initrd_addr, initrd_size, /* XXX: need an option to load a NVRAM image */ 0, graphic_width, graphic_height, graphic_depth, (uint8_t *)&nd_table[0].macaddr); fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0); fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id); fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_entry); fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); if (kernel_cmdline) { fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(kernel_cmdline) + 1); fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline); } else { fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 0); } fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr); fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_devices[0]); fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_WIDTH, graphic_width); fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_HEIGHT, graphic_height); fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_DEPTH, graphic_depth); qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); }
static void ppc_heathrow_init (ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { CPUState *env = NULL; char *filename; qemu_irq *pic, **heathrow_irqs; int linux_boot, i; ram_addr_t ram_offset, bios_offset; uint32_t kernel_base, initrd_base, cmdline_base = 0; int32_t kernel_size, initrd_size; PCIBus *pci_bus; MacIONVRAMState *nvr; int bios_size; int pic_mem_index, nvram_mem_index, dbdma_mem_index, cuda_mem_index; int escc_mem_index, ide_mem_index[2]; uint16_t ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; void *dbdma; linux_boot = (kernel_filename != NULL); /* init CPUs */ if (cpu_model == NULL) cpu_model = "G3"; for (i = 0; i < smp_cpus; i++) { env = cpu_init(cpu_model); if (!env) { fprintf(stderr, "Unable to find PowerPC CPU definition\n"); exit(1); } /* Set time-base frequency to 16.6 Mhz */ cpu_ppc_tb_init(env, 16600000UL); qemu_register_reset((QEMUResetHandler*)&cpu_reset, env); } /* allocate RAM */ if (ram_size > (2047 << 20)) { fprintf(stderr, "qemu: Too much memory for this machine: %d MB, maximum 2047 MB\n", ((unsigned int)ram_size / (1 << 20))); exit(1); } ram_offset = qemu_ram_alloc(NULL, "ppc_heathrow.ram", ram_size); cpu_register_physical_memory(0, ram_size, ram_offset); /* allocate and load BIOS */ bios_offset = qemu_ram_alloc(NULL, "ppc_heathrow.bios", BIOS_SIZE); if (bios_name == NULL) bios_name = PROM_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); cpu_register_physical_memory(PROM_ADDR, BIOS_SIZE, bios_offset | IO_MEM_ROM); /* Load OpenBIOS (ELF) */ if (filename) { bios_size = load_elf(filename, 0, NULL, NULL, NULL, NULL, 1, ELF_MACHINE, 0); qemu_free(filename); } else { bios_size = -1; } if (bios_size < 0 || bios_size > BIOS_SIZE) { hw_error("qemu: could not load PowerPC bios '%s'\n", bios_name); exit(1); } if (linux_boot) { uint64_t lowaddr = 0; int bswap_needed; #ifdef BSWAP_NEEDED bswap_needed = 1; #else bswap_needed = 0; #endif kernel_base = KERNEL_LOAD_ADDR; kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0); if (kernel_size < 0) kernel_size = load_aout(kernel_filename, kernel_base, ram_size - kernel_base, bswap_needed, TARGET_PAGE_SIZE); if (kernel_size < 0) kernel_size = load_image_targphys(kernel_filename, kernel_base, ram_size - kernel_base); if (kernel_size < 0) { hw_error("qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } /* load initrd */ if (initrd_filename) { initrd_base = round_page(kernel_base + kernel_size + KERNEL_GAP); initrd_size = load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); if (initrd_size < 0) { hw_error("qemu: could not load initial ram disk '%s'\n", initrd_filename); exit(1); } cmdline_base = round_page(initrd_base + initrd_size); } else { initrd_base = 0; initrd_size = 0; cmdline_base = round_page(kernel_base + kernel_size + KERNEL_GAP); } ppc_boot_device = 'm'; } else { kernel_base = 0; kernel_size = 0; initrd_base = 0; initrd_size = 0; ppc_boot_device = '\0'; for (i = 0; boot_device[i] != '\0'; i++) { /* TOFIX: for now, the second IDE channel is not properly * used by OHW. The Mac floppy disk are not emulated. * For now, OHW cannot boot from the network. */ #if 0 if (boot_device[i] >= 'a' && boot_device[i] <= 'f') { ppc_boot_device = boot_device[i]; break; } #else if (boot_device[i] >= 'c' && boot_device[i] <= 'd') { ppc_boot_device = boot_device[i]; break; } #endif } if (ppc_boot_device == '\0') { fprintf(stderr, "No valid boot device for G3 Beige machine\n"); exit(1); } } isa_mem_base = 0x80000000; /* Register 2 MB of ISA IO space */ isa_mmio_init(0xfe000000, 0x00200000); /* XXX: we register only 1 output pin for heathrow PIC */ heathrow_irqs = qemu_mallocz(smp_cpus * sizeof(qemu_irq *)); heathrow_irqs[0] = qemu_mallocz(smp_cpus * sizeof(qemu_irq) * 1); /* Connect the heathrow PIC outputs to the 6xx bus */ for (i = 0; i < smp_cpus; i++) { switch (PPC_INPUT(env)) { case PPC_FLAGS_INPUT_6xx: heathrow_irqs[i] = heathrow_irqs[0] + (i * 1); heathrow_irqs[i][0] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; break; default: hw_error("Bus model not supported on OldWorld Mac machine\n"); } } /* init basic PC hardware */ if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) { hw_error("Only 6xx bus is supported on heathrow machine\n"); } pic = heathrow_pic_init(&pic_mem_index, 1, heathrow_irqs); pci_bus = pci_grackle_init(0xfec00000, pic); pci_vga_init(pci_bus); escc_mem_index = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0], serial_hds[1], ESCC_CLOCK, 4); for(i = 0; i < nb_nics; i++) pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL); ide_drive_get(hd, MAX_IDE_BUS); /* First IDE channel is a MAC IDE on the MacIO bus */ dbdma = DBDMA_init(&dbdma_mem_index); ide_mem_index[0] = -1; ide_mem_index[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]); /* Second IDE channel is a CMD646 on the PCI bus */ hd[0] = hd[MAX_IDE_DEVS]; hd[1] = hd[MAX_IDE_DEVS + 1]; hd[3] = hd[2] = NULL; pci_cmd646_ide_init(pci_bus, hd, 0); /* cuda also initialize ADB */ cuda_init(&cuda_mem_index, pic[0x12]); adb_kbd_init(&adb_bus); adb_mouse_init(&adb_bus); nvr = macio_nvram_init(&nvram_mem_index, 0x2000, 4); pmac_format_nvram_partition(nvr, 0x2000); macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem_index, dbdma_mem_index, cuda_mem_index, nvr, 2, ide_mem_index, escc_mem_index); if (usb_enabled) { usb_ohci_init_pci(pci_bus, -1); } if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) graphic_depth = 15; /* No PCI init: the BIOS will do it */ fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2); fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); if (kernel_cmdline) { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base); pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline); } else { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0); } fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base); fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled()); if (kvm_enabled()) { #ifdef CONFIG_KVM uint8_t *hypercall; fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq()); hypercall = qemu_malloc(16); kvmppc_get_hypercall(env, hypercall, 16); fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid()); #endif } else { fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec()); } qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); }