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); }
static void mips_cps_realize(DeviceState *dev, Error **errp) { MIPSCPSState *s = MIPS_CPS(dev); CPUMIPSState *env; MIPSCPU *cpu; int i; Error *err = NULL; target_ulong gcr_base; bool itu_present = false; bool saar_present = false; for (i = 0; i < s->num_vp; i++) { cpu = MIPS_CPU(cpu_create(s->cpu_type)); /* Init internal devices */ cpu_mips_irq_init_cpu(cpu); cpu_mips_clock_init(cpu); env = &cpu->env; if (cpu_mips_itu_supported(env)) { itu_present = true; /* Attach ITC Tag to the VP */ env->itc_tag = mips_itu_get_tag_region(&s->itu); env->itu = &s->itu; } qemu_register_reset(main_cpu_reset, cpu); } cpu = MIPS_CPU(first_cpu); env = &cpu->env; saar_present = (bool)env->saarp; /* Inter-Thread Communication Unit */ if (itu_present) { object_initialize(&s->itu, sizeof(s->itu), TYPE_MIPS_ITU); qdev_set_parent_bus(DEVICE(&s->itu), sysbus_get_default()); object_property_set_int(OBJECT(&s->itu), 16, "num-fifo", &err); object_property_set_int(OBJECT(&s->itu), 16, "num-semaphores", &err); object_property_set_bool(OBJECT(&s->itu), saar_present, "saar-present", &err); if (saar_present) { qdev_prop_set_ptr(DEVICE(&s->itu), "saar", (void *)&env->CP0_SAAR); } object_property_set_bool(OBJECT(&s->itu), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); return; } memory_region_add_subregion(&s->container, 0, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->itu), 0)); } /* Cluster Power Controller */ object_initialize(&s->cpc, sizeof(s->cpc), TYPE_MIPS_CPC); qdev_set_parent_bus(DEVICE(&s->cpc), sysbus_get_default()); object_property_set_int(OBJECT(&s->cpc), s->num_vp, "num-vp", &err); object_property_set_int(OBJECT(&s->cpc), 1, "vp-start-running", &err); object_property_set_bool(OBJECT(&s->cpc), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); return; } memory_region_add_subregion(&s->container, 0, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpc), 0)); /* Global Interrupt Controller */ object_initialize(&s->gic, sizeof(s->gic), TYPE_MIPS_GIC); qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default()); object_property_set_int(OBJECT(&s->gic), s->num_vp, "num-vp", &err); object_property_set_int(OBJECT(&s->gic), 128, "num-irq", &err); object_property_set_bool(OBJECT(&s->gic), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); return; } memory_region_add_subregion(&s->container, 0, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gic), 0)); /* Global Configuration Registers */ gcr_base = env->CP0_CMGCRBase << 4; object_initialize(&s->gcr, sizeof(s->gcr), TYPE_MIPS_GCR); qdev_set_parent_bus(DEVICE(&s->gcr), sysbus_get_default()); object_property_set_int(OBJECT(&s->gcr), s->num_vp, "num-vp", &err); object_property_set_int(OBJECT(&s->gcr), 0x800, "gcr-rev", &err); object_property_set_int(OBJECT(&s->gcr), gcr_base, "gcr-base", &err); object_property_set_link(OBJECT(&s->gcr), OBJECT(&s->gic.mr), "gic", &err); object_property_set_link(OBJECT(&s->gcr), OBJECT(&s->cpc.mr), "cpc", &err); object_property_set_bool(OBJECT(&s->gcr), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); return; } memory_region_add_subregion(&s->container, gcr_base, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gcr), 0)); }
static void zynq_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; ARMCPU *cpu; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *ext_ram = g_new(MemoryRegion, 1); MemoryRegion *ocm_ram = g_new(MemoryRegion, 1); DeviceState *dev; SysBusDevice *busdev; qemu_irq *irqp; qemu_irq pic[64]; NICInfo *nd; int n; qemu_irq cpu_irq; if (!cpu_model) { cpu_model = "cortex-a9"; } 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 = irqp[ARM_PIC_CPU_IRQ]; /* max 2GB ram */ if (ram_size > 0x80000000) { ram_size = 0x80000000; } /* DDR remapped to address zero. */ memory_region_init_ram(ext_ram, "zynq.ext_ram", ram_size); vmstate_register_ram_global(ext_ram); memory_region_add_subregion(address_space_mem, 0, ext_ram); /* 256K of on-chip memory */ memory_region_init_ram(ocm_ram, "zynq.ocm_ram", 256 << 10); vmstate_register_ram_global(ocm_ram); memory_region_add_subregion(address_space_mem, 0xFFFC0000, ocm_ram); DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0); /* AMD */ pflash_cfi02_register(0xe2000000, NULL, "zynq.pflash", FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, FLASH_SECTOR_SIZE, FLASH_SIZE/FLASH_SECTOR_SIZE, 1, 1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x2aa, 0); dev = qdev_create(NULL, "xilinx,zynq_slcr"); qdev_init_nofail(dev); sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0xF8000000); dev = qdev_create(NULL, "a9mpcore_priv"); qdev_prop_set_uint32(dev, "num-cpu", 1); qdev_init_nofail(dev); busdev = sysbus_from_qdev(dev); sysbus_mmio_map(busdev, 0, 0xF8F00000); sysbus_connect_irq(busdev, 0, cpu_irq); for (n = 0; n < 64; n++) { pic[n] = qdev_get_gpio_in(dev, n); } zynq_init_spi_flashes(0xE0006000, pic[58-IRQ_OFFSET], false); zynq_init_spi_flashes(0xE0007000, pic[81-IRQ_OFFSET], false); zynq_init_spi_flashes(0xE000D000, pic[51-IRQ_OFFSET], true); sysbus_create_simple("xlnx,ps7-usb", 0xE0002000, pic[53-IRQ_OFFSET]); sysbus_create_simple("xlnx,ps7-usb", 0xE0003000, pic[75-IRQ_OFFSET]); sysbus_create_simple("cadence_uart", 0xE0000000, pic[59-IRQ_OFFSET]); sysbus_create_simple("cadence_uart", 0xE0001000, pic[82-IRQ_OFFSET]); sysbus_create_varargs("cadence_ttc", 0xF8001000, pic[42-IRQ_OFFSET], pic[43-IRQ_OFFSET], pic[44-IRQ_OFFSET], NULL); sysbus_create_varargs("cadence_ttc", 0xF8002000, pic[69-IRQ_OFFSET], pic[70-IRQ_OFFSET], pic[71-IRQ_OFFSET], NULL); for (n = 0; n < nb_nics; n++) { nd = &nd_table[n]; if (n == 0) { gem_init(nd, 0xE000B000, pic[54-IRQ_OFFSET]); } else if (n == 1) { gem_init(nd, 0xE000C000, pic[77-IRQ_OFFSET]); } } zynq_binfo.ram_size = ram_size; zynq_binfo.kernel_filename = kernel_filename; zynq_binfo.kernel_cmdline = kernel_cmdline; zynq_binfo.initrd_filename = initrd_filename; zynq_binfo.nb_cpus = 1; zynq_binfo.board_id = 0xd32; zynq_binfo.loader_start = 0; arm_load_kernel(arm_env_get_cpu(first_cpu), &zynq_binfo); }
static void integratorcp_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; ARMCPU *cpu; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *ram_alias = g_new(MemoryRegion, 1); qemu_irq pic[32]; qemu_irq *cpu_pic; DeviceState *dev; int i; if (!cpu_model) { cpu_model = "arm926"; } cpu = cpu_arm_init(cpu_model); if (!cpu) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } memory_region_init_ram(ram, "integrator.ram", ram_size); vmstate_register_ram_global(ram); /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash. */ /* ??? RAM should repeat to fill physical memory space. */ /* SDRAM at address zero*/ memory_region_add_subregion(address_space_mem, 0, ram); /* And again at address 0x80000000 */ memory_region_init_alias(ram_alias, "ram.alias", ram, 0, ram_size); memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias); dev = qdev_create(NULL, "integrator_core"); qdev_prop_set_uint32(dev, "memsz", ram_size >> 20); qdev_init_nofail(dev); sysbus_mmio_map((SysBusDevice *)dev, 0, 0x10000000); cpu_pic = arm_pic_init_cpu(cpu); dev = sysbus_create_varargs("integrator_pic", 0x14000000, cpu_pic[ARM_PIC_CPU_IRQ], cpu_pic[ARM_PIC_CPU_FIQ], NULL); for (i = 0; i < 32; i++) { pic[i] = qdev_get_gpio_in(dev, i); } sysbus_create_simple("integrator_pic", 0xca000000, pic[26]); sysbus_create_varargs("integrator_pit", 0x13000000, pic[5], pic[6], pic[7], NULL); sysbus_create_simple("pl031", 0x15000000, pic[8]); sysbus_create_simple("pl011", 0x16000000, pic[1]); sysbus_create_simple("pl011", 0x17000000, pic[2]); icp_control_init(0xcb000000); sysbus_create_simple("pl050_keyboard", 0x18000000, pic[3]); sysbus_create_simple("pl050_mouse", 0x19000000, pic[4]); sysbus_create_varargs("pl181", 0x1c000000, pic[23], pic[24], NULL); if (nd_table[0].used) smc91c111_init(&nd_table[0], 0xc8000000, pic[27]); sysbus_create_simple("pl110", 0xc0000000, pic[22]); integrator_binfo.ram_size = ram_size; integrator_binfo.kernel_filename = kernel_filename; integrator_binfo.kernel_cmdline = kernel_cmdline; integrator_binfo.initrd_filename = initrd_filename; arm_load_kernel(cpu, &integrator_binfo); }
static void mips_mipssim_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; char *filename; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *isa = g_new(MemoryRegion, 1); MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *bios = g_new(MemoryRegion, 1); MIPSCPU *cpu; CPUMIPSState *env; ResetData *reset_info; int bios_size; /* Init CPUs. */ if (cpu_model == NULL) { #ifdef TARGET_MIPS64 cpu_model = "5Kf"; #else cpu_model = "24Kf"; #endif } cpu = cpu_mips_init(cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } env = &cpu->env; reset_info = g_malloc0(sizeof(ResetData)); reset_info->cpu = cpu; reset_info->vector = env->active_tc.PC; qemu_register_reset(main_cpu_reset, reset_info); /* Allocate RAM. */ memory_region_allocate_system_memory(ram, NULL, "mips_mipssim.ram", ram_size); memory_region_init_ram(bios, NULL, "mips_mipssim.bios", BIOS_SIZE, &error_fatal); vmstate_register_ram_global(bios); memory_region_set_readonly(bios, true); memory_region_add_subregion(address_space_mem, 0, ram); /* Map the BIOS / boot exception handler. */ memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios); /* Load a BIOS / boot exception handler image. */ if (bios_name == NULL) bios_name = BIOS_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { bios_size = load_image_targphys(filename, 0x1fc00000LL, BIOS_SIZE); g_free(filename); } else { bios_size = -1; } if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename && !qtest_enabled()) { /* Bail out if we have neither a kernel image nor boot vector code. */ error_report("Could not load MIPS bios '%s', and no " "-kernel argument was specified", bios_name); exit(1); } else { /* We have a boot vector start address. */ env->active_tc.PC = (target_long)(int32_t)0xbfc00000; } if (kernel_filename) { loaderparams.ram_size = ram_size; loaderparams.kernel_filename = kernel_filename; loaderparams.kernel_cmdline = kernel_cmdline; loaderparams.initrd_filename = initrd_filename; reset_info->vector = load_kernel(); } /* Init CPU internal devices. */ cpu_mips_irq_init_cpu(cpu); cpu_mips_clock_init(cpu); /* Register 64 KB of ISA IO space at 0x1fd00000. */ memory_region_init_alias(isa, NULL, "isa_mmio", get_system_io(), 0, 0x00010000); memory_region_add_subregion(get_system_memory(), 0x1fd00000, isa); /* A single 16450 sits at offset 0x3f8. It is attached to MIPS CPU INT2, which is interrupt 4. */ if (serial_hds[0]) serial_init(0x3f8, env->irq[4], 115200, serial_hds[0], get_system_io()); if (nd_table[0].used) /* MIPSnet uses the MIPS CPU INT0, which is interrupt 2. */ mipsnet_init(0x4200, env->irq[2], &nd_table[0]); }
/* 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; NewWorldMacIOState *macio; MACIOIDEState *macio_ide; BusState *adb_bus; MacIONVRAMState *nvr; int bios_size, ndrv_size; uint8_t *ndrv_file; int ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; int machine_arch; SysBusDevice *s; DeviceState *dev, *pic_dev; int *token = g_new(int, 1); 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); } } /* 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); 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][j]); } } for (i = 0; i < 64; i++) { pic[i] = qdev_get_gpio_in(pic_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; } object_property_set_bool(OBJECT(pci_bus), true, "realized", &error_abort); machine->usb |= defaults_enabled() && !machine->usb_disabled; /* Timebase Frequency */ if (kvm_enabled()) { tbfreq = kvmppc_get_tbfreq(); } else { tbfreq = TBFREQ; } /* MacIO */ macio = NEWWORLD_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[0x24]); /* ESCC-B */ qdev_connect_gpio_out(dev, 2, pic[0x25]); /* ESCC-A */ qdev_connect_gpio_out(dev, 3, pic[0x0d]); /* IDE */ qdev_connect_gpio_out(dev, 4, pic[0x02]); /* IDE DMA */ qdev_connect_gpio_out(dev, 5, pic[0x0e]); /* IDE */ qdev_connect_gpio_out(dev, 6, pic[0x03]); /* IDE DMA */ qdev_prop_set_uint64(dev, "frequency", tbfreq); 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]); 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_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_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) { ndrv_size = get_image_size(filename); if (ndrv_size != -1) { ndrv_file = g_malloc(ndrv_size); ndrv_size = load_image(filename, ndrv_file); 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 ivshmem_read(void *opaque, const uint8_t * buf, int flags) { IVShmemState *s = opaque; int incoming_fd, tmp_fd; int guest_max_eventfd; long incoming_posn; memcpy(&incoming_posn, buf, sizeof(long)); /* pick off s->server_chr->msgfd and store it, posn should accompany msg */ tmp_fd = qemu_chr_fe_get_msgfd(s->server_chr); IVSHMEM_DPRINTF("posn is %ld, fd is %d\n", incoming_posn, tmp_fd); /* make sure we have enough space for this guest */ if (incoming_posn >= s->nb_peers) { increase_dynamic_storage(s, incoming_posn); } if (tmp_fd == -1) { /* if posn is positive and unseen before then this is our posn*/ if ((incoming_posn >= 0) && (s->peers[incoming_posn].eventfds == NULL)) { /* receive our posn */ s->vm_id = incoming_posn; return; } else { /* otherwise an fd == -1 means an existing guest has gone away */ IVSHMEM_DPRINTF("posn %ld has gone away\n", incoming_posn); close_guest_eventfds(s, incoming_posn); return; } } /* because of the implementation of get_msgfd, we need a dup */ incoming_fd = dup(tmp_fd); if (incoming_fd == -1) { fprintf(stderr, "could not allocate file descriptor %s\n", strerror(errno)); return; } /* if the position is -1, then it's shared memory region fd */ if (incoming_posn == -1) { void * map_ptr; s->max_peer = 0; if (check_shm_size(incoming_fd, s->ivshmem_size, 0) == -1) { exit(-1); } /* mmap the region and map into the BAR2 */ map_ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, incoming_fd, 0); memory_region_init_ram_ptr(&s->ivshmem, "ivshmem.bar2", s->ivshmem_size, map_ptr); vmstate_register_ram(&s->ivshmem, &s->dev.qdev); IVSHMEM_DPRINTF("guest h/w addr = %" PRIu64 ", size = %" PRIu64 "\n", s->ivshmem_offset, s->ivshmem_size); memory_region_add_subregion(&s->bar, 0, &s->ivshmem); /* only store the fd if it is successfully mapped */ memset(s->shm_fds, 0, sizeof(s->shm_fds)); s->shm_fds[0] = incoming_fd; return; } /* each guest has an array of eventfds, and we keep track of how many * guests for each VM */ guest_max_eventfd = s->peers[incoming_posn].nb_eventfds; if (guest_max_eventfd == 0) { /* one eventfd per MSI vector */ s->peers[incoming_posn].eventfds = g_new(EventNotifier, s->vectors); } /* this is an eventfd for a particular guest VM */ IVSHMEM_DPRINTF("eventfds[%ld][%d] = %d\n", incoming_posn, guest_max_eventfd, incoming_fd); event_notifier_init_fd(&s->peers[incoming_posn].eventfds[guest_max_eventfd], incoming_fd); /* increment count for particular guest */ s->peers[incoming_posn].nb_eventfds++; /* keep track of the maximum VM ID */ if (incoming_posn > s->max_peer) { s->max_peer = incoming_posn; } if (incoming_posn == s->vm_id) { s->eventfd_chr[guest_max_eventfd] = create_eventfd_chr_device(s, &s->peers[s->vm_id].eventfds[guest_max_eventfd], guest_max_eventfd); } if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) { ivshmem_add_eventfd(s, incoming_posn, guest_max_eventfd); } }
static void a15mp_priv_realize(DeviceState *dev, Error **errp) { SysBusDevice *sbd = SYS_BUS_DEVICE(dev); A15MPPrivState *s = A15MPCORE_PRIV(dev); DeviceState *gicdev; SysBusDevice *busdev; int i; Error *err = NULL; bool has_el3; bool has_el2 = false; Object *cpuobj; gicdev = DEVICE(&s->gic); qdev_prop_set_uint32(gicdev, "num-cpu", s->num_cpu); qdev_prop_set_uint32(gicdev, "num-irq", s->num_irq); if (!kvm_irqchip_in_kernel()) { /* Make the GIC's TZ support match the CPUs. We assume that * either all the CPUs have TZ, or none do. */ cpuobj = OBJECT(qemu_get_cpu(0)); has_el3 = object_property_find(cpuobj, "has_el3", NULL) && object_property_get_bool(cpuobj, "has_el3", &error_abort); qdev_prop_set_bit(gicdev, "has-security-extensions", has_el3); /* Similarly for virtualization support */ has_el2 = object_property_find(cpuobj, "has_el2", NULL) && object_property_get_bool(cpuobj, "has_el2", &error_abort); qdev_prop_set_bit(gicdev, "has-virtualization-extensions", has_el2); } object_property_set_bool(OBJECT(&s->gic), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); return; } busdev = SYS_BUS_DEVICE(&s->gic); /* Pass through outbound IRQ lines from the GIC */ sysbus_pass_irq(sbd, busdev); /* Pass through inbound GPIO lines to the GIC */ qdev_init_gpio_in(dev, a15mp_priv_set_irq, s->num_irq - 32); /* Wire the outputs from each CPU's generic timer to the * appropriate GIC PPI inputs */ for (i = 0; i < s->num_cpu; i++) { DeviceState *cpudev = DEVICE(qemu_get_cpu(i)); int ppibase = s->num_irq - 32 + i * 32; int irq; /* Mapping from the output timer irq lines from the CPU to the * GIC PPI inputs used on the A15: */ const int timer_irq[] = { [GTIMER_PHYS] = 30, [GTIMER_VIRT] = 27, [GTIMER_HYP] = 26, [GTIMER_SEC] = 29, }; for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) { qdev_connect_gpio_out(cpudev, irq, qdev_get_gpio_in(gicdev, ppibase + timer_irq[irq])); } if (has_el2) { /* Connect the GIC maintenance interrupt to PPI ID 25 */ sysbus_connect_irq(SYS_BUS_DEVICE(gicdev), i + 4 * s->num_cpu, qdev_get_gpio_in(gicdev, ppibase + 25)); } } /* Memory map (addresses are offsets from PERIPHBASE): * 0x0000-0x0fff -- reserved * 0x1000-0x1fff -- GIC Distributor * 0x2000-0x3fff -- GIC CPU interface * 0x4000-0x4fff -- GIC virtual interface control for this CPU * 0x5000-0x51ff -- GIC virtual interface control for CPU 0 * 0x5200-0x53ff -- GIC virtual interface control for CPU 1 * 0x5400-0x55ff -- GIC virtual interface control for CPU 2 * 0x5600-0x57ff -- GIC virtual interface control for CPU 3 * 0x6000-0x7fff -- GIC virtual CPU interface */ memory_region_add_subregion(&s->container, 0x1000, sysbus_mmio_get_region(busdev, 0)); memory_region_add_subregion(&s->container, 0x2000, sysbus_mmio_get_region(busdev, 1)); if (has_el2) { memory_region_add_subregion(&s->container, 0x4000, sysbus_mmio_get_region(busdev, 2)); memory_region_add_subregion(&s->container, 0x6000, sysbus_mmio_get_region(busdev, 3)); for (i = 0; i < s->num_cpu; i++) { hwaddr base = 0x5000 + i * 0x200; MemoryRegion *mr = sysbus_mmio_get_region(busdev, 4 + s->num_cpu + i); memory_region_add_subregion(&s->container, base, mr); } } }
static void petalogix_ml605_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; MemoryRegion *address_space_mem = get_system_memory(); DeviceState *dev, *dma, *eth0; Object *ds, *cs; MicroBlazeCPU *cpu; SysBusDevice *busdev; DriveInfo *dinfo; int i; hwaddr ddr_base = MEMORY_BASEADDR; MemoryRegion *phys_lmb_bram = g_new(MemoryRegion, 1); MemoryRegion *phys_ram = g_new(MemoryRegion, 1); qemu_irq irq[32]; /* init CPUs */ cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU)); object_property_set_bool(OBJECT(cpu), true, "realized", &error_abort); /* Attach emulated BRAM through the LMB. */ memory_region_init_ram(phys_lmb_bram, NULL, "petalogix_ml605.lmb_bram", LMB_BRAM_SIZE); vmstate_register_ram_global(phys_lmb_bram); memory_region_add_subregion(address_space_mem, 0x00000000, phys_lmb_bram); memory_region_init_ram(phys_ram, NULL, "petalogix_ml605.ram", ram_size); vmstate_register_ram_global(phys_ram); memory_region_add_subregion(address_space_mem, ddr_base, phys_ram); dinfo = drive_get(IF_PFLASH, 0, 0); /* 5th parameter 2 means bank-width * 10th paremeter 0 means little-endian */ pflash_cfi01_register(FLASH_BASEADDR, NULL, "petalogix_ml605.flash", FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, (64 * 1024), FLASH_SIZE >> 16, 2, 0x89, 0x18, 0x0000, 0x0, 0); dev = qdev_create(NULL, "xlnx.xps-intc"); qdev_prop_set_uint32(dev, "kind-of-intr", 1 << TIMER_IRQ); qdev_init_nofail(dev); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(DEVICE(cpu), MB_CPU_IRQ)); for (i = 0; i < 32; i++) { irq[i] = qdev_get_gpio_in(dev, i); } serial_mm_init(address_space_mem, UART16550_BASEADDR + 0x1000, 2, irq[UART16550_IRQ], 115200, serial_hds[0], DEVICE_LITTLE_ENDIAN); /* 2 timers at irq 2 @ 100 Mhz. */ dev = qdev_create(NULL, "xlnx.xps-timer"); qdev_prop_set_uint32(dev, "one-timer-only", 0); qdev_prop_set_uint32(dev, "clock-frequency", 100 * 1000000); qdev_init_nofail(dev); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, TIMER_BASEADDR); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ]); /* axi ethernet and dma initialization. */ qemu_check_nic_model(&nd_table[0], "xlnx.axi-ethernet"); eth0 = qdev_create(NULL, "xlnx.axi-ethernet"); dma = qdev_create(NULL, "xlnx.axi-dma"); /* FIXME: attach to the sysbus instead */ object_property_add_child(qdev_get_machine(), "xilinx-eth", OBJECT(eth0), NULL); object_property_add_child(qdev_get_machine(), "xilinx-dma", OBJECT(dma), NULL); ds = object_property_get_link(OBJECT(dma), "axistream-connected-target", NULL); cs = object_property_get_link(OBJECT(dma), "axistream-control-connected-target", NULL); qdev_set_nic_properties(eth0, &nd_table[0]); qdev_prop_set_uint32(eth0, "rxmem", 0x1000); qdev_prop_set_uint32(eth0, "txmem", 0x1000); object_property_set_link(OBJECT(eth0), OBJECT(ds), "axistream-connected", &error_abort); object_property_set_link(OBJECT(eth0), OBJECT(cs), "axistream-control-connected", &error_abort); qdev_init_nofail(eth0); sysbus_mmio_map(SYS_BUS_DEVICE(eth0), 0, AXIENET_BASEADDR); sysbus_connect_irq(SYS_BUS_DEVICE(eth0), 0, irq[AXIENET_IRQ]); ds = object_property_get_link(OBJECT(eth0), "axistream-connected-target", NULL); cs = object_property_get_link(OBJECT(eth0), "axistream-control-connected-target", NULL); qdev_prop_set_uint32(dma, "freqhz", 100 * 1000000); object_property_set_link(OBJECT(dma), OBJECT(ds), "axistream-connected", &error_abort); object_property_set_link(OBJECT(dma), OBJECT(cs), "axistream-control-connected", &error_abort); qdev_init_nofail(dma); sysbus_mmio_map(SYS_BUS_DEVICE(dma), 0, AXIDMA_BASEADDR); sysbus_connect_irq(SYS_BUS_DEVICE(dma), 0, irq[AXIDMA_IRQ0]); sysbus_connect_irq(SYS_BUS_DEVICE(dma), 1, irq[AXIDMA_IRQ1]); { SSIBus *spi; dev = qdev_create(NULL, "xlnx.xps-spi"); qdev_prop_set_uint8(dev, "num-ss-bits", NUM_SPI_FLASHES); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, SPI_BASEADDR); sysbus_connect_irq(busdev, 0, irq[SPI_IRQ]); spi = (SSIBus *)qdev_get_child_bus(dev, "spi"); for (i = 0; i < NUM_SPI_FLASHES; i++) { qemu_irq cs_line; dev = ssi_create_slave(spi, "n25q128"); cs_line = qdev_get_gpio_in_named(dev, SSI_GPIO_CS, 0); sysbus_connect_irq(busdev, i+1, cs_line); } } microblaze_load_kernel(cpu, ddr_base, ram_size, machine->initrd_filename, BINARY_DEVICE_TREE_FILE, machine_cpu_reset); }
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++) { qemu_irq *input; env = cpu_ppc_init(cpu_model); if (!env) { fprintf(stderr, "Unable to initialize CPU!\n"); exit(1); } 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, env); env->load_info = boot_info; } else { /* Secondary CPUs */ qemu_register_reset(mpc8544ds_cpu_reset_sec, env); } } 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(); } }
static void petalogix_ml605_init(QEMUMachineInitArgs *args) { ram_addr_t ram_size = args->ram_size; const char *cpu_model = args->cpu_model; MemoryRegion *address_space_mem = get_system_memory(); DeviceState *dev, *dma, *eth0; MicroBlazeCPU *cpu; SysBusDevice *busdev; CPUMBState *env; DriveInfo *dinfo; int i; hwaddr ddr_base = MEMORY_BASEADDR; MemoryRegion *phys_lmb_bram = g_new(MemoryRegion, 1); MemoryRegion *phys_ram = g_new(MemoryRegion, 1); qemu_irq irq[32], *cpu_irq; /* init CPUs */ if (cpu_model == NULL) { cpu_model = "microblaze"; } cpu = cpu_mb_init(cpu_model); env = &cpu->env; /* Attach emulated BRAM through the LMB. */ memory_region_init_ram(phys_lmb_bram, "petalogix_ml605.lmb_bram", LMB_BRAM_SIZE); vmstate_register_ram_global(phys_lmb_bram); memory_region_add_subregion(address_space_mem, 0x00000000, phys_lmb_bram); memory_region_init_ram(phys_ram, "petalogix_ml605.ram", ram_size); vmstate_register_ram_global(phys_ram); memory_region_add_subregion(address_space_mem, ddr_base, phys_ram); dinfo = drive_get(IF_PFLASH, 0, 0); /* 5th parameter 2 means bank-width * 10th paremeter 0 means little-endian */ pflash_cfi01_register(FLASH_BASEADDR, NULL, "petalogix_ml605.flash", FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, (64 * 1024), FLASH_SIZE >> 16, 2, 0x89, 0x18, 0x0000, 0x0, 0); cpu_irq = microblaze_pic_init_cpu(env); dev = xilinx_intc_create(INTC_BASEADDR, cpu_irq[0], 4); for (i = 0; i < 32; i++) { irq[i] = qdev_get_gpio_in(dev, i); } serial_mm_init(address_space_mem, UART16550_BASEADDR + 0x1000, 2, irq[5], 115200, serial_hds[0], DEVICE_LITTLE_ENDIAN); /* 2 timers at irq 2 @ 100 Mhz. */ xilinx_timer_create(TIMER_BASEADDR, irq[2], 0, 100 * 1000000); /* axi ethernet and dma initialization. */ dma = qdev_create(NULL, "xlnx.axi-dma"); /* FIXME: attach to the sysbus instead */ object_property_add_child(container_get(qdev_get_machine(), "/unattached"), "xilinx-dma", OBJECT(dma), NULL); eth0 = xilinx_axiethernet_create(&nd_table[0], STREAM_SLAVE(dma), 0x82780000, irq[3], 0x1000, 0x1000); xilinx_axiethernetdma_init(dma, STREAM_SLAVE(eth0), 0x84600000, irq[1], irq[0], 100 * 1000000); { SSIBus *spi; dev = qdev_create(NULL, "xlnx.xps-spi"); qdev_prop_set_uint8(dev, "num-ss-bits", NUM_SPI_FLASHES); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, 0x40a00000); sysbus_connect_irq(busdev, 0, irq[4]); spi = (SSIBus *)qdev_get_child_bus(dev, "spi"); for (i = 0; i < NUM_SPI_FLASHES; i++) { qemu_irq cs_line; dev = ssi_create_slave_no_init(spi, "m25p80"); qdev_prop_set_string(dev, "partname", "n25q128"); qdev_init_nofail(dev); cs_line = qdev_get_gpio_in(dev, 0); sysbus_connect_irq(busdev, i+1, cs_line); } } microblaze_load_kernel(cpu, ddr_base, ram_size, BINARY_DEVICE_TREE_FILE, machine_cpu_reset); }
static void fsl_imx31_realize(DeviceState *dev, Error **errp) { FslIMX31State *s = FSL_IMX31(dev); uint16_t i; Error *err = NULL; object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err); if (err) { error_propagate(errp, err); return; } object_property_set_bool(OBJECT(&s->avic), true, "realized", &err); if (err) { error_propagate(errp, err); return; } sysbus_mmio_map(SYS_BUS_DEVICE(&s->avic), 0, FSL_IMX31_AVIC_ADDR); sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 0, qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 1, qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ)); object_property_set_bool(OBJECT(&s->ccm), true, "realized", &err); if (err) { error_propagate(errp, err); return; } sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX31_CCM_ADDR); /* Initialize all UARTS */ for (i = 0; i < FSL_IMX31_NUM_UARTS; i++) { static const struct { hwaddr addr; unsigned int irq; } serial_table[FSL_IMX31_NUM_UARTS] = { { FSL_IMX31_UART1_ADDR, FSL_IMX31_UART1_IRQ }, { FSL_IMX31_UART2_ADDR, FSL_IMX31_UART2_IRQ }, }; if (i < MAX_SERIAL_PORTS) { CharDriverState *chr; chr = serial_hds[i]; if (!chr) { char label[20]; snprintf(label, sizeof(label), "imx31.uart%d", i); chr = qemu_chr_new(label, "null", NULL); } qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr); } object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", &err); if (err) { error_propagate(errp, err); return; } sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, qdev_get_gpio_in(DEVICE(&s->avic), serial_table[i].irq)); } s->gpt.ccm = IMX_CCM(&s->ccm); object_property_set_bool(OBJECT(&s->gpt), true, "realized", &err); if (err) { error_propagate(errp, err); return; } sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt), 0, FSL_IMX31_GPT_ADDR); sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt), 0, qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX31_GPT_IRQ)); /* Initialize all EPIT timers */ for (i = 0; i < FSL_IMX31_NUM_EPITS; i++) { static const struct { hwaddr addr; unsigned int irq; } epit_table[FSL_IMX31_NUM_EPITS] = { { FSL_IMX31_EPIT1_ADDR, FSL_IMX31_EPIT1_IRQ }, { FSL_IMX31_EPIT2_ADDR, FSL_IMX31_EPIT2_IRQ }, }; s->epit[i].ccm = IMX_CCM(&s->ccm); object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err); if (err) { error_propagate(errp, err); return; } sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0, epit_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0, qdev_get_gpio_in(DEVICE(&s->avic), epit_table[i].irq)); } /* Initialize all I2C */ for (i = 0; i < FSL_IMX31_NUM_I2CS; i++) { static const struct { hwaddr addr; unsigned int irq; } i2c_table[FSL_IMX31_NUM_I2CS] = { { FSL_IMX31_I2C1_ADDR, FSL_IMX31_I2C1_IRQ }, { FSL_IMX31_I2C2_ADDR, FSL_IMX31_I2C2_IRQ }, { FSL_IMX31_I2C3_ADDR, FSL_IMX31_I2C3_IRQ } }; /* Initialize the I2C */ object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized", &err); if (err) { error_propagate(errp, err); return; } /* Map I2C memory */ sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr); /* Connect I2C IRQ to PIC */ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0, qdev_get_gpio_in(DEVICE(&s->avic), i2c_table[i].irq)); } /* Initialize all GPIOs */ for (i = 0; i < FSL_IMX31_NUM_GPIOS; i++) { static const struct { hwaddr addr; unsigned int irq; } gpio_table[FSL_IMX31_NUM_GPIOS] = { { FSL_IMX31_GPIO1_ADDR, FSL_IMX31_GPIO1_IRQ }, { FSL_IMX31_GPIO2_ADDR, FSL_IMX31_GPIO2_IRQ }, { FSL_IMX31_GPIO3_ADDR, FSL_IMX31_GPIO3_IRQ } }; object_property_set_bool(OBJECT(&s->gpio[i]), false, "has-edge-sel", &error_abort); object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized", &err); if (err) { error_propagate(errp, err); return; } sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, gpio_table[i].addr); /* Connect GPIO IRQ to PIC */ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0, qdev_get_gpio_in(DEVICE(&s->avic), gpio_table[i].irq)); } /* On a real system, the first 16k is a `secure boot rom' */ memory_region_init_rom(&s->secure_rom, NULL, "imx31.secure_rom", FSL_IMX31_SECURE_ROM_SIZE, &err); if (err) { error_propagate(errp, err); return; } memory_region_add_subregion(get_system_memory(), FSL_IMX31_SECURE_ROM_ADDR, &s->secure_rom); /* There is also a 16k ROM */ memory_region_init_rom(&s->rom, NULL, "imx31.rom", FSL_IMX31_ROM_SIZE, &err); if (err) { error_propagate(errp, err); return; } memory_region_add_subregion(get_system_memory(), FSL_IMX31_ROM_ADDR, &s->rom); /* initialize internal RAM (16 KB) */ memory_region_init_ram(&s->iram, NULL, "imx31.iram", FSL_IMX31_IRAM_SIZE, &err); if (err) { error_propagate(errp, err); return; } memory_region_add_subregion(get_system_memory(), FSL_IMX31_IRAM_ADDR, &s->iram); vmstate_register_ram_global(&s->iram); /* internal RAM (16 KB) is aliased over 256 MB - 16 KB */ memory_region_init_alias(&s->iram_alias, NULL, "imx31.iram_alias", &s->iram, 0, FSL_IMX31_IRAM_ALIAS_SIZE); memory_region_add_subregion(get_system_memory(), FSL_IMX31_IRAM_ALIAS_ADDR, &s->iram_alias); }
void sysbus_add_io(SysBusDevice *dev, hwaddr addr, MemoryRegion *mem) { memory_region_add_subregion(get_system_io(), addr, mem); }
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_cb[SPR_BOOKE_PIR].default_value = 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(); } }
static void a15_daughterboard_init(const VEDBoardInfo *daughterboard, ram_addr_t ram_size, const char *cpu_model, qemu_irq *pic) { int n; MemoryRegion *sysmem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *sram = g_new(MemoryRegion, 1); qemu_irq cpu_irq[4]; DeviceState *dev; SysBusDevice *busdev; if (!cpu_model) { cpu_model = "cortex-a15"; } for (n = 0; n < smp_cpus; n++) { ARMCPU *cpu; qemu_irq *irqp; 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]; } { /* We have to use a separate 64 bit variable here to avoid the gcc * "comparison is always false due to limited range of data type" * warning if we are on a host where ram_addr_t is 32 bits. */ uint64_t rsz = ram_size; if (rsz > (30ULL * 1024 * 1024 * 1024)) { fprintf(stderr, "vexpress-a15: cannot model more than 30GB RAM\n"); exit(1); } } memory_region_init_ram(ram, "vexpress.highmem", ram_size); vmstate_register_ram_global(ram); /* RAM is from 0x80000000 upwards; there is no low-memory alias for it. */ memory_region_add_subregion(sysmem, 0x80000000, ram); /* 0x2c000000 A15MPCore private memory region (GIC) */ dev = qdev_create(NULL, "a15mpcore_priv"); qdev_prop_set_uint32(dev, "num-cpu", smp_cpus); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, 0x2c000000); for (n = 0; n < smp_cpus; n++) { sysbus_connect_irq(busdev, n, cpu_irq[n]); } /* Interrupts [42:0] are from the motherboard; * [47:43] are reserved; [63:48] are daughterboard * peripherals. Note that some documentation numbers * external interrupts starting from 32 (because there * are internal interrupts 0..31). */ for (n = 0; n < 64; n++) { pic[n] = qdev_get_gpio_in(dev, n); } /* A15 daughterboard peripherals: */ /* 0x20000000: CoreSight interfaces: not modelled */ /* 0x2a000000: PL301 AXI interconnect: not modelled */ /* 0x2a420000: SCC: not modelled */ /* 0x2a430000: system counter: not modelled */ /* 0x2b000000: HDLCD controller: not modelled */ /* 0x2b060000: SP805 watchdog: not modelled */ /* 0x2b0a0000: PL341 dynamic memory controller: not modelled */ /* 0x2e000000: system SRAM */ memory_region_init_ram(sram, "vexpress.a15sram", 0x10000); vmstate_register_ram_global(sram); memory_region_add_subregion(sysmem, 0x2e000000, sram); /* 0x7ffb0000: DMA330 DMA controller: not modelled */ /* 0x7ffd0000: PL354 static memory controller: not modelled */ }
static void vexpress_common_init(VEDBoardInfo *daughterboard, QEMUMachineInitArgs *args) { DeviceState *dev, *sysctl, *pl041; qemu_irq pic[64]; uint32_t sys_id; DriveInfo *dinfo; pflash_t *pflash0; ram_addr_t vram_size, sram_size; MemoryRegion *sysmem = get_system_memory(); MemoryRegion *vram = g_new(MemoryRegion, 1); MemoryRegion *sram = g_new(MemoryRegion, 1); MemoryRegion *flashalias = g_new(MemoryRegion, 1); MemoryRegion *flash0mem; const hwaddr *map = daughterboard->motherboard_map; int i; daughterboard->init(daughterboard, args->ram_size, args->cpu_model, pic); /* Motherboard peripherals: the wiring is the same but the * addresses vary between the legacy and A-Series memory maps. */ sys_id = 0x1190f500; sysctl = qdev_create(NULL, "realview_sysctl"); qdev_prop_set_uint32(sysctl, "sys_id", sys_id); qdev_prop_set_uint32(sysctl, "proc_id", daughterboard->proc_id); qdev_prop_set_uint32(sysctl, "len-db-voltage", daughterboard->num_voltage_sensors); for (i = 0; i < daughterboard->num_voltage_sensors; i++) { char *propname = g_strdup_printf("db-voltage[%d]", i); qdev_prop_set_uint32(sysctl, propname, daughterboard->voltages[i]); g_free(propname); } qdev_prop_set_uint32(sysctl, "len-db-clock", daughterboard->num_clocks); for (i = 0; i < daughterboard->num_clocks; i++) { char *propname = g_strdup_printf("db-clock[%d]", i); qdev_prop_set_uint32(sysctl, propname, daughterboard->clocks[i]); g_free(propname); } qdev_init_nofail(sysctl); sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, map[VE_SYSREGS]); /* VE_SP810: not modelled */ /* VE_SERIALPCI: not modelled */ pl041 = qdev_create(NULL, "pl041"); qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512); qdev_init_nofail(pl041); sysbus_mmio_map(SYS_BUS_DEVICE(pl041), 0, map[VE_PL041]); sysbus_connect_irq(SYS_BUS_DEVICE(pl041), 0, pic[11]); dev = sysbus_create_varargs("pl181", map[VE_MMCI], pic[9], pic[10], NULL); /* Wire up MMC card detect and read-only signals */ qdev_connect_gpio_out(dev, 0, qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT)); qdev_connect_gpio_out(dev, 1, qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN)); sysbus_create_simple("pl050_keyboard", map[VE_KMI0], pic[12]); sysbus_create_simple("pl050_mouse", map[VE_KMI1], pic[13]); sysbus_create_simple("pl011", map[VE_UART0], pic[5]); sysbus_create_simple("pl011", map[VE_UART1], pic[6]); sysbus_create_simple("pl011", map[VE_UART2], pic[7]); sysbus_create_simple("pl011", map[VE_UART3], pic[8]); sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]); sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]); /* VE_SERIALDVI: not modelled */ sysbus_create_simple("pl031", map[VE_RTC], pic[4]); /* RTC */ /* VE_COMPACTFLASH: not modelled */ sysbus_create_simple("pl111", map[VE_CLCD], pic[14]); dinfo = drive_get_next(IF_PFLASH); pflash0 = ve_pflash_cfi01_register(map[VE_NORFLASH0], "vexpress.flash0", dinfo); if (!pflash0) { fprintf(stderr, "vexpress: error registering flash 0.\n"); exit(1); } if (map[VE_NORFLASHALIAS] != -1) { /* Map flash 0 as an alias into low memory */ flash0mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(pflash0), 0); memory_region_init_alias(flashalias, NULL, "vexpress.flashalias", flash0mem, 0, VEXPRESS_FLASH_SIZE); memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], flashalias); } dinfo = drive_get_next(IF_PFLASH); if (!ve_pflash_cfi01_register(map[VE_NORFLASH1], "vexpress.flash1", dinfo)) { fprintf(stderr, "vexpress: error registering flash 1.\n"); exit(1); } sram_size = 0x2000000; memory_region_init_ram(sram, NULL, "vexpress.sram", sram_size); vmstate_register_ram_global(sram); memory_region_add_subregion(sysmem, map[VE_SRAM], sram); vram_size = 0x800000; memory_region_init_ram(vram, NULL, "vexpress.vram", vram_size); vmstate_register_ram_global(vram); memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram); /* 0x4e000000 LAN9118 Ethernet */ if (nd_table[0].used) { lan9118_init(&nd_table[0], map[VE_ETHERNET], pic[15]); } /* VE_USB: not modelled */ /* VE_DAPROM: not modelled */ /* Create mmio transports, so the user can create virtio backends * (which will be automatically plugged in to the transports). If * no backend is created the transport will just sit harmlessly idle. */ for (i = 0; i < NUM_VIRTIO_TRANSPORTS; i++) { sysbus_create_simple("virtio-mmio", map[VE_VIRTIO] + 0x200 * i, pic[40 + i]); } daughterboard->bootinfo.ram_size = args->ram_size; daughterboard->bootinfo.kernel_filename = args->kernel_filename; daughterboard->bootinfo.kernel_cmdline = args->kernel_cmdline; daughterboard->bootinfo.initrd_filename = args->initrd_filename; daughterboard->bootinfo.nb_cpus = smp_cpus; daughterboard->bootinfo.board_id = VEXPRESS_BOARD_ID; daughterboard->bootinfo.loader_start = daughterboard->loader_start; daughterboard->bootinfo.smp_loader_start = map[VE_SRAM]; daughterboard->bootinfo.smp_bootreg_addr = map[VE_SYSREGS] + 0x30; daughterboard->bootinfo.gic_cpu_if_addr = daughterboard->gic_cpu_if_addr; daughterboard->bootinfo.modify_dtb = vexpress_modify_dtb; arm_load_kernel(ARM_CPU(first_cpu), &daughterboard->bootinfo); }
static void vexpress_common_init(const VEDBoardInfo *daughterboard, QEMUMachineInitArgs *args) { DeviceState *dev, *sysctl, *pl041; qemu_irq pic[64]; uint32_t sys_id; DriveInfo *dinfo; ram_addr_t vram_size, sram_size; MemoryRegion *sysmem = get_system_memory(); MemoryRegion *vram = g_new(MemoryRegion, 1); MemoryRegion *sram = g_new(MemoryRegion, 1); const hwaddr *map = daughterboard->motherboard_map; int i; daughterboard->init(daughterboard, args->ram_size, args->cpu_model, pic); /* Motherboard peripherals: the wiring is the same but the * addresses vary between the legacy and A-Series memory maps. */ sys_id = 0x1190f500; sysctl = qdev_create(NULL, "realview_sysctl"); qdev_prop_set_uint32(sysctl, "sys_id", sys_id); qdev_prop_set_uint32(sysctl, "proc_id", daughterboard->proc_id); qdev_prop_set_uint32(sysctl, "len-db-voltage", daughterboard->num_voltage_sensors); for (i = 0; i < daughterboard->num_voltage_sensors; i++) { char *propname = g_strdup_printf("db-voltage[%d]", i); qdev_prop_set_uint32(sysctl, propname, daughterboard->voltages[i]); g_free(propname); } qdev_prop_set_uint32(sysctl, "len-db-clock", daughterboard->num_clocks); for (i = 0; i < daughterboard->num_clocks; i++) { char *propname = g_strdup_printf("db-clock[%d]", i); qdev_prop_set_uint32(sysctl, propname, daughterboard->clocks[i]); g_free(propname); } qdev_init_nofail(sysctl); sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, map[VE_SYSREGS]); /* VE_SP810: not modelled */ /* VE_SERIALPCI: not modelled */ pl041 = qdev_create(NULL, "pl041"); qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512); qdev_init_nofail(pl041); sysbus_mmio_map(SYS_BUS_DEVICE(pl041), 0, map[VE_PL041]); sysbus_connect_irq(SYS_BUS_DEVICE(pl041), 0, pic[11]); dev = sysbus_create_varargs("pl181", map[VE_MMCI], pic[9], pic[10], NULL); /* Wire up MMC card detect and read-only signals */ qdev_connect_gpio_out(dev, 0, qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT)); qdev_connect_gpio_out(dev, 1, qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN)); sysbus_create_simple("pl050_keyboard", map[VE_KMI0], pic[12]); sysbus_create_simple("pl050_mouse", map[VE_KMI1], pic[13]); sysbus_create_simple("pl011", map[VE_UART0], pic[5]); sysbus_create_simple("pl011", map[VE_UART1], pic[6]); sysbus_create_simple("pl011", map[VE_UART2], pic[7]); sysbus_create_simple("pl011", map[VE_UART3], pic[8]); sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]); sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]); /* VE_SERIALDVI: not modelled */ sysbus_create_simple("pl031", map[VE_RTC], pic[4]); /* RTC */ /* VE_COMPACTFLASH: not modelled */ sysbus_create_simple("pl111", map[VE_CLCD], pic[14]); dinfo = drive_get_next(IF_PFLASH); if (!pflash_cfi01_register(map[VE_NORFLASH0], NULL, "vexpress.flash0", VEXPRESS_FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, VEXPRESS_FLASH_SECT_SIZE, VEXPRESS_FLASH_SIZE / VEXPRESS_FLASH_SECT_SIZE, 4, 0x00, 0x89, 0x00, 0x18, 0)) { fprintf(stderr, "vexpress: error registering flash 0.\n"); exit(1); } dinfo = drive_get_next(IF_PFLASH); if (!pflash_cfi01_register(map[VE_NORFLASH1], NULL, "vexpress.flash1", VEXPRESS_FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, VEXPRESS_FLASH_SECT_SIZE, VEXPRESS_FLASH_SIZE / VEXPRESS_FLASH_SECT_SIZE, 4, 0x00, 0x89, 0x00, 0x18, 0)) { fprintf(stderr, "vexpress: error registering flash 1.\n"); exit(1); } sram_size = 0x2000000; memory_region_init_ram(sram, "vexpress.sram", sram_size); vmstate_register_ram_global(sram); memory_region_add_subregion(sysmem, map[VE_SRAM], sram); vram_size = 0x800000; memory_region_init_ram(vram, "vexpress.vram", vram_size); vmstate_register_ram_global(vram); memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram); /* 0x4e000000 LAN9118 Ethernet */ if (nd_table[0].used) { lan9118_init(&nd_table[0], map[VE_ETHERNET], pic[15]); } /* VE_USB: not modelled */ /* VE_DAPROM: not modelled */ vexpress_binfo.ram_size = args->ram_size; vexpress_binfo.kernel_filename = args->kernel_filename; vexpress_binfo.kernel_cmdline = args->kernel_cmdline; vexpress_binfo.initrd_filename = args->initrd_filename; vexpress_binfo.nb_cpus = smp_cpus; vexpress_binfo.board_id = VEXPRESS_BOARD_ID; vexpress_binfo.loader_start = daughterboard->loader_start; vexpress_binfo.smp_loader_start = map[VE_SRAM]; vexpress_binfo.smp_bootreg_addr = map[VE_SYSREGS] + 0x30; vexpress_binfo.gic_cpu_if_addr = daughterboard->gic_cpu_if_addr; arm_load_kernel(arm_env_get_cpu(first_cpu), &vexpress_binfo); }
static void fsl_imx25_realize(DeviceState *dev, Error **errp) { FslIMX25State *s = FSL_IMX25(dev); uint8_t i; Error *err = NULL; object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err); if (err) { error_propagate(errp, err); return; } object_property_set_bool(OBJECT(&s->avic), true, "realized", &err); if (err) { error_propagate(errp, err); return; } sysbus_mmio_map(SYS_BUS_DEVICE(&s->avic), 0, FSL_IMX25_AVIC_ADDR); sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 0, qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 1, qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ)); object_property_set_bool(OBJECT(&s->ccm), true, "realized", &err); if (err) { error_propagate(errp, err); return; } sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX25_CCM_ADDR); /* Initialize all UARTs */ for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) { static const struct { hwaddr addr; unsigned int irq; } serial_table[FSL_IMX25_NUM_UARTS] = { { FSL_IMX25_UART1_ADDR, FSL_IMX25_UART1_IRQ }, { FSL_IMX25_UART2_ADDR, FSL_IMX25_UART2_IRQ }, { FSL_IMX25_UART3_ADDR, FSL_IMX25_UART3_IRQ }, { FSL_IMX25_UART4_ADDR, FSL_IMX25_UART4_IRQ }, { FSL_IMX25_UART5_ADDR, FSL_IMX25_UART5_IRQ } }; if (i < MAX_SERIAL_PORTS) { CharDriverState *chr; chr = serial_hds[i]; if (!chr) { char label[20]; snprintf(label, sizeof(label), "imx31.uart%d", i); chr = qemu_chr_new(label, "null", NULL); } qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr); } object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", &err); if (err) { error_propagate(errp, err); return; } sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, qdev_get_gpio_in(DEVICE(&s->avic), serial_table[i].irq)); } /* Initialize all GPT timers */ for (i = 0; i < FSL_IMX25_NUM_GPTS; i++) { static const struct { hwaddr addr; unsigned int irq; } gpt_table[FSL_IMX25_NUM_GPTS] = { { FSL_IMX25_GPT1_ADDR, FSL_IMX25_GPT1_IRQ }, { FSL_IMX25_GPT2_ADDR, FSL_IMX25_GPT2_IRQ }, { FSL_IMX25_GPT3_ADDR, FSL_IMX25_GPT3_IRQ }, { FSL_IMX25_GPT4_ADDR, FSL_IMX25_GPT4_IRQ } }; s->gpt[i].ccm = DEVICE(&s->ccm); object_property_set_bool(OBJECT(&s->gpt[i]), true, "realized", &err); if (err) { error_propagate(errp, err); return; } sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, gpt_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0, qdev_get_gpio_in(DEVICE(&s->avic), gpt_table[i].irq)); } /* Initialize all EPIT timers */ for (i = 0; i < FSL_IMX25_NUM_EPITS; i++) { static const struct { hwaddr addr; unsigned int irq; } epit_table[FSL_IMX25_NUM_EPITS] = { { FSL_IMX25_EPIT1_ADDR, FSL_IMX25_EPIT1_IRQ }, { FSL_IMX25_EPIT2_ADDR, FSL_IMX25_EPIT2_IRQ } }; s->epit[i].ccm = DEVICE(&s->ccm); object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err); if (err) { error_propagate(errp, err); return; } sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0, epit_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0, qdev_get_gpio_in(DEVICE(&s->avic), epit_table[i].irq)); } qdev_set_nic_properties(DEVICE(&s->fec), &nd_table[0]); object_property_set_bool(OBJECT(&s->fec), true, "realized", &err); if (err) { error_propagate(errp, err); return; } sysbus_mmio_map(SYS_BUS_DEVICE(&s->fec), 0, FSL_IMX25_FEC_ADDR); sysbus_connect_irq(SYS_BUS_DEVICE(&s->fec), 0, qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX25_FEC_IRQ)); /* Initialize all I2C */ for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) { static const struct { hwaddr addr; unsigned int irq; } i2c_table[FSL_IMX25_NUM_I2CS] = { { FSL_IMX25_I2C1_ADDR, FSL_IMX25_I2C1_IRQ }, { FSL_IMX25_I2C2_ADDR, FSL_IMX25_I2C2_IRQ }, { FSL_IMX25_I2C3_ADDR, FSL_IMX25_I2C3_IRQ } }; object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized", &err); if (err) { error_propagate(errp, err); return; } sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0, qdev_get_gpio_in(DEVICE(&s->avic), i2c_table[i].irq)); } /* Initialize all GPIOs */ for (i = 0; i < FSL_IMX25_NUM_GPIOS; i++) { static const struct { hwaddr addr; unsigned int irq; } gpio_table[FSL_IMX25_NUM_GPIOS] = { { FSL_IMX25_GPIO1_ADDR, FSL_IMX25_GPIO1_IRQ }, { FSL_IMX25_GPIO2_ADDR, FSL_IMX25_GPIO2_IRQ }, { FSL_IMX25_GPIO3_ADDR, FSL_IMX25_GPIO3_IRQ }, { FSL_IMX25_GPIO4_ADDR, FSL_IMX25_GPIO4_IRQ } }; object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized", &err); if (err) { error_propagate(errp, err); return; } sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, gpio_table[i].addr); /* Connect GPIO IRQ to PIC */ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0, qdev_get_gpio_in(DEVICE(&s->avic), gpio_table[i].irq)); } /* initialize 2 x 16 KB ROM */ memory_region_init_rom_device(&s->rom[0], NULL, NULL, NULL, "imx25.rom0", FSL_IMX25_ROM0_SIZE, &err); if (err) { error_propagate(errp, err); return; } memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM0_ADDR, &s->rom[0]); memory_region_init_rom_device(&s->rom[1], NULL, NULL, NULL, "imx25.rom1", FSL_IMX25_ROM1_SIZE, &err); if (err) { error_propagate(errp, err); return; } memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM1_ADDR, &s->rom[1]); /* initialize internal RAM (128 KB) */ memory_region_init_ram(&s->iram, NULL, "imx25.iram", FSL_IMX25_IRAM_SIZE, &err); if (err) { error_propagate(errp, err); return; } memory_region_add_subregion(get_system_memory(), FSL_IMX25_IRAM_ADDR, &s->iram); vmstate_register_ram_global(&s->iram); /* internal RAM (128 KB) is aliased over 128 MB - 128 KB */ memory_region_init_alias(&s->iram_alias, NULL, "imx25.iram_alias", &s->iram, 0, FSL_IMX25_IRAM_ALIAS_SIZE); memory_region_add_subregion(get_system_memory(), FSL_IMX25_IRAM_ALIAS_ADDR, &s->iram_alias); }
/* create the shared memory BAR when we are not using the server, so we can * create the BAR and map the memory immediately */ static int create_shared_memory_BAR(IVShmemState *s, IVShmemFile f[IVSHMEM_MAX_FILES], int num_files) { void * ptr_data, * virt_area; uint64_t total_size = 0, one_gb_align; int i, fd_zero; /* open /dev/zero for mmap */ fd_zero = open("/dev/zero", O_RDWR); if (fd_zero < 0) { fprintf(stderr, "ivshmem: opening /dev/zero failed (%s)\n", strerror(errno)); return -1; } /* Get virtual area of ivshmem_size plus 1GB for alignment. * virt_area later will be used to remap files backed up by hugepages (1GB * or 2MB). Therefore and due to mmap restrictions virt_area will have to * be aligned to both 1GB and 2MB (1GB will cover both scenarios). In order * to be sure we can freely align virt_area up to 1GB we reserve vshmem_size * plus 1GB */ virt_area = mmap(NULL, s->ivshmem_size + ONE_GB, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd_zero, 0); if (virt_area == MAP_FAILED) { fprintf(stderr, "ivshmem: mmap /dev/zero failed (%s)\n", strerror(errno)); return -1; } /* Calculate 1GB boundary alignment covering 1GB and 2MB hugepage cases */ one_gb_align = ONE_GB - ((uint64_t) virt_area % ONE_GB); munmap(virt_area, s->ivshmem_size + ONE_GB); close(fd_zero); /* Finally align virt_area to 1GB boundary. */ virt_area += one_gb_align; /* at this point virt_area contains a virtual address that where we can * safely use to mmap all ivshmem files. * Proceed to mmap all ivshmem files so. */ for (i = 0; i < num_files; i++) { /* remap file into the start of virtual area */ ptr_data = mmap(virt_area + total_size, f[i].size, PROT_READ|PROT_WRITE, MAP_SHARED | MAP_FIXED, f[i].fd, f[i].offset); /* we need to make sure we get _exactly_ what we want */ if (ptr_data == MAP_FAILED || ptr_data != virt_area + total_size) { fprintf(stderr, "ivshmem: mmap failed (%s)\n", strerror(errno)); return -1; } total_size += f[i].size; } memcpy(s->shm_fds, f, sizeof(s->shm_fds)); memory_region_init_ram_ptr(&s->ivshmem, "ivshmem.bar2", s->ivshmem_size, virt_area); vmstate_register_ram(&s->ivshmem, &s->dev.qdev); memory_region_add_subregion(&s->bar, 0, &s->ivshmem); /* region for shared memory */ pci_register_bar(&s->dev, 2, s->ivshmem_attr, &s->bar); return 0; }
static void realview_gic_map_setup(RealViewGICState *s) { memory_region_init(&s->container, "realview-gic-container", 0x2000); memory_region_add_subregion(&s->container, 0, &s->gic.cpuiomem[0]); memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem); }
static void kzm_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; ARMCPU *cpu; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *sram = g_new(MemoryRegion, 1); MemoryRegion *ram_alias = g_new(MemoryRegion, 1); qemu_irq *cpu_pic; DeviceState *dev; DeviceState *ccm; if (!cpu_model) { cpu_model = "arm1136"; } cpu = cpu_arm_init(cpu_model); if (!cpu) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } /* On a real system, the first 16k is a `secure boot rom' */ memory_region_init_ram(ram, "kzm.ram", ram_size); vmstate_register_ram_global(ram); memory_region_add_subregion(address_space_mem, KZM_RAMADDRESS, ram); memory_region_init_alias(ram_alias, "ram.alias", ram, 0, ram_size); memory_region_add_subregion(address_space_mem, 0x88000000, ram_alias); memory_region_init_ram(sram, "kzm.sram", 0x4000); memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram); cpu_pic = arm_pic_init_cpu(cpu); dev = sysbus_create_varargs("imx_avic", 0x68000000, cpu_pic[ARM_PIC_CPU_IRQ], cpu_pic[ARM_PIC_CPU_FIQ], NULL); imx_serial_create(0, 0x43f90000, qdev_get_gpio_in(dev, 45)); imx_serial_create(1, 0x43f94000, qdev_get_gpio_in(dev, 32)); ccm = sysbus_create_simple("imx_ccm", 0x53f80000, NULL); imx_timerp_create(0x53f94000, qdev_get_gpio_in(dev, 28), ccm); imx_timerp_create(0x53f98000, qdev_get_gpio_in(dev, 27), ccm); imx_timerg_create(0x53f90000, qdev_get_gpio_in(dev, 29), ccm); if (nd_table[0].used) { lan9118_init(&nd_table[0], 0xb6000000, qdev_get_gpio_in(dev, 52)); } if (serial_hds[2]) { /* touchscreen */ serial_mm_init(address_space_mem, KZM_FPGA+0x10, 0, qdev_get_gpio_in(dev, 52), 14745600, serial_hds[2], DEVICE_NATIVE_ENDIAN); } kzm_binfo.ram_size = ram_size; kzm_binfo.kernel_filename = kernel_filename; kzm_binfo.kernel_cmdline = kernel_cmdline; kzm_binfo.initrd_filename = initrd_filename; kzm_binfo.nb_cpus = 1; arm_load_kernel(cpu, &kzm_binfo); }
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) { 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; MacIONVRAMState *nvr; int bios_size; MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem; MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1), *ide_mem[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++) { 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); /* First IDE channel is a MAC IDE on the MacIO bus */ dbdma = DBDMA_init(&dbdma_mem); ide_mem[0] = NULL; ide_mem[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, pic[0x12]); adb_kbd_init(&adb_bus); adb_mouse_init(&adb_bus); nvr = macio_nvram_init(0x2000, 4); pmac_format_nvram_partition(nvr, 0x2000); macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem, dbdma_mem, cuda_mem, nvr, 2, ide_mem, escc_bar); if (usb_enabled) { 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_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 realview_init(MachineState *machine, enum realview_board_type board_type) { ARMCPU *cpu = NULL; CPUARMState *env; ObjectClass *cpu_oc; 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 pic[64]; qemu_irq mmc_irq[2]; PCIBus *pci_bus = NULL; NICInfo *nd; I2CBus *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; ram_addr_t ram_size = machine->ram_size; hwaddr periphbase = 0; switch (board_type) { case BOARD_EB: break; case BOARD_EB_MPCORE: is_mpcore = 1; periphbase = 0x10100000; break; case BOARD_PB_A8: is_pb = 1; break; case BOARD_PBX_A9: is_mpcore = 1; is_pb = 1; periphbase = 0x1f000000; break; } cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, machine->cpu_model); if (!cpu_oc) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } for (n = 0; n < smp_cpus; n++) { Object *cpuobj = object_new(object_class_get_name(cpu_oc)); Error *err = NULL; if (is_pb && is_mpcore) { object_property_set_int(cpuobj, periphbase, "reset-cbar", &err); if (err) { error_report("%s", error_get_pretty(err)); exit(1); } } object_property_set_bool(cpuobj, true, "realized", &err); if (err) { error_report("%s", error_get_pretty(err)); exit(1); } cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpuobj), ARM_CPU_IRQ); } cpu = ARM_CPU(first_cpu); 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, NULL, "realview.lowmem", low_ram_size, &error_abort); vmstate_register_ram_global(ram_lo); memory_region_add_subregion(sysmem, 0x20000000, ram_lo); } memory_region_init_ram(ram_hi, NULL, "realview.highmem", ram_size, &error_abort); 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, NULL, "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(SYS_BUS_DEVICE(sysctl), 0, 0x10000000); 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 = SYS_BUS_DEVICE(dev); 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(SYS_BUS_DEVICE(pl041), 0, 0x10004000); sysbus_connect_irq(SYS_BUS_DEVICE(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 = SYS_BUS_DEVICE(dev); qdev_init_nofail(dev); sysbus_mmio_map(busdev, 0, 0x10019000); /* PCI controller registers */ sysbus_mmio_map(busdev, 1, 0x60000000); /* PCI self-config */ sysbus_mmio_map(busdev, 2, 0x61000000); /* PCI config */ sysbus_mmio_map(busdev, 3, 0x62000000); /* PCI I/O */ sysbus_mmio_map(busdev, 4, 0x63000000); /* PCI memory window 1 */ sysbus_mmio_map(busdev, 5, 0x64000000); /* PCI memory window 2 */ sysbus_mmio_map(busdev, 6, 0x68000000); /* PCI memory window 3 */ 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(false)) { 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 { if (pci_bus) { pci_nic_init_nofail(nd, pci_bus, "rtl8139", NULL); } } } dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL); i2c = (I2CBus *)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. */ /* 0x60000000 PCI Self Config. */ /* 0x61000000 PCI Config. */ /* 0x62000000 PCI IO. */ /* 0x63000000 PCI mem 0. */ /* 0x64000000 PCI mem 1. */ /* 0x68000000 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, NULL, "realview.hack", 0x1000, &error_abort); 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 = machine->kernel_filename; realview_binfo.kernel_cmdline = machine->kernel_cmdline; realview_binfo.initrd_filename = machine->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_CPU(first_cpu), &realview_binfo); }
static void a9mp_priv_realize(DeviceState *dev, Error **errp) { SysBusDevice *sbd = SYS_BUS_DEVICE(dev); A9MPPrivState *s = A9MPCORE_PRIV(dev); DeviceState *scudev, *gicdev, *gtimerdev, *mptimerdev, *wdtdev; SysBusDevice *scubusdev, *gicbusdev, *gtimerbusdev, *mptimerbusdev, *wdtbusdev; Error *err = NULL; int i; bool has_el3; Object *cpuobj; scudev = DEVICE(&s->scu); qdev_prop_set_uint32(scudev, "num-cpu", s->num_cpu); object_property_set_bool(OBJECT(&s->scu), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); return; } scubusdev = SYS_BUS_DEVICE(&s->scu); gicdev = DEVICE(&s->gic); qdev_prop_set_uint32(gicdev, "num-cpu", s->num_cpu); qdev_prop_set_uint32(gicdev, "num-irq", s->num_irq); /* Make the GIC's TZ support match the CPUs. We assume that * either all the CPUs have TZ, or none do. */ cpuobj = OBJECT(qemu_get_cpu(0)); has_el3 = object_property_find(cpuobj, "has_el3", NULL) && object_property_get_bool(cpuobj, "has_el3", &error_abort); qdev_prop_set_bit(gicdev, "has-security-extensions", has_el3); object_property_set_bool(OBJECT(&s->gic), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); return; } gicbusdev = SYS_BUS_DEVICE(&s->gic); /* Pass through outbound IRQ lines from the GIC */ sysbus_pass_irq(sbd, gicbusdev); /* Pass through inbound GPIO lines to the GIC */ qdev_init_gpio_in(dev, a9mp_priv_set_irq, s->num_irq - 32); gtimerdev = DEVICE(&s->gtimer); qdev_prop_set_uint32(gtimerdev, "num-cpu", s->num_cpu); object_property_set_bool(OBJECT(&s->gtimer), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); return; } gtimerbusdev = SYS_BUS_DEVICE(&s->gtimer); mptimerdev = DEVICE(&s->mptimer); qdev_prop_set_uint32(mptimerdev, "num-cpu", s->num_cpu); object_property_set_bool(OBJECT(&s->mptimer), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); return; } mptimerbusdev = SYS_BUS_DEVICE(&s->mptimer); wdtdev = DEVICE(&s->wdt); qdev_prop_set_uint32(wdtdev, "num-cpu", s->num_cpu); object_property_set_bool(OBJECT(&s->wdt), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); return; } wdtbusdev = SYS_BUS_DEVICE(&s->wdt); /* Memory map (addresses are offsets from PERIPHBASE): * 0x0000-0x00ff -- Snoop Control Unit * 0x0100-0x01ff -- GIC CPU interface * 0x0200-0x02ff -- Global Timer * 0x0300-0x05ff -- nothing * 0x0600-0x06ff -- private timers and watchdogs * 0x0700-0x0fff -- nothing * 0x1000-0x1fff -- GIC Distributor */ memory_region_add_subregion(&s->container, 0, sysbus_mmio_get_region(scubusdev, 0)); /* GIC CPU interface */ memory_region_add_subregion(&s->container, 0x100, sysbus_mmio_get_region(gicbusdev, 1)); memory_region_add_subregion(&s->container, 0x200, sysbus_mmio_get_region(gtimerbusdev, 0)); /* Note that the A9 exposes only the "timer/watchdog for this core" * memory region, not the "timer/watchdog for core X" ones 11MPcore has. */ memory_region_add_subregion(&s->container, 0x600, sysbus_mmio_get_region(mptimerbusdev, 0)); memory_region_add_subregion(&s->container, 0x620, sysbus_mmio_get_region(wdtbusdev, 0)); memory_region_add_subregion(&s->container, 0x1000, sysbus_mmio_get_region(gicbusdev, 0)); /* Wire up the interrupt from each watchdog and timer. * For each core the global timer is PPI 27, the private * timer is PPI 29 and the watchdog PPI 30. */ for (i = 0; i < s->num_cpu; i++) { int ppibase = (s->num_irq - 32) + i * 32; sysbus_connect_irq(gtimerbusdev, i, qdev_get_gpio_in(gicdev, ppibase + 27)); sysbus_connect_irq(mptimerbusdev, i, qdev_get_gpio_in(gicdev, ppibase + 29)); sysbus_connect_irq(wdtbusdev, i, qdev_get_gpio_in(gicdev, ppibase + 30)); } }
/* 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(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 leon3_generic_hw_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; SPARCCPU *cpu; CPUSPARCState *env; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *prom = g_new(MemoryRegion, 1); int ret; char *filename; qemu_irq *cpu_irqs = NULL; int bios_size; int prom_size; ResetData *reset_info; /* Init CPU */ if (!cpu_model) { cpu_model = "LEON3"; } cpu = cpu_sparc_init(cpu_model); if (cpu == NULL) { fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n"); exit(1); } env = &cpu->env; cpu_sparc_set_id(env, 0); /* Reset data */ reset_info = g_malloc0(sizeof(ResetData)); reset_info->cpu = cpu; reset_info->sp = 0x40000000 + ram_size; qemu_register_reset(main_cpu_reset, reset_info); /* Allocate IRQ manager */ grlib_irqmp_create(0x80000200, env, &cpu_irqs, MAX_PILS, &leon3_set_pil_in); env->qemu_irq_ack = leon3_irq_manager; /* Allocate RAM */ if ((uint64_t)ram_size > (1UL << 30)) { fprintf(stderr, "qemu: Too much memory for this machine: %d, maximum 1G\n", (unsigned int)(ram_size / (1024 * 1024))); exit(1); } memory_region_allocate_system_memory(ram, NULL, "leon3.ram", ram_size); memory_region_add_subregion(address_space_mem, 0x40000000, ram); /* Allocate BIOS */ prom_size = 8 * 1024 * 1024; /* 8Mb */ memory_region_init_ram(prom, NULL, "Leon3.bios", prom_size, &error_fatal); vmstate_register_ram_global(prom); memory_region_set_readonly(prom, true); memory_region_add_subregion(address_space_mem, 0x00000000, prom); /* Load boot prom */ if (bios_name == NULL) { bios_name = PROM_FILENAME; } filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); bios_size = get_image_size(filename); if (bios_size > prom_size) { fprintf(stderr, "qemu: could not load prom '%s': file too big\n", filename); exit(1); } if (bios_size > 0) { ret = load_image_targphys(filename, 0x00000000, bios_size); if (ret < 0 || ret > prom_size) { fprintf(stderr, "qemu: could not load prom '%s'\n", filename); exit(1); } } else if (kernel_filename == NULL && !qtest_enabled()) { fprintf(stderr, "Can't read bios image %s\n", filename); exit(1); } g_free(filename); /* Can directly load an application. */ if (kernel_filename != NULL) { long kernel_size; uint64_t entry; kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL, 1 /* big endian */, ELF_MACHINE, 0); if (kernel_size < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } if (bios_size <= 0) { /* If there is no bios/monitor, start the application. */ env->pc = entry; env->npc = entry + 4; reset_info->entry = entry; } } /* Allocate timers */ grlib_gptimer_create(0x80000300, 2, CPU_CLK, cpu_irqs, 6); /* Allocate uart */ if (serial_hds[0]) { grlib_apbuart_create(0x80000100, serial_hds[0], cpu_irqs[3]); } }
static void a9_daughterboard_init(const VEDBoardInfo *daughterboard, ram_addr_t ram_size, const char *cpu_model, qemu_irq *pic) { MemoryRegion *sysmem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *lowram = g_new(MemoryRegion, 1); DeviceState *dev; SysBusDevice *busdev; qemu_irq *irqp; int n; qemu_irq cpu_irq[4]; ram_addr_t low_ram_size; if (!cpu_model) { cpu_model = "cortex-a9"; } for (n = 0; n < smp_cpus; n++) { ARMCPU *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]; } if (ram_size > 0x40000000) { /* 1GB is the maximum the address space permits */ fprintf(stderr, "vexpress-a9: cannot model more than 1GB RAM\n"); exit(1); } memory_region_init_ram(ram, "vexpress.highmem", ram_size); vmstate_register_ram_global(ram); low_ram_size = ram_size; if (low_ram_size > 0x4000000) { low_ram_size = 0x4000000; } /* RAM is from 0x60000000 upwards. The bottom 64MB of the * address space should in theory be remappable to various * things including ROM or RAM; we always map the RAM there. */ memory_region_init_alias(lowram, "vexpress.lowmem", ram, 0, low_ram_size); memory_region_add_subregion(sysmem, 0x0, lowram); memory_region_add_subregion(sysmem, 0x60000000, ram); /* 0x1e000000 A9MPCore (SCU) private memory region */ dev = qdev_create(NULL, "a9mpcore_priv"); qdev_prop_set_uint32(dev, "num-cpu", smp_cpus); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, 0x1e000000); for (n = 0; n < smp_cpus; n++) { sysbus_connect_irq(busdev, n, cpu_irq[n]); } /* Interrupts [42:0] are from the motherboard; * [47:43] are reserved; [63:48] are daughterboard * peripherals. Note that some documentation numbers * external interrupts starting from 32 (because the * A9MP has internal interrupts 0..31). */ for (n = 0; n < 64; n++) { pic[n] = qdev_get_gpio_in(dev, n); } /* Daughterboard peripherals : 0x10020000 .. 0x20000000 */ /* 0x10020000 PL111 CLCD (daughterboard) */ sysbus_create_simple("pl111", 0x10020000, pic[44]); /* 0x10060000 AXI RAM */ /* 0x100e0000 PL341 Dynamic Memory Controller */ /* 0x100e1000 PL354 Static Memory Controller */ /* 0x100e2000 System Configuration Controller */ sysbus_create_simple("sp804", 0x100e4000, pic[48]); /* 0x100e5000 SP805 Watchdog module */ /* 0x100e6000 BP147 TrustZone Protection Controller */ /* 0x100e9000 PL301 'Fast' AXI matrix */ /* 0x100ea000 PL301 'Slow' AXI matrix */ /* 0x100ec000 TrustZone Address Space Controller */ /* 0x10200000 CoreSight debug APB */ /* 0x1e00a000 PL310 L2 Cache Controller */ sysbus_create_varargs("l2x0", 0x1e00a000, NULL); }
static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) { STM32F205State *s = STM32F205_SOC(dev_soc); DeviceState *syscfgdev, *usartdev, *timerdev, *nvic; SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev; Error *err = NULL; int i; MemoryRegion *system_memory = get_system_memory(); MemoryRegion *sram = g_new(MemoryRegion, 1); MemoryRegion *flash = g_new(MemoryRegion, 1); MemoryRegion *flash_alias = g_new(MemoryRegion, 1); memory_region_init_ram(flash, NULL, "STM32F205.flash", FLASH_SIZE, &error_fatal); memory_region_init_alias(flash_alias, NULL, "STM32F205.flash.alias", flash, 0, FLASH_SIZE); vmstate_register_ram_global(flash); memory_region_set_readonly(flash, true); memory_region_set_readonly(flash_alias, true); memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, flash); memory_region_add_subregion(system_memory, 0, flash_alias); memory_region_init_ram(sram, NULL, "STM32F205.sram", SRAM_SIZE, &error_fatal); vmstate_register_ram_global(sram); memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram); nvic = armv7m_init(get_system_memory(), FLASH_SIZE, 96, s->kernel_filename, s->cpu_model); /* System configuration controller */ syscfgdev = DEVICE(&s->syscfg); object_property_set_bool(OBJECT(&s->syscfg), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); return; } syscfgbusdev = SYS_BUS_DEVICE(syscfgdev); sysbus_mmio_map(syscfgbusdev, 0, 0x40013800); sysbus_connect_irq(syscfgbusdev, 0, qdev_get_gpio_in(nvic, 71)); /* Attach UART (uses USART registers) and USART controllers */ for (i = 0; i < STM_NUM_USARTS; i++) { usartdev = DEVICE(&(s->usart[i])); object_property_set_bool(OBJECT(&s->usart[i]), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); return; } usartbusdev = SYS_BUS_DEVICE(usartdev); sysbus_mmio_map(usartbusdev, 0, usart_addr[i]); sysbus_connect_irq(usartbusdev, 0, qdev_get_gpio_in(nvic, usart_irq[i])); } /* Timer 2 to 5 */ for (i = 0; i < STM_NUM_TIMERS; i++) { timerdev = DEVICE(&(s->timer[i])); qdev_prop_set_uint64(timerdev, "clock-frequency", 1000000000); object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); return; } timerbusdev = SYS_BUS_DEVICE(timerdev); sysbus_mmio_map(timerbusdev, 0, timer_addr[i]); sysbus_connect_irq(timerbusdev, 0, qdev_get_gpio_in(nvic, timer_irq[i])); } }
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; qemu_irq *pic, **heathrow_irqs; int linux_boot, i; MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *bios = g_new(MemoryRegion, 1); MemoryRegion *isa = 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; uint64_t tbfreq; linux_boot = (kernel_filename != NULL); /* init CPUs */ if (machine->cpu_model == NULL) machine->cpu_model = "G3"; 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 16.6 Mhz */ cpu_ppc_tb_init(env, TBFREQ); 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_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); 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, 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 = 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'; 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 */ memory_region_init_alias(isa, NULL, "isa_mmio", get_system_io(), 0, 0x00200000); memory_region_add_subregion(sysmem, 0xfe000000, isa); /* 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: 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); } 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, NULL, "escc-bar", escc_mem, 0, memory_region_size(escc_mem)); 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 = 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-0 */ qdev_connect_gpio_out(dev, 2, pic[0x02]); /* IDE-0 DMA */ qdev_connect_gpio_out(dev, 3, pic[0x0E]); /* IDE-1 */ qdev_connect_gpio_out(dev, 4, pic[0x03]); /* IDE-1 DMA */ qdev_prop_set_uint64(dev, "frequency", tbfreq); macio_init(macio, pic_mem, escc_bar); 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 */ 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, 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); qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); }