示例#1
0
static void old_pc_system_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
{
    char *filename;
    MemoryRegion *bios, *isa_bios;
    int bios_size, isa_bios_size;
    int ret;

    /* BIOS load */
    if (bios_name == NULL) {
        bios_name = BIOS_FILENAME;
    }
    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
    if (filename) {
        bios_size = get_image_size(filename);
    } else {
        bios_size = -1;
    }
    if (bios_size <= 0 ||
        (bios_size % 65536) != 0) {
        goto bios_error;
    }
    bios = g_malloc(sizeof(*bios));
    memory_region_init_ram(bios, "pc.bios", bios_size);
    vmstate_register_ram_global(bios);
    if (!isapc_ram_fw) {
        memory_region_set_readonly(bios, true);
    }
    ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
    if (ret != 0) {
    bios_error:
        fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name);
        exit(1);
    }
    if (filename) {
        g_free(filename);
    }

    /* map the last 128KB of the BIOS in ISA space */
    isa_bios_size = bios_size;
    if (isa_bios_size > (128 * 1024)) {
        isa_bios_size = 128 * 1024;
    }
    isa_bios = g_malloc(sizeof(*isa_bios));
    memory_region_init_alias(isa_bios, "isa-bios", bios,
                             bios_size - isa_bios_size, isa_bios_size);
    memory_region_add_subregion_overlap(rom_memory,
                                        0x100000 - isa_bios_size,
                                        isa_bios,
                                        1);
    if (!isapc_ram_fw) {
        memory_region_set_readonly(isa_bios, true);
    }

    /* map all the bios at the top of memory */
    memory_region_add_subregion(rom_memory,
                                (uint32_t)(-bios_size),
                                bios);
}
static void pc_isa_bios_init(MemoryRegion *rom_memory,
                             MemoryRegion *flash_mem,
                             int ram_size)
{
    int isa_bios_size;
    MemoryRegion *isa_bios;
    uint64_t flash_size;
    void *flash_ptr, *isa_bios_ptr;

    flash_size = memory_region_size(flash_mem);

    /* map the last 128KB of the BIOS in ISA space */
    isa_bios_size = flash_size;
    if (isa_bios_size > (128 * 1024)) {
        isa_bios_size = 128 * 1024;
    }
    isa_bios = g_malloc(sizeof(*isa_bios));
    memory_region_init_ram(isa_bios, "isa-bios", isa_bios_size);
    vmstate_register_ram_global(isa_bios);
    memory_region_add_subregion_overlap(rom_memory,
                                        0x100000 - isa_bios_size,
                                        isa_bios,
                                        1);

    /* copy ISA rom image from top of flash memory */
    flash_ptr = memory_region_get_ram_ptr(flash_mem);
    isa_bios_ptr = memory_region_get_ram_ptr(isa_bios);
    memcpy(isa_bios_ptr,
           ((uint8_t*)flash_ptr) + (flash_size - isa_bios_size),
           isa_bios_size);

    memory_region_set_readonly(isa_bios, true);
}
示例#3
0
static int f2xx_flash_init(SysBusDevice *dev)
{
    f2xx_flash_t *flash = FROM_SYSBUS(typeof(*flash), dev);

//    memory_region_init_rom_device(&flash->mem, &f2xx_flash_ops, flash, "name",
//      size);
    memory_region_init_ram(&flash->mem, NULL, "f2xx.flash", flash->size);

    vmstate_register_ram(&flash->mem, DEVICE(flash));
    //vmstate_register_ram_global(&flash->mem);
    memory_region_set_readonly(&flash->mem, true);
    memory_region_add_subregion(get_system_memory(), flash->base_address, &flash->mem);
//    sysbus_init_mmio(dev, &flash->mem);

    flash->data = memory_region_get_ram_ptr(&flash->mem);
    memset(flash->data, 0xff, flash->size);
    if (flash->bdrv) {
        int r;
        r = bdrv_read(flash->bdrv, 0, flash->data, bdrv_getlength(flash->bdrv)/BDRV_SECTOR_SIZE);
        if (r < 0) {
            vmstate_unregister_ram(&flash->mem, DEVICE(flash));
            memory_region_destroy(&flash->mem);
            return 1;
        }
    }

    return 0;
}
示例#4
0
文件: tcx.c 项目: adelina-t/qemu
static void tcx_initfn(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    TCXState *s = TCX(obj);

    memory_region_init_ram(&s->rom, NULL, "tcx.prom", FCODE_MAX_ROM_SIZE,
                           &error_abort);
    memory_region_set_readonly(&s->rom, true);
    sysbus_init_mmio(sbd, &s->rom);

    /* DAC */
    memory_region_init_io(&s->dac, OBJECT(s), &tcx_dac_ops, s,
                          "tcx.dac", TCX_DAC_NREGS);
    sysbus_init_mmio(sbd, &s->dac);

    /* TEC (dummy) */
    memory_region_init_io(&s->tec, OBJECT(s), &dummy_ops, s,
                          "tcx.tec", TCX_TEC_NREGS);
    sysbus_init_mmio(sbd, &s->tec);

    /* THC: NetBSD writes here even with 8-bit display: dummy */
    memory_region_init_io(&s->thc24, OBJECT(s), &dummy_ops, s, "tcx.thc24",
                          TCX_THC_NREGS_24);
    sysbus_init_mmio(sbd, &s->thc24);

    return;
}
示例#5
0
void init_pam(DeviceState *dev, MemoryRegion *ram_memory,
              MemoryRegion *system_memory, MemoryRegion *pci_address_space,
              PAMMemoryRegion *mem, uint32_t start, uint32_t size)
{
    int i;

    /* RAM */
    memory_region_init_alias(&mem->alias[3], OBJECT(dev), "pam-ram", ram_memory,
                             start, size);
    /* ROM (XXX: not quite correct) */
    memory_region_init_alias(&mem->alias[1], OBJECT(dev), "pam-rom", ram_memory,
                             start, size);
    memory_region_set_readonly(&mem->alias[1], true);

    /* XXX: should distinguish read/write cases */
    memory_region_init_alias(&mem->alias[0], OBJECT(dev), "pam-pci", pci_address_space,
                             start, size);
    memory_region_init_alias(&mem->alias[2], OBJECT(dev), "pam-pci", ram_memory,
                             start, size);

    for (i = 0; i < 4; ++i) {
        memory_region_set_enabled(&mem->alias[i], false);
        memory_region_add_subregion_overlap(system_memory, start,
                                            &mem->alias[i], 1);
    }
    mem->current = 0;
}
示例#6
0
static int prom_init1(SysBusDevice *dev)
{
    PROMState *s = FROM_SYSBUS(PROMState, dev);

    memory_region_init_ram(&s->prom, "sun4u.prom", PROM_SIZE_MAX);
    vmstate_register_ram_global(&s->prom);
    memory_region_set_readonly(&s->prom, true);
    sysbus_init_mmio(dev, &s->prom);
    return 0;
}
示例#7
0
文件: sun4m.c 项目: Fantu/qemu
static int idreg_init1(SysBusDevice *dev)
{
    IDRegState *s = MACIO_ID_REGISTER(dev);

    memory_region_init_ram(&s->mem, OBJECT(s),
                           "sun4m.idreg", sizeof(idreg_data), &error_abort);
    vmstate_register_ram_global(&s->mem);
    memory_region_set_readonly(&s->mem, true);
    sysbus_init_mmio(dev, &s->mem);
    return 0;
}
示例#8
0
文件: sun4m.c 项目: Fantu/qemu
static int prom_init1(SysBusDevice *dev)
{
    PROMState *s = OPENPROM(dev);

    memory_region_init_ram(&s->prom, OBJECT(s), "sun4m.prom", PROM_SIZE_MAX,
                           &error_abort);
    vmstate_register_ram_global(&s->prom);
    memory_region_set_readonly(&s->prom, true);
    sysbus_init_mmio(dev, &s->prom);
    return 0;
}
示例#9
0
文件: sun4u.c 项目: Marshalzxy/qemu
static void prom_init1(Object *obj)
{
    PROMState *s = OPENPROM(obj);
    SysBusDevice *dev = SYS_BUS_DEVICE(obj);

    memory_region_init_ram_nomigrate(&s->prom, obj, "sun4u.prom", PROM_SIZE_MAX,
                           &error_fatal);
    vmstate_register_ram_global(&s->prom);
    memory_region_set_readonly(&s->prom, true);
    sysbus_init_mmio(dev, &s->prom);
}
示例#10
0
文件: shix.c 项目: NormanM/qemu
static void shix_init(QEMUMachineInitArgs *args)
{
    const char *cpu_model = args->cpu_model;
    int ret;
    SuperHCPU *cpu;
    struct SH7750State *s;
    MemoryRegion *sysmem = get_system_memory();
    MemoryRegion *rom = g_new(MemoryRegion, 1);
    MemoryRegion *sdram = g_new(MemoryRegion, 2);
    
    if (!cpu_model)
        cpu_model = "any";

    printf("Initializing CPU\n");
    cpu = cpu_sh4_init(cpu_model);
    if (cpu == NULL) {
        fprintf(stderr, "Unable to find CPU definition\n");
        exit(1);
    }

    /* Allocate memory space */
    printf("Allocating ROM\n");
    memory_region_init_ram(rom, NULL, "shix.rom", 0x4000);
    vmstate_register_ram_global(rom);
    memory_region_set_readonly(rom, true);
    memory_region_add_subregion(sysmem, 0x00000000, rom);
    printf("Allocating SDRAM 1\n");
    memory_region_init_ram(&sdram[0], NULL, "shix.sdram1", 0x01000000);
    vmstate_register_ram_global(&sdram[0]);
    memory_region_add_subregion(sysmem, 0x08000000, &sdram[0]);
    printf("Allocating SDRAM 2\n");
    memory_region_init_ram(&sdram[1], NULL, "shix.sdram2", 0x01000000);
    vmstate_register_ram_global(&sdram[1]);
    memory_region_add_subregion(sysmem, 0x0c000000, &sdram[1]);

    /* Load BIOS in 0 (and access it through P2, 0xA0000000) */
    if (bios_name == NULL)
        bios_name = BIOS_FILENAME;
    printf("%s: load BIOS '%s'\n", __func__, bios_name);
    ret = load_image_targphys(bios_name, 0, 0x4000);
    if (ret < 0) {		/* Check bios size */
	fprintf(stderr, "ret=%d\n", ret);
	fprintf(stderr, "qemu: could not load SHIX bios '%s'\n",
		bios_name);
	exit(1);
    }

    /* Register peripherals */
    s = sh7750_init(cpu, sysmem);
    /* XXXXX Check success */
    tc58128_init(s, "shix_linux_nand.bin", NULL);
    fprintf(stderr, "initialization terminated\n");
}
示例#11
0
文件: cg3.c 项目: Acidburn0zzz/qemu
static void cg3_initfn(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    CG3State *s = CG3(obj);

    memory_region_init_ram(&s->rom, NULL, "cg3.prom", FCODE_MAX_ROM_SIZE);
    memory_region_set_readonly(&s->rom, true);
    sysbus_init_mmio(sbd, &s->rom);

    memory_region_init_io(&s->reg, NULL, &cg3_reg_ops, s, "cg3.reg",
                          CG3_REG_SIZE);
    sysbus_init_mmio(sbd, &s->reg);
}
示例#12
0
文件: shix.c 项目: 01org/qemu-lite
static void shix_init(MachineState *machine)
{
    const char *cpu_model = machine->cpu_model;
    int ret;
    SuperHCPU *cpu;
    struct SH7750State *s;
    MemoryRegion *sysmem = get_system_memory();
    MemoryRegion *rom = g_new(MemoryRegion, 1);
    MemoryRegion *sdram = g_new(MemoryRegion, 2);
    
    if (!cpu_model)
        cpu_model = "any";

    cpu = cpu_sh4_init(cpu_model);
    if (cpu == NULL) {
        fprintf(stderr, "Unable to find CPU definition\n");
        exit(1);
    }

    /* Allocate memory space */
    memory_region_init_ram(rom, NULL, "shix.rom", 0x4000, &error_fatal);
    vmstate_register_ram_global(rom);
    memory_region_set_readonly(rom, true);
    memory_region_add_subregion(sysmem, 0x00000000, rom);
    memory_region_init_ram(&sdram[0], NULL, "shix.sdram1", 0x01000000,
                           &error_fatal);
    vmstate_register_ram_global(&sdram[0]);
    memory_region_add_subregion(sysmem, 0x08000000, &sdram[0]);
    memory_region_init_ram(&sdram[1], NULL, "shix.sdram2", 0x01000000,
                           &error_fatal);
    vmstate_register_ram_global(&sdram[1]);
    memory_region_add_subregion(sysmem, 0x0c000000, &sdram[1]);

    /* Load BIOS in 0 (and access it through P2, 0xA0000000) */
    if (bios_name == NULL)
        bios_name = BIOS_FILENAME;
    ret = load_image_targphys(bios_name, 0, 0x4000);
    if (ret < 0 && !qtest_enabled()) {
        error_report("Could not load SHIX bios '%s'", bios_name);
        exit(1);
    }

    /* Register peripherals */
    s = sh7750_init(cpu, sysmem);
    /* XXXXX Check success */
    tc58128_init(s, "shix_linux_nand.bin", NULL);
}
示例#13
0
static void dp8393x_realize(DeviceState *dev, Error **errp)
{
    dp8393xState *s = DP8393X(dev);
    int i, checksum;
    uint8_t *prom;
    Error *local_err = NULL;

    address_space_init(&s->as, s->dma_mr, "dp8393x");
    memory_region_init_io(&s->mmio, OBJECT(dev), &dp8393x_ops, s,
                          "dp8393x-regs", 0x40 << s->it_shift);

    s->nic = qemu_new_nic(&net_dp83932_info, &s->conf,
                          object_get_typename(OBJECT(dev)), dev->id, s);
    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);

    s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s);
    s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */

    memory_region_init_ram(&s->prom, OBJECT(dev),
                           "dp8393x-prom", SONIC_PROM_SIZE, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }
    memory_region_set_readonly(&s->prom, true);
    prom = memory_region_get_ram_ptr(&s->prom);
    checksum = 0;
    for (i = 0; i < 6; i++) {
        prom[i] = s->conf.macaddr.a[i];
        checksum += prom[i];
        if (checksum > 0xff) {
            checksum = (checksum + 1) & 0xff;
        }
    }
    prom[7] = 0xff - checksum;
}
示例#14
0
文件: exynos4210.c 项目: L0op/qemu
Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
        unsigned long ram_size)
{
    int i, n;
    Exynos4210State *s = g_new(Exynos4210State, 1);
    qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
    unsigned long mem_size;
    DeviceState *dev;
    SysBusDevice *busdev;
    ObjectClass *cpu_oc;

    cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, "cortex-a9");
    assert(cpu_oc);

    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
        Object *cpuobj = object_new(object_class_get_name(cpu_oc));
        Error *err = NULL;

        /* By default A9 CPUs have EL3 enabled.  This board does not currently
         * support EL3 so the CPU EL3 property is disabled before realization.
         */
        if (object_property_find(cpuobj, "has_el3", NULL)) {
            object_property_set_bool(cpuobj, false, "has_el3", &err);
            if (err) {
                error_report("%s", error_get_pretty(err));
                exit(1);
            }
        }

        s->cpu[n] = ARM_CPU(cpuobj);
        object_property_set_int(cpuobj, EXYNOS4210_SMP_PRIVATE_BASE_ADDR,
                                "reset-cbar", &error_abort);
        object_property_set_bool(cpuobj, true, "realized", &err);
        if (err) {
            error_report("%s", error_get_pretty(err));
            exit(1);
        }
    }

    /*** IRQs ***/

    s->irq_table = exynos4210_init_irq(&s->irqs);

    /* IRQ Gate */
    for (i = 0; i < EXYNOS4210_NCPUS; i++) {
        dev = qdev_create(NULL, "exynos4210.irq_gate");
        qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
        qdev_init_nofail(dev);
        /* Get IRQ Gate input in gate_irq */
        for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
            gate_irq[i][n] = qdev_get_gpio_in(dev, n);
        }
        busdev = SYS_BUS_DEVICE(dev);

        /* Connect IRQ Gate output to CPU's IRQ line */
        sysbus_connect_irq(busdev, 0,
                           qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
    }

    /* Private memory region and Internal GIC */
    dev = qdev_create(NULL, "a9mpcore_priv");
    qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
        sysbus_connect_irq(busdev, n, gate_irq[n][0]);
    }
    for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
        s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
    }

    /* Cache controller */
    sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);

    /* External GIC */
    dev = qdev_create(NULL, "exynos4210.gic");
    qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    /* Map CPU interface */
    sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
    /* Map Distributer interface */
    sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
        sysbus_connect_irq(busdev, n, gate_irq[n][1]);
    }
    for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
        s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
    }

    /* Internal Interrupt Combiner */
    dev = qdev_create(NULL, "exynos4210.combiner");
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
        sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
    }
    exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
    sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);

    /* External Interrupt Combiner */
    dev = qdev_create(NULL, "exynos4210.combiner");
    qdev_prop_set_uint32(dev, "external", 1);
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
        sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]);
    }
    exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
    sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);

    /* Initialize board IRQs. */
    exynos4210_init_board_irqs(&s->irqs);

    /*** Memory ***/

    /* Chip-ID and OMR */
    memory_region_init_io(&s->chipid_mem, NULL, &exynos4210_chipid_and_omr_ops,
        NULL, "exynos4210.chipid", sizeof(chipid_and_omr));
    memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR,
                                &s->chipid_mem);

    /* Internal ROM */
    memory_region_init_ram(&s->irom_mem, NULL, "exynos4210.irom",
                           EXYNOS4210_IROM_SIZE, &error_abort);
    vmstate_register_ram_global(&s->irom_mem);
    memory_region_set_readonly(&s->irom_mem, true);
    memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR,
                                &s->irom_mem);
    /* mirror of iROM */
    memory_region_init_alias(&s->irom_alias_mem, NULL, "exynos4210.irom_alias",
                             &s->irom_mem,
                             0,
                             EXYNOS4210_IROM_SIZE);
    memory_region_set_readonly(&s->irom_alias_mem, true);
    memory_region_add_subregion(system_mem, EXYNOS4210_IROM_MIRROR_BASE_ADDR,
                                &s->irom_alias_mem);

    /* Internal RAM */
    memory_region_init_ram(&s->iram_mem, NULL, "exynos4210.iram",
                           EXYNOS4210_IRAM_SIZE, &error_abort);
    vmstate_register_ram_global(&s->iram_mem);
    memory_region_add_subregion(system_mem, EXYNOS4210_IRAM_BASE_ADDR,
                                &s->iram_mem);

    /* DRAM */
    mem_size = ram_size;
    if (mem_size > EXYNOS4210_DRAM_MAX_SIZE) {
        memory_region_init_ram(&s->dram1_mem, NULL, "exynos4210.dram1",
                mem_size - EXYNOS4210_DRAM_MAX_SIZE, &error_abort);
        vmstate_register_ram_global(&s->dram1_mem);
        memory_region_add_subregion(system_mem, EXYNOS4210_DRAM1_BASE_ADDR,
                &s->dram1_mem);
        mem_size = EXYNOS4210_DRAM_MAX_SIZE;
    }
    memory_region_init_ram(&s->dram0_mem, NULL, "exynos4210.dram0", mem_size,
                           &error_abort);
    vmstate_register_ram_global(&s->dram0_mem);
    memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
            &s->dram0_mem);

   /* PMU.
    * The only reason of existence at the moment is that secondary CPU boot
    * loader uses PMU INFORM5 register as a holding pen.
    */
    sysbus_create_simple("exynos4210.pmu", EXYNOS4210_PMU_BASE_ADDR, NULL);

    /* PWM */
    sysbus_create_varargs("exynos4210.pwm", EXYNOS4210_PWM_BASE_ADDR,
                          s->irq_table[exynos4210_get_irq(22, 0)],
                          s->irq_table[exynos4210_get_irq(22, 1)],
                          s->irq_table[exynos4210_get_irq(22, 2)],
                          s->irq_table[exynos4210_get_irq(22, 3)],
                          s->irq_table[exynos4210_get_irq(22, 4)],
                          NULL);
    /* RTC */
    sysbus_create_varargs("exynos4210.rtc", EXYNOS4210_RTC_BASE_ADDR,
                          s->irq_table[exynos4210_get_irq(23, 0)],
                          s->irq_table[exynos4210_get_irq(23, 1)],
                          NULL);

    /* Multi Core Timer */
    dev = qdev_create(NULL, "exynos4210.mct");
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    for (n = 0; n < 4; n++) {
        /* Connect global timer interrupts to Combiner gpio_in */
        sysbus_connect_irq(busdev, n,
                s->irq_table[exynos4210_get_irq(1, 4 + n)]);
    }
    /* Connect local timer interrupts to Combiner gpio_in */
    sysbus_connect_irq(busdev, 4,
            s->irq_table[exynos4210_get_irq(51, 0)]);
    sysbus_connect_irq(busdev, 5,
            s->irq_table[exynos4210_get_irq(35, 3)]);
    sysbus_mmio_map(busdev, 0, EXYNOS4210_MCT_BASE_ADDR);

    /*** I2C ***/
    for (n = 0; n < EXYNOS4210_I2C_NUMBER; n++) {
        uint32_t addr = EXYNOS4210_I2C_BASE_ADDR + EXYNOS4210_I2C_SHIFT * n;
        qemu_irq i2c_irq;

        if (n < 8) {
            i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_I2C_INTG, n)];
        } else {
            i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_HDMI_INTG, 1)];
        }

        dev = qdev_create(NULL, "exynos4210.i2c");
        qdev_init_nofail(dev);
        busdev = SYS_BUS_DEVICE(dev);
        sysbus_connect_irq(busdev, 0, i2c_irq);
        sysbus_mmio_map(busdev, 0, addr);
        s->i2c_if[n] = (I2CBus *)qdev_get_child_bus(dev, "i2c");
    }


    /*** UARTs ***/
    exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
                           EXYNOS4210_UART0_FIFO_SIZE, 0, NULL,
                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 0)]);

    exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
                           EXYNOS4210_UART1_FIFO_SIZE, 1, NULL,
                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 1)]);

    exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
                           EXYNOS4210_UART2_FIFO_SIZE, 2, NULL,
                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 2)]);

    exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
                           EXYNOS4210_UART3_FIFO_SIZE, 3, NULL,
                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 3)]);

    /*** Display controller (FIMD) ***/
    sysbus_create_varargs("exynos4210.fimd", EXYNOS4210_FIMD0_BASE_ADDR,
            s->irq_table[exynos4210_get_irq(11, 0)],
            s->irq_table[exynos4210_get_irq(11, 1)],
            s->irq_table[exynos4210_get_irq(11, 2)],
            NULL);

    sysbus_create_simple(TYPE_EXYNOS4210_EHCI, EXYNOS4210_EHCI_BASE_ADDR,
            s->irq_table[exynos4210_get_irq(28, 3)]);

    return s;
}
示例#15
0
static void sx1_init(MachineState *machine, const int version)
{
    struct omap_mpu_state_s *mpu;
    MemoryRegion *address_space = get_system_memory();
    MemoryRegion *flash = g_new(MemoryRegion, 1);
    MemoryRegion *cs = g_new(MemoryRegion, 4);
    static uint32_t cs0val = 0x00213090;
    static uint32_t cs1val = 0x00215070;
    static uint32_t cs2val = 0x00001139;
    static uint32_t cs3val = 0x00001139;
    DriveInfo *dinfo;
    int fl_idx;
    uint32_t flash_size = flash0_size;
    int be;

    if (version == 2) {
        flash_size = flash2_size;
    }

    mpu = omap310_mpu_init(address_space, sx1_binfo.ram_size,
                           machine->cpu_type);

    /* External Flash (EMIFS) */
    memory_region_init_ram(flash, NULL, "omap_sx1.flash0-0", flash_size,
                           &error_fatal);
    memory_region_set_readonly(flash, true);
    memory_region_add_subregion(address_space, OMAP_CS0_BASE, flash);

    memory_region_init_io(&cs[0], NULL, &static_ops, &cs0val,
                          "sx1.cs0", OMAP_CS0_SIZE - flash_size);
    memory_region_add_subregion(address_space,
                                OMAP_CS0_BASE + flash_size, &cs[0]);


    memory_region_init_io(&cs[2], NULL, &static_ops, &cs2val,
                          "sx1.cs2", OMAP_CS2_SIZE);
    memory_region_add_subregion(address_space,
                                OMAP_CS2_BASE, &cs[2]);

    memory_region_init_io(&cs[3], NULL, &static_ops, &cs3val,
                          "sx1.cs3", OMAP_CS3_SIZE);
    memory_region_add_subregion(address_space,
                                OMAP_CS2_BASE, &cs[3]);

    fl_idx = 0;
#ifdef TARGET_WORDS_BIGENDIAN
    be = 1;
#else
    be = 0;
#endif

    if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
        if (!pflash_cfi01_register(OMAP_CS0_BASE,
                                   "omap_sx1.flash0-1", flash_size,
                                   blk_by_legacy_dinfo(dinfo),
                                   sector_size, 4, 0, 0, 0, 0, be)) {
            fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                           fl_idx);
        }
        fl_idx++;
    }

    if ((version == 1) &&
            (dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
        MemoryRegion *flash_1 = g_new(MemoryRegion, 1);
        memory_region_init_ram(flash_1, NULL, "omap_sx1.flash1-0",
                               flash1_size, &error_fatal);
        memory_region_set_readonly(flash_1, true);
        memory_region_add_subregion(address_space, OMAP_CS1_BASE, flash_1);

        memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val,
                              "sx1.cs1", OMAP_CS1_SIZE - flash1_size);
        memory_region_add_subregion(address_space,
                                OMAP_CS1_BASE + flash1_size, &cs[1]);

        if (!pflash_cfi01_register(OMAP_CS1_BASE,
                                   "omap_sx1.flash1-1", flash1_size,
                                   blk_by_legacy_dinfo(dinfo),
                                   sector_size, 4, 0, 0, 0, 0, be)) {
            fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                           fl_idx);
        }
        fl_idx++;
    } else {
        memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val,
                              "sx1.cs1", OMAP_CS1_SIZE);
        memory_region_add_subregion(address_space,
                                OMAP_CS1_BASE, &cs[1]);
    }

    if (!machine->kernel_filename && !fl_idx && !qtest_enabled()) {
        error_report("Kernel or Flash image must be specified");
        exit(1);
    }

    /* Load the kernel.  */
    sx1_binfo.kernel_filename = machine->kernel_filename;
    sx1_binfo.kernel_cmdline = machine->kernel_cmdline;
    sx1_binfo.initrd_filename = machine->initrd_filename;
    arm_load_kernel(mpu->cpu, &sx1_binfo);

    /* TODO: fix next line */
    //~ qemu_console_resize(ds, 640, 480);
}
示例#16
0
static void ppc_heathrow_init(QEMUMachineInitArgs *args)
{
    ram_addr_t ram_size = args->ram_size;
    const char *cpu_model = args->cpu_model;
    const char *kernel_filename = args->kernel_filename;
    const char *kernel_cmdline = args->kernel_cmdline;
    const char *initrd_filename = args->initrd_filename;
    const char *boot_device = args->boot_device;
    MemoryRegion *sysmem = get_system_memory();
    PowerPCCPU *cpu = NULL;
    CPUPPCState *env = NULL;
    char *filename;
    qemu_irq *pic, **heathrow_irqs;
    int linux_boot, i;
    MemoryRegion *ram = g_new(MemoryRegion, 1);
    MemoryRegion *bios = g_new(MemoryRegion, 1);
    uint32_t kernel_base, initrd_base, cmdline_base = 0;
    int32_t kernel_size, initrd_size;
    PCIBus *pci_bus;
    PCIDevice *macio;
    MACIOIDEState *macio_ide;
    DeviceState *dev;
    BusState *adb_bus;
    int bios_size;
    MemoryRegion *pic_mem;
    MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1);
    uint16_t ppc_boot_device;
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
    void *fw_cfg;

    linux_boot = (kernel_filename != NULL);

    /* init CPUs */
    if (cpu_model == NULL)
        cpu_model = "G3";
    for (i = 0; i < smp_cpus; i++) {
        cpu = cpu_ppc_init(cpu_model);
        if (cpu == NULL) {
            fprintf(stderr, "Unable to find PowerPC CPU definition\n");
            exit(1);
        }
        env = &cpu->env;

        /* Set time-base frequency to 16.6 Mhz */
        cpu_ppc_tb_init(env,  16600000UL);
        qemu_register_reset(ppc_heathrow_reset, cpu);
    }

    /* allocate RAM */
    if (ram_size > (2047 << 20)) {
        fprintf(stderr,
                "qemu: Too much memory for this machine: %d MB, maximum 2047 MB\n",
                ((unsigned int)ram_size / (1 << 20)));
        exit(1);
    }

    memory_region_init_ram(ram, "ppc_heathrow.ram", ram_size);
    vmstate_register_ram_global(ram);
    memory_region_add_subregion(sysmem, 0, ram);

    /* allocate and load BIOS */
    memory_region_init_ram(bios, "ppc_heathrow.bios", BIOS_SIZE);
    vmstate_register_ram_global(bios);
    if (bios_name == NULL)
        bios_name = PROM_FILENAME;
    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
    memory_region_set_readonly(bios, true);
    memory_region_add_subregion(sysmem, PROM_ADDR, bios);

    /* Load OpenBIOS (ELF) */
    if (filename) {
        bios_size = load_elf(filename, 0, NULL, NULL, NULL, NULL,
                             1, ELF_MACHINE, 0);
        g_free(filename);
    } else {
        bios_size = -1;
    }
    if (bios_size < 0 || bios_size > BIOS_SIZE) {
        hw_error("qemu: could not load PowerPC bios '%s'\n", bios_name);
        exit(1);
    }

    if (linux_boot) {
        uint64_t lowaddr = 0;
        int bswap_needed;

#ifdef BSWAP_NEEDED
        bswap_needed = 1;
#else
        bswap_needed = 0;
#endif
        kernel_base = KERNEL_LOAD_ADDR;
        kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
                               NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0);
        if (kernel_size < 0)
            kernel_size = load_aout(kernel_filename, kernel_base,
                                    ram_size - kernel_base, bswap_needed,
                                    TARGET_PAGE_SIZE);
        if (kernel_size < 0)
            kernel_size = load_image_targphys(kernel_filename,
                                              kernel_base,
                                              ram_size - kernel_base);
        if (kernel_size < 0) {
            hw_error("qemu: could not load kernel '%s'\n",
                      kernel_filename);
            exit(1);
        }
        /* load initrd */
        if (initrd_filename) {
            initrd_base = round_page(kernel_base + kernel_size + KERNEL_GAP);
            initrd_size = load_image_targphys(initrd_filename, initrd_base,
                                              ram_size - initrd_base);
            if (initrd_size < 0) {
                hw_error("qemu: could not load initial ram disk '%s'\n",
                         initrd_filename);
                exit(1);
            }
            cmdline_base = round_page(initrd_base + initrd_size);
        } else {
            initrd_base = 0;
            initrd_size = 0;
            cmdline_base = round_page(kernel_base + kernel_size + KERNEL_GAP);
        }
        ppc_boot_device = 'm';
    } else {
        kernel_base = 0;
        kernel_size = 0;
        initrd_base = 0;
        initrd_size = 0;
        ppc_boot_device = '\0';
        for (i = 0; boot_device[i] != '\0'; i++) {
            /* TOFIX: for now, the second IDE channel is not properly
             *        used by OHW. The Mac floppy disk are not emulated.
             *        For now, OHW cannot boot from the network.
             */
#if 0
            if (boot_device[i] >= 'a' && boot_device[i] <= 'f') {
                ppc_boot_device = boot_device[i];
                break;
            }
#else
            if (boot_device[i] >= 'c' && boot_device[i] <= 'd') {
                ppc_boot_device = boot_device[i];
                break;
            }
#endif
        }
        if (ppc_boot_device == '\0') {
            fprintf(stderr, "No valid boot device for G3 Beige machine\n");
            exit(1);
        }
    }

    /* Register 2 MB of ISA IO space */
    isa_mmio_init(0xfe000000, 0x00200000);

    /* XXX: we register only 1 output pin for heathrow PIC */
    heathrow_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
    heathrow_irqs[0] =
        g_malloc0(smp_cpus * sizeof(qemu_irq) * 1);
    /* Connect the heathrow PIC outputs to the 6xx bus */
    for (i = 0; i < smp_cpus; i++) {
        switch (PPC_INPUT(env)) {
        case PPC_FLAGS_INPUT_6xx:
            heathrow_irqs[i] = heathrow_irqs[0] + (i * 1);
            heathrow_irqs[i][0] =
                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
            break;
        default:
            hw_error("Bus model not supported on OldWorld Mac machine\n");
        }
    }

    /* init basic PC hardware */
    if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
        hw_error("Only 6xx bus is supported on heathrow machine\n");
    }
    pic = heathrow_pic_init(&pic_mem, 1, heathrow_irqs);
    pci_bus = pci_grackle_init(0xfec00000, pic,
                               get_system_memory(),
                               get_system_io());
    pci_vga_init(pci_bus);

    escc_mem = escc_init(0, pic[0x0f], pic[0x10], serial_hds[0],
                               serial_hds[1], ESCC_CLOCK, 4);
    memory_region_init_alias(escc_bar, "escc-bar",
                             escc_mem, 0, memory_region_size(escc_mem));

    for(i = 0; i < nb_nics; i++)
        pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);


    ide_drive_get(hd, MAX_IDE_BUS);

    macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO);
    dev = DEVICE(macio);
    qdev_connect_gpio_out(dev, 0, pic[0x12]); /* CUDA */
    qdev_connect_gpio_out(dev, 1, pic[0x0D]); /* IDE */
    qdev_connect_gpio_out(dev, 2, pic[0x02]); /* IDE DMA */
    macio_init(macio, pic_mem, escc_bar);

    /* First IDE channel is a MAC IDE on the MacIO bus */
    macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
                                                        "ide"));
    macio_ide_init_drives(macio_ide, hd);

    /* Second IDE channel is a CMD646 on the PCI bus */
    hd[0] = hd[MAX_IDE_DEVS];
    hd[1] = hd[MAX_IDE_DEVS + 1];
    hd[3] = hd[2] = NULL;
    pci_cmd646_ide_init(pci_bus, hd, 0);

    dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda"));
    adb_bus = qdev_get_child_bus(dev, "adb.0");
    dev = qdev_create(adb_bus, TYPE_ADB_KEYBOARD);
    qdev_init_nofail(dev);
    dev = qdev_create(adb_bus, TYPE_ADB_MOUSE);
    qdev_init_nofail(dev);

    if (usb_enabled(false)) {
        pci_create_simple(pci_bus, -1, "pci-ohci");
    }

    if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
        graphic_depth = 15;

    /* No PCI init: the BIOS will do it */

    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW);
    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
    if (kernel_cmdline) {
        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base);
        pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline);
    } else {
        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
    }
    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base);
    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device);

    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width);
    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height);
    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth);

    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
    if (kvm_enabled()) {
#ifdef CONFIG_KVM
        uint8_t *hypercall;

        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq());
        hypercall = g_malloc(16);
        kvmppc_get_hypercall(env, hypercall, 16);
        fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
#endif
    } else {
        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec());
    }

    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
}
示例#17
0
Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
        unsigned long ram_size)
{
    qemu_irq cpu_irq[EXYNOS4210_NCPUS];
    int i, n;
    Exynos4210State *s = g_new(Exynos4210State, 1);
    qemu_irq *irqp;
    qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
    unsigned long mem_size;
    DeviceState *dev;
    SysBusDevice *busdev;

    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
        s->cpu[n] = cpu_arm_init("cortex-a9");
        if (!s->cpu[n]) {
            fprintf(stderr, "Unable to find CPU %d definition\n", n);
            exit(1);
        }

        /* Create PIC controller for each processor instance */
        irqp = arm_pic_init_cpu(s->cpu[n]);

        /*
         * Get GICs gpio_in cpu_irq to connect a combiner to them later.
         * Use only IRQ for a while.
         */
        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
    }

    /*** IRQs ***/

    s->irq_table = exynos4210_init_irq(&s->irqs);

    /* IRQ Gate */
    for (i = 0; i < EXYNOS4210_NCPUS; i++) {
        dev = qdev_create(NULL, "exynos4210.irq_gate");
        qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
        qdev_init_nofail(dev);
        /* Get IRQ Gate input in gate_irq */
        for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
            gate_irq[i][n] = qdev_get_gpio_in(dev, n);
        }
        busdev = SYS_BUS_DEVICE(dev);

        /* Connect IRQ Gate output to cpu_irq */
        sysbus_connect_irq(busdev, 0, cpu_irq[i]);
    }

    /* Private memory region and Internal GIC */
    dev = qdev_create(NULL, "a9mpcore_priv");
    qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
        sysbus_connect_irq(busdev, n, gate_irq[n][0]);
    }
    for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
        s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
    }

    /* Cache controller */
    sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);

    /* External GIC */
    dev = qdev_create(NULL, "exynos4210.gic");
    qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    /* Map CPU interface */
    sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
    /* Map Distributer interface */
    sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
        sysbus_connect_irq(busdev, n, gate_irq[n][1]);
    }
    for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
        s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
    }

    /* Internal Interrupt Combiner */
    dev = qdev_create(NULL, "exynos4210.combiner");
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
        sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
    }
    exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
    sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);

    /* External Interrupt Combiner */
    dev = qdev_create(NULL, "exynos4210.combiner");
    qdev_prop_set_uint32(dev, "external", 1);
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
        sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]);
    }
    exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
    sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);

    /* Initialize board IRQs. */
    exynos4210_init_board_irqs(&s->irqs);

    /*** Memory ***/

    /* Chip-ID and OMR */
    memory_region_init_ram_ptr(&s->chipid_mem, "exynos4210.chipid",
            sizeof(chipid_and_omr), chipid_and_omr);
    memory_region_set_readonly(&s->chipid_mem, true);
    memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR,
                                &s->chipid_mem);

    /* Internal ROM */
    memory_region_init_ram(&s->irom_mem, "exynos4210.irom",
                           EXYNOS4210_IROM_SIZE);
    memory_region_set_readonly(&s->irom_mem, true);
    memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR,
                                &s->irom_mem);
    /* mirror of iROM */
    memory_region_init_alias(&s->irom_alias_mem, "exynos4210.irom_alias",
                             &s->irom_mem,
                             0,
                             EXYNOS4210_IROM_SIZE);
    memory_region_set_readonly(&s->irom_alias_mem, true);
    memory_region_add_subregion(system_mem, EXYNOS4210_IROM_MIRROR_BASE_ADDR,
                                &s->irom_alias_mem);

    /* Internal RAM */
    memory_region_init_ram(&s->iram_mem, "exynos4210.iram",
                           EXYNOS4210_IRAM_SIZE);
    vmstate_register_ram_global(&s->iram_mem);
    memory_region_add_subregion(system_mem, EXYNOS4210_IRAM_BASE_ADDR,
                                &s->iram_mem);

    /* DRAM */
    mem_size = ram_size;
    if (mem_size > EXYNOS4210_DRAM_MAX_SIZE) {
        memory_region_init_ram(&s->dram1_mem, "exynos4210.dram1",
                mem_size - EXYNOS4210_DRAM_MAX_SIZE);
        vmstate_register_ram_global(&s->dram1_mem);
        memory_region_add_subregion(system_mem, EXYNOS4210_DRAM1_BASE_ADDR,
                &s->dram1_mem);
        mem_size = EXYNOS4210_DRAM_MAX_SIZE;
    }
    memory_region_init_ram(&s->dram0_mem, "exynos4210.dram0", mem_size);
    vmstate_register_ram_global(&s->dram0_mem);
    memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
            &s->dram0_mem);

   /* PMU.
    * The only reason of existence at the moment is that secondary CPU boot
    * loader uses PMU INFORM5 register as a holding pen.
    */
    sysbus_create_simple("exynos4210.pmu", EXYNOS4210_PMU_BASE_ADDR, NULL);

    /* PWM */
    sysbus_create_varargs("exynos4210.pwm", EXYNOS4210_PWM_BASE_ADDR,
                          s->irq_table[exynos4210_get_irq(22, 0)],
                          s->irq_table[exynos4210_get_irq(22, 1)],
                          s->irq_table[exynos4210_get_irq(22, 2)],
                          s->irq_table[exynos4210_get_irq(22, 3)],
                          s->irq_table[exynos4210_get_irq(22, 4)],
                          NULL);
    /* RTC */
    sysbus_create_varargs("exynos4210.rtc", EXYNOS4210_RTC_BASE_ADDR,
                          s->irq_table[exynos4210_get_irq(23, 0)],
                          s->irq_table[exynos4210_get_irq(23, 1)],
                          NULL);

    /* Multi Core Timer */
    dev = qdev_create(NULL, "exynos4210.mct");
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    for (n = 0; n < 4; n++) {
        /* Connect global timer interrupts to Combiner gpio_in */
        sysbus_connect_irq(busdev, n,
                s->irq_table[exynos4210_get_irq(1, 4 + n)]);
    }
    /* Connect local timer interrupts to Combiner gpio_in */
    sysbus_connect_irq(busdev, 4,
            s->irq_table[exynos4210_get_irq(51, 0)]);
    sysbus_connect_irq(busdev, 5,
            s->irq_table[exynos4210_get_irq(35, 3)]);
    sysbus_mmio_map(busdev, 0, EXYNOS4210_MCT_BASE_ADDR);

    /*** I2C ***/
    for (n = 0; n < EXYNOS4210_I2C_NUMBER; n++) {
        uint32_t addr = EXYNOS4210_I2C_BASE_ADDR + EXYNOS4210_I2C_SHIFT * n;
        qemu_irq i2c_irq;

        if (n < 8) {
            i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_I2C_INTG, n)];
        } else {
            i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_HDMI_INTG, 1)];
        }

        dev = qdev_create(NULL, "exynos4210.i2c");
        qdev_init_nofail(dev);
        busdev = SYS_BUS_DEVICE(dev);
        sysbus_connect_irq(busdev, 0, i2c_irq);
        sysbus_mmio_map(busdev, 0, addr);
        s->i2c_if[n] = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
    }


    /*** UARTs ***/
    exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
                           EXYNOS4210_UART0_FIFO_SIZE, 0, NULL,
                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 0)]);

    exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
                           EXYNOS4210_UART1_FIFO_SIZE, 1, NULL,
                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 1)]);

    exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
                           EXYNOS4210_UART2_FIFO_SIZE, 2, NULL,
                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 2)]);

    exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
                           EXYNOS4210_UART3_FIFO_SIZE, 3, NULL,
                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 3)]);

    /*** Display controller (FIMD) ***/
    sysbus_create_varargs("exynos4210.fimd", EXYNOS4210_FIMD0_BASE_ADDR,
            s->irq_table[exynos4210_get_irq(11, 0)],
            s->irq_table[exynos4210_get_irq(11, 1)],
            s->irq_table[exynos4210_get_irq(11, 2)],
            NULL);

    sysbus_create_simple(TYPE_EXYNOS4210_EHCI, EXYNOS4210_EHCI_BASE_ADDR,
            s->irq_table[exynos4210_get_irq(28, 3)]);

    return s;
}
示例#18
0
文件: xbox.c 项目: JayFoxRox/xqemu
static void xbox_flash_init(MemoryRegion *rom_memory)
{
    char *filename;
    int bios_size;
    int bootrom_size;

    MemoryRegion *bios;
    MemoryRegion *map_bios;

    uint32_t map_loc;
    int rc, fd = -1;

    char *bios_data;

    /* Locate BIOS ROM image */
    if (bios_name == NULL) {
        bios_name = "bios.bin";
    }

    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
    if (filename) {
        bios_size = get_image_size(filename);
    } else {
        bios_size = -1;
    }
    if (bios_size <= 0 ||
        (bios_size % 65536) != 0) {
        goto bios_error;
    }

    /* Read BIOS ROM into memory */
    bios_data = g_malloc(bios_size);
    assert(bios_data != NULL);
    fd = open(filename, O_RDONLY | O_BINARY);
    assert(fd >= 0);
    rc = read(fd, bios_data, bios_size);
    assert(rc == bios_size);
    close(fd);
    g_free(filename);

    /* XBOX_FIXME: What follows is a big hack to overlay the MCPX ROM on the
     * top 512 bytes of the ROM region. This differs from original XQEMU
     * sources which copied it in at lpc init; new QEMU seems to be different
     * now in that the BIOS images supplied to rom_add_file_fixed will be
     * loaded *after* lpc init is called, so the MCPX ROM would get
     * overwritten. Instead, let's just map it in right here while we map in
     * BIOS.
     *
     * Anyway it behaves the same as before--that is, wrongly. Really, we
     * should let the CPU execute from MMIO emulating the TSOP access with
     * bootrom overlay being controlled by the magic bit..but this is "good
     * enough" for now ;).
     */

    /* Locate and overlay MCPX ROM image into new copy of BIOS if provided */
    const char *bootrom_file = object_property_get_str(qdev_get_machine(),
                                                       "bootrom", NULL);

    if ((bootrom_file != NULL) && *bootrom_file) {
        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bootrom_file);
        assert(filename);

        bootrom_size = get_image_size(filename);
        if (bootrom_size != 512) {
            fprintf(stderr, "MCPX bootrom should be 512 bytes, got %d\n",
                    bootrom_size);
            exit(1);
            return;
        }

        /* Read in MCPX ROM over last 512 bytes of BIOS data */
        fd = open(filename, O_RDONLY | O_BINARY);
        assert(fd >= 0);
        rc = read(fd, &bios_data[bios_size - bootrom_size], bootrom_size);
        assert(rc == bootrom_size);
        close(fd);
        g_free(filename);
    }

    /* Create BIOS region */
    bios = g_malloc(sizeof(*bios));
    assert(bios != NULL);
    memory_region_init_ram(bios, NULL, "xbox.bios", bios_size, &error_fatal);
    memory_region_set_readonly(bios, true);
    rom_add_blob_fixed("xbox.bios", bios_data, bios_size,
                       (uint32_t)(-2 * bios_size));

    /* Assuming bios_data will be needed for duration of execution
     * so no free(bios) here.
     */

    /* Mirror ROM from 0xff000000 - 0xffffffff */
    for (map_loc = (uint32_t)(-bios_size);
         map_loc >= 0xff000000;
         map_loc -= bios_size) {
        map_bios = g_malloc(sizeof(*map_bios));
        memory_region_init_alias(map_bios, NULL, "pci-bios", bios, 0, bios_size);
        memory_region_add_subregion(rom_memory, map_loc, map_bios);
        memory_region_set_readonly(map_bios, true);
    }

    return;

bios_error:
    fprintf(stderr, "qemu: could not load xbox BIOS '%s'\n", bios_name);
    exit(1);
}
示例#19
0
文件: palm.c 项目: Kozzi11/qemu
static void palmte_init(MachineState *machine)
{
    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;
    MemoryRegion *address_space_mem = get_system_memory();
    struct omap_mpu_state_s *mpu;
    int flash_size = 0x00800000;
    int sdram_size = palmte_binfo.ram_size;
    static uint32_t cs0val = 0xffffffff;
    static uint32_t cs1val = 0x0000e1a0;
    static uint32_t cs2val = 0x0000e1a0;
    static uint32_t cs3val = 0xe1a0e1a0;
    int rom_size, rom_loaded = 0;
    MemoryRegion *flash = g_new(MemoryRegion, 1);
    MemoryRegion *cs = g_new(MemoryRegion, 4);

    mpu = omap310_mpu_init(address_space_mem, sdram_size, cpu_model);

    /* External Flash (EMIFS) */
    memory_region_init_ram(flash, NULL, "palmte.flash", flash_size);
    vmstate_register_ram_global(flash);
    memory_region_set_readonly(flash, true);
    memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE, flash);

    memory_region_init_io(&cs[0], NULL, &static_ops, &cs0val, "palmte-cs0",
                          OMAP_CS0_SIZE - flash_size);
    memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE + flash_size,
                                &cs[0]);
    memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val, "palmte-cs1",
                          OMAP_CS1_SIZE);
    memory_region_add_subregion(address_space_mem, OMAP_CS1_BASE, &cs[1]);
    memory_region_init_io(&cs[2], NULL, &static_ops, &cs2val, "palmte-cs2",
                          OMAP_CS2_SIZE);
    memory_region_add_subregion(address_space_mem, OMAP_CS2_BASE, &cs[2]);
    memory_region_init_io(&cs[3], NULL, &static_ops, &cs3val, "palmte-cs3",
                          OMAP_CS3_SIZE);
    memory_region_add_subregion(address_space_mem, OMAP_CS3_BASE, &cs[3]);

    palmte_microwire_setup(mpu);

    qemu_add_kbd_event_handler(palmte_button_event, mpu);

    palmte_gpio_setup(mpu);

    /* Setup initial (reset) machine state */
    if (nb_option_roms) {
        rom_size = get_image_size(option_rom[0].name);
        if (rom_size > flash_size) {
            fprintf(stderr, "%s: ROM image too big (%x > %x)\n",
                    __FUNCTION__, rom_size, flash_size);
            rom_size = 0;
        }
        if (rom_size > 0) {
            rom_size = load_image_targphys(option_rom[0].name, OMAP_CS0_BASE,
                                           flash_size);
            rom_loaded = 1;
        }
        if (rom_size < 0) {
            fprintf(stderr, "%s: error loading '%s'\n",
                    __FUNCTION__, option_rom[0].name);
        }
    }

    if (!rom_loaded && !kernel_filename && !qtest_enabled()) {
        fprintf(stderr, "Kernel or ROM image must be specified\n");
        exit(1);
    }

    /* Load the kernel.  */
    palmte_binfo.kernel_filename = kernel_filename;
    palmte_binfo.kernel_cmdline = kernel_cmdline;
    palmte_binfo.initrd_filename = initrd_filename;
    arm_load_kernel(mpu->cpu, &palmte_binfo);
}
示例#20
0
static void leon3_generic_hw_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;
    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;
    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_init_ram(ram, "leon3.ram", ram_size);
    vmstate_register_ram_global(ram);
    memory_region_add_subregion(address_space_mem, 0x40000000, ram);

    /* Allocate BIOS */
    prom_size = 8 * 1024 * 1024; /* 8Mb */
    memory_region_init_ram(prom, "Leon3.bios", prom_size);
    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) {
        fprintf(stderr, "Can't read bios image %s\n", filename);
        exit(1);
    }

    /* 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]);
    }
}
示例#21
0
文件: mainstone.c 项目: sevikkk/qemu
static void mainstone_common_init(MemoryRegion *address_space_mem,
                ram_addr_t ram_size,
                const char *kernel_filename,
                const char *kernel_cmdline, const char *initrd_filename,
                const char *cpu_model, enum mainstone_model_e model, int arm_id)
{
    uint32_t sector_len = 256 * 1024;
    hwaddr mainstone_flash_base[] = { MST_FLASH_0, MST_FLASH_1 };
    PXA2xxState *mpu;
    DeviceState *mst_irq;
    DriveInfo *dinfo;
    int i;
    int be;
    MemoryRegion *rom = g_new(MemoryRegion, 1);

    if (!cpu_model)
        cpu_model = "pxa270-c5";

    /* Setup CPU & memory */
    mpu = pxa270_init(address_space_mem, mainstone_binfo.ram_size, cpu_model);
    memory_region_init_ram(rom, "mainstone.rom", MAINSTONE_ROM);
    vmstate_register_ram_global(rom);
    memory_region_set_readonly(rom, true);
    memory_region_add_subregion(address_space_mem, 0, rom);

#ifdef TARGET_WORDS_BIGENDIAN
    be = 1;
#else
    be = 0;
#endif
    /* There are two 32MiB flash devices on the board */
    for (i = 0; i < 2; i ++) {
        dinfo = drive_get(IF_PFLASH, 0, i);
        if (!dinfo) {
            fprintf(stderr, "Two flash images must be given with the "
                    "'pflash' parameter\n");
            exit(1);
        }

        if (!pflash_cfi01_register(mainstone_flash_base[i], NULL,
                                   i ? "mainstone.flash1" : "mainstone.flash0",
                                   MAINSTONE_FLASH,
                                   dinfo->bdrv, sector_len,
                                   MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, 0,
                                   be)) {
            fprintf(stderr, "qemu: Error registering flash memory.\n");
            exit(1);
        }
    }

    mst_irq = sysbus_create_simple("mainstone-fpga", MST_FPGA_PHYS,
                    qdev_get_gpio_in(mpu->gpio, 0));

    /* setup keypad */
    printf("map addr %p\n", &map);
    pxa27x_register_keypad(mpu->kp, map, 0xe0);

    /* MMC/SD host */
    pxa2xx_mmci_handlers(mpu->mmc, NULL, qdev_get_gpio_in(mst_irq, MMC_IRQ));

    pxa2xx_pcmcia_set_irq_cb(mpu->pcmcia[0],
            qdev_get_gpio_in(mst_irq, S0_IRQ),
            qdev_get_gpio_in(mst_irq, S0_CD_IRQ));
    pxa2xx_pcmcia_set_irq_cb(mpu->pcmcia[1],
            qdev_get_gpio_in(mst_irq, S1_IRQ),
            qdev_get_gpio_in(mst_irq, S1_CD_IRQ));

    smc91c111_init(&nd_table[0], MST_ETH_PHYS,
                    qdev_get_gpio_in(mst_irq, ETHERNET_IRQ));

    mainstone_binfo.kernel_filename = kernel_filename;
    mainstone_binfo.kernel_cmdline = kernel_cmdline;
    mainstone_binfo.initrd_filename = initrd_filename;
    mainstone_binfo.board_id = arm_id;
    arm_load_kernel(mpu->cpu, &mainstone_binfo);
}
示例#22
0
static void ppc_heathrow_init(MachineState *machine)
{
    ram_addr_t ram_size = machine->ram_size;
    const char *kernel_filename = machine->kernel_filename;
    const char *kernel_cmdline = machine->kernel_cmdline;
    const char *initrd_filename = machine->initrd_filename;
    const char *boot_device = machine->boot_order;
    MemoryRegion *sysmem = get_system_memory();
    PowerPCCPU *cpu = NULL;
    CPUPPCState *env = NULL;
    char *filename;
    int linux_boot, i;
    MemoryRegion *ram = g_new(MemoryRegion, 1);
    MemoryRegion *bios = g_new(MemoryRegion, 1);
    uint32_t kernel_base, initrd_base, cmdline_base = 0;
    int32_t kernel_size, initrd_size;
    PCIBus *pci_bus;
    OldWorldMacIOState *macio;
    MACIOIDEState *macio_ide;
    SysBusDevice *s;
    DeviceState *dev, *pic_dev;
    BusState *adb_bus;
    int bios_size;
    uint16_t ppc_boot_device;
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
    void *fw_cfg;
    uint64_t tbfreq;

    linux_boot = (kernel_filename != NULL);

    /* init CPUs */
    for (i = 0; i < smp_cpus; i++) {
        cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
        env = &cpu->env;

        /* Set time-base frequency to 16.6 Mhz */
        cpu_ppc_tb_init(env,  TBFREQ);
        qemu_register_reset(ppc_heathrow_reset, cpu);
    }

    /* allocate RAM */
    if (ram_size > 2047 * MiB) {
        error_report("Too much memory for this machine: %" PRId64 " MB, "
                     "maximum 2047 MB", ram_size / MiB);
        exit(1);
    }

    memory_region_allocate_system_memory(ram, NULL, "ppc_heathrow.ram",
                                         ram_size);
    memory_region_add_subregion(sysmem, 0, ram);

    /* allocate and load BIOS */
    memory_region_init_ram(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE,
                           &error_fatal);

    if (bios_name == NULL)
        bios_name = PROM_FILENAME;
    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
    memory_region_set_readonly(bios, true);
    memory_region_add_subregion(sysmem, PROM_ADDR, bios);

    /* Load OpenBIOS (ELF) */
    if (filename) {
        bios_size = load_elf(filename, NULL, 0, NULL, NULL, NULL, NULL,
                             1, PPC_ELF_MACHINE, 0, 0);
        g_free(filename);
    } else {
        bios_size = -1;
    }
    if (bios_size < 0 || bios_size > BIOS_SIZE) {
        error_report("could not load PowerPC bios '%s'", bios_name);
        exit(1);
    }

    if (linux_boot) {
        uint64_t lowaddr = 0;
        int bswap_needed;

#ifdef BSWAP_NEEDED
        bswap_needed = 1;
#else
        bswap_needed = 0;
#endif
        kernel_base = KERNEL_LOAD_ADDR;
        kernel_size = load_elf(kernel_filename, NULL,
                               translate_kernel_address, NULL,
                               NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE,
                               0, 0);
        if (kernel_size < 0)
            kernel_size = load_aout(kernel_filename, kernel_base,
                                    ram_size - kernel_base, bswap_needed,
                                    TARGET_PAGE_SIZE);
        if (kernel_size < 0)
            kernel_size = load_image_targphys(kernel_filename,
                                              kernel_base,
                                              ram_size - kernel_base);
        if (kernel_size < 0) {
            error_report("could not load kernel '%s'", kernel_filename);
            exit(1);
        }
        /* load initrd */
        if (initrd_filename) {
            initrd_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP);
            initrd_size = load_image_targphys(initrd_filename, initrd_base,
                                              ram_size - initrd_base);
            if (initrd_size < 0) {
                error_report("could not load initial ram disk '%s'",
                             initrd_filename);
                exit(1);
            }
            cmdline_base = TARGET_PAGE_ALIGN(initrd_base + initrd_size);
        } else {
            initrd_base = 0;
            initrd_size = 0;
            cmdline_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP);
        }
        ppc_boot_device = 'm';
    } else {
        kernel_base = 0;
        kernel_size = 0;
        initrd_base = 0;
        initrd_size = 0;
        ppc_boot_device = '\0';
        for (i = 0; boot_device[i] != '\0'; i++) {
            /* TOFIX: for now, the second IDE channel is not properly
             *        used by OHW. The Mac floppy disk are not emulated.
             *        For now, OHW cannot boot from the network.
             */
#if 0
            if (boot_device[i] >= 'a' && boot_device[i] <= 'f') {
                ppc_boot_device = boot_device[i];
                break;
            }
#else
            if (boot_device[i] >= 'c' && boot_device[i] <= 'd') {
                ppc_boot_device = boot_device[i];
                break;
            }
#endif
        }
        if (ppc_boot_device == '\0') {
            error_report("No valid boot device for G3 Beige machine");
            exit(1);
        }
    }

    /* XXX: we register only 1 output pin for heathrow PIC */
    pic_dev = qdev_create(NULL, TYPE_HEATHROW);
    qdev_init_nofail(pic_dev);

    /* Connect the heathrow PIC outputs to the 6xx bus */
    for (i = 0; i < smp_cpus; i++) {
        switch (PPC_INPUT(env)) {
        case PPC_FLAGS_INPUT_6xx:
            qdev_connect_gpio_out(pic_dev, 0,
                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]);
            break;
        default:
            error_report("Bus model not supported on OldWorld Mac machine");
            exit(1);
        }
    }

    /* Timebase Frequency */
    if (kvm_enabled()) {
        tbfreq = kvmppc_get_tbfreq();
    } else {
        tbfreq = TBFREQ;
    }

    /* init basic PC hardware */
    if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
        error_report("Only 6xx bus is supported on heathrow machine");
        exit(1);
    }

    /* Grackle PCI host bridge */
    dev = qdev_create(NULL, TYPE_GRACKLE_PCI_HOST_BRIDGE);
    qdev_prop_set_uint32(dev, "ofw-addr", 0x80000000);
    object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic",
                             &error_abort);
    qdev_init_nofail(dev);
    s = SYS_BUS_DEVICE(dev);
    sysbus_mmio_map(s, 0, GRACKLE_BASE);
    sysbus_mmio_map(s, 1, GRACKLE_BASE + 0x200000);
    /* PCI hole */
    memory_region_add_subregion(get_system_memory(), 0x80000000ULL,
                                sysbus_mmio_get_region(s, 2));
    /* Register 2 MB of ISA IO space */
    memory_region_add_subregion(get_system_memory(), 0xfe000000,
                                sysbus_mmio_get_region(s, 3));

    pci_bus = PCI_HOST_BRIDGE(dev)->bus;

    pci_vga_init(pci_bus);

    for (i = 0; i < nb_nics; i++) {
        pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL);
    }

    ide_drive_get(hd, ARRAY_SIZE(hd));

    /* MacIO */
    macio = OLDWORLD_MACIO(pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO));
    dev = DEVICE(macio);
    qdev_prop_set_uint64(dev, "frequency", tbfreq);
    object_property_set_link(OBJECT(macio), OBJECT(pic_dev), "pic",
                             &error_abort);
    qdev_init_nofail(dev);

    macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
                                                        "ide[0]"));
    macio_ide_init_drives(macio_ide, hd);

    macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
                                                        "ide[1]"));
    macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]);

    dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda"));
    adb_bus = qdev_get_child_bus(dev, "adb.0");
    dev = qdev_create(adb_bus, TYPE_ADB_KEYBOARD);
    qdev_init_nofail(dev);
    dev = qdev_create(adb_bus, TYPE_ADB_MOUSE);
    qdev_init_nofail(dev);

    if (machine_usb(machine)) {
        pci_create_simple(pci_bus, -1, "pci-ohci");
    }

    if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
        graphic_depth = 15;

    /* No PCI init: the BIOS will do it */

    dev = qdev_create(NULL, TYPE_FW_CFG_MEM);
    fw_cfg = FW_CFG(dev);
    qdev_prop_set_uint32(dev, "data_width", 1);
    qdev_prop_set_bit(dev, "dma_enabled", false);
    object_property_add_child(OBJECT(qdev_get_machine()), TYPE_FW_CFG,
                              OBJECT(fw_cfg), NULL);
    qdev_init_nofail(dev);
    s = SYS_BUS_DEVICE(dev);
    sysbus_mmio_map(s, 0, CFG_ADDR);
    sysbus_mmio_map(s, 1, CFG_ADDR + 2);

    fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW);
    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
    if (kernel_cmdline) {
        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base);
        pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline);
    } else {
        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
    }
    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base);
    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device);

    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width);
    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height);
    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth);

    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
    if (kvm_enabled()) {
#ifdef CONFIG_KVM
        uint8_t *hypercall;

        hypercall = g_malloc(16);
        kvmppc_get_hypercall(env, hypercall, 16);
        fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
#endif
    }
    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, tbfreq);
    /* Mac OS X requires a "known good" clock-frequency value; pass it one. */
    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_CLOCKFREQ, CLOCKFREQ);
    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_BUSFREQ, BUSFREQ);

    /* MacOS NDRV VGA driver */
    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, NDRV_VGA_FILENAME);
    if (filename) {
        gchar *ndrv_file;
        gsize ndrv_size;

        if (g_file_get_contents(filename, &ndrv_file, &ndrv_size, NULL)) {
            fw_cfg_add_file(fw_cfg, "ndrv/qemu_vga.ndrv", ndrv_file, ndrv_size);
        }
        g_free(filename);
    }

    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
}
示例#23
0
static
void mips_r4k_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 *ram = g_new(MemoryRegion, 1);
    MemoryRegion *bios;
    MemoryRegion *iomem = g_new(MemoryRegion, 1);
    MemoryRegion *isa_io = g_new(MemoryRegion, 1);
    MemoryRegion *isa_mem = g_new(MemoryRegion, 1);
    int bios_size;
    MIPSCPU *cpu;
    CPUMIPSState *env;
    ResetData *reset_info;
    int i;
    qemu_irq *i8259;
    ISABus *isa_bus;
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
    DriveInfo *dinfo;
    int be;

    /* init CPUs */
    if (cpu_model == NULL) {
#ifdef TARGET_MIPS64
        cpu_model = "R4000";
#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 */
    if (ram_size > (256 << 20)) {
        fprintf(stderr,
                "qemu: Too much memory for this machine: %d MB, maximum 256 MB\n",
                ((unsigned int)ram_size / (1 << 20)));
        exit(1);
    }
    memory_region_allocate_system_memory(ram, NULL, "mips_r4k.ram", ram_size);

    memory_region_add_subregion(address_space_mem, 0, ram);

    memory_region_init_io(iomem, NULL, &mips_qemu_ops, NULL, "mips-qemu", 0x10000);
    memory_region_add_subregion(address_space_mem, 0x1fbf0000, iomem);

    /* Try to load a BIOS image. If this fails, we continue regardless,
       but initialize the hardware ourselves. When a kernel gets
       preloaded we also initialize the hardware, since the BIOS wasn't
       run. */
    if (bios_name == NULL)
        bios_name = BIOS_FILENAME;
    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
    if (filename) {
        bios_size = get_image_size(filename);
    } else {
        bios_size = -1;
    }
#ifdef TARGET_WORDS_BIGENDIAN
    be = 1;
#else
    be = 0;
#endif
    if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) {
        bios = g_new(MemoryRegion, 1);
        memory_region_init_ram(bios, NULL, "mips_r4k.bios", BIOS_SIZE,
                               &error_fatal);
        vmstate_register_ram_global(bios);
        memory_region_set_readonly(bios, true);
        memory_region_add_subregion(get_system_memory(), 0x1fc00000, bios);

        load_image_targphys(filename, 0x1fc00000, BIOS_SIZE);
    } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
        uint32_t mips_rom = 0x00400000;
        if (!pflash_cfi01_register(0x1fc00000, NULL, "mips_r4k.bios", mips_rom,
                                   blk_by_legacy_dinfo(dinfo),
                                   sector_len, mips_rom / sector_len,
                                   4, 0, 0, 0, 0, be)) {
            fprintf(stderr, "qemu: Error registering flash memory.\n");
	}
    } else if (!qtest_enabled()) {
	/* not fatal */
        fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
		bios_name);
    }
    g_free(filename);

    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(env);
    cpu_mips_clock_init(env);

    /* ISA bus: IO space at 0x14000000, mem space at 0x10000000 */
    memory_region_init_alias(isa_io, NULL, "isa-io",
                             get_system_io(), 0, 0x00010000);
    memory_region_init(isa_mem, NULL, "isa-mem", 0x01000000);
    memory_region_add_subregion(get_system_memory(), 0x14000000, isa_io);
    memory_region_add_subregion(get_system_memory(), 0x10000000, isa_mem);
    isa_bus = isa_bus_new(NULL, isa_mem, get_system_io(), &error_abort);

    /* The PIC is attached to the MIPS CPU INT0 pin */
    i8259 = i8259_init(isa_bus, env->irq[2]);
    isa_bus_irqs(isa_bus, i8259);

    rtc_init(isa_bus, 2000, NULL);

    pit = pit_init(isa_bus, 0x40, 0, NULL);

    serial_hds_isa_init(isa_bus, MAX_SERIAL_PORTS);

    isa_vga_init(isa_bus);

    if (nd_table[0].used)
        isa_ne2000_init(isa_bus, 0x300, 9, &nd_table[0]);

    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[MAX_IDE_DEVS * i],
		     hd[MAX_IDE_DEVS * i + 1]);

    isa_create_simple(isa_bus, "i8042");
}
示例#24
0
文件: mac_newworld.c 项目: aik/qemu
/* PowerPC Mac99 hardware initialisation */
static void ppc_core99_init(MachineState *machine)
{
    ram_addr_t ram_size = machine->ram_size;
    const char *kernel_filename = machine->kernel_filename;
    const char *kernel_cmdline = machine->kernel_cmdline;
    const char *initrd_filename = machine->initrd_filename;
    const char *boot_device = machine->boot_order;
    Core99MachineState *core99_machine = CORE99_MACHINE(machine);
    PowerPCCPU *cpu = NULL;
    CPUPPCState *env = NULL;
    char *filename;
    IrqLines *openpic_irqs;
    int linux_boot, i, j, k;
    MemoryRegion *ram = g_new(MemoryRegion, 1), *bios = g_new(MemoryRegion, 1);
    hwaddr kernel_base, initrd_base, cmdline_base = 0;
    long kernel_size, initrd_size;
    UNINHostState *uninorth_pci;
    PCIBus *pci_bus;
    NewWorldMacIOState *macio;
    bool has_pmu, has_adb;
    MACIOIDEState *macio_ide;
    BusState *adb_bus;
    MacIONVRAMState *nvr;
    int bios_size;
    int ppc_boot_device;
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
    void *fw_cfg;
    int machine_arch;
    SysBusDevice *s;
    DeviceState *dev, *pic_dev;
    hwaddr nvram_addr = 0xFFF04000;
    uint64_t tbfreq;

    linux_boot = (kernel_filename != NULL);

    /* init CPUs */
    for (i = 0; i < smp_cpus; i++) {
        cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
        env = &cpu->env;

        /* Set time-base frequency to 100 Mhz */
        cpu_ppc_tb_init(env, TBFREQ);
        qemu_register_reset(ppc_core99_reset, cpu);
    }

    /* allocate RAM */
    memory_region_allocate_system_memory(ram, NULL, "ppc_core99.ram", ram_size);
    memory_region_add_subregion(get_system_memory(), 0, ram);

    /* allocate and load BIOS */
    memory_region_init_ram(bios, NULL, "ppc_core99.bios", BIOS_SIZE,
                           &error_fatal);

    if (bios_name == NULL)
        bios_name = PROM_FILENAME;
    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
    memory_region_set_readonly(bios, true);
    memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios);

    /* Load OpenBIOS (ELF) */
    if (filename) {
        bios_size = load_elf(filename, NULL, NULL, NULL,
                             NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0);

        g_free(filename);
    } else {
        bios_size = -1;
    }
    if (bios_size < 0 || bios_size > BIOS_SIZE) {
        error_report("could not load PowerPC bios '%s'", bios_name);
        exit(1);
    }

    if (linux_boot) {
        uint64_t lowaddr = 0;
        int bswap_needed;

#ifdef BSWAP_NEEDED
        bswap_needed = 1;
#else
        bswap_needed = 0;
#endif
        kernel_base = KERNEL_LOAD_ADDR;

        kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
                               NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE,
                               0, 0);
        if (kernel_size < 0)
            kernel_size = load_aout(kernel_filename, kernel_base,
                                    ram_size - kernel_base, bswap_needed,
                                    TARGET_PAGE_SIZE);
        if (kernel_size < 0)
            kernel_size = load_image_targphys(kernel_filename,
                                              kernel_base,
                                              ram_size - kernel_base);
        if (kernel_size < 0) {
            error_report("could not load kernel '%s'", kernel_filename);
            exit(1);
        }
        /* load initrd */
        if (initrd_filename) {
            initrd_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP);
            initrd_size = load_image_targphys(initrd_filename, initrd_base,
                                              ram_size - initrd_base);
            if (initrd_size < 0) {
                error_report("could not load initial ram disk '%s'",
                             initrd_filename);
                exit(1);
            }
            cmdline_base = TARGET_PAGE_ALIGN(initrd_base + initrd_size);
        } else {
            initrd_base = 0;
            initrd_size = 0;
            cmdline_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP);
        }
        ppc_boot_device = 'm';
    } else {
        kernel_base = 0;
        kernel_size = 0;
        initrd_base = 0;
        initrd_size = 0;
        ppc_boot_device = '\0';
        /* We consider that NewWorld PowerMac never have any floppy drive
         * For now, OHW cannot boot from the network.
         */
        for (i = 0; boot_device[i] != '\0'; i++) {
            if (boot_device[i] >= 'c' && boot_device[i] <= 'f') {
                ppc_boot_device = boot_device[i];
                break;
            }
        }
        if (ppc_boot_device == '\0') {
            error_report("No valid boot device for Mac99 machine");
            exit(1);
        }
    }

    /* UniN init */
    dev = qdev_create(NULL, TYPE_UNI_NORTH);
    qdev_init_nofail(dev);
    s = SYS_BUS_DEVICE(dev);
    memory_region_add_subregion(get_system_memory(), 0xf8000000,
                                sysbus_mmio_get_region(s, 0));

    openpic_irqs = g_new0(IrqLines, smp_cpus);
    for (i = 0; i < smp_cpus; i++) {
        /* Mac99 IRQ connection between OpenPIC outputs pins
         * and PowerPC input pins
         */
        switch (PPC_INPUT(env)) {
        case PPC_FLAGS_INPUT_6xx:
            openpic_irqs[i].irq[OPENPIC_OUTPUT_INT] =
                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
            openpic_irqs[i].irq[OPENPIC_OUTPUT_CINT] =
                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
            openpic_irqs[i].irq[OPENPIC_OUTPUT_MCK] =
                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_MCP];
            /* Not connected ? */
            openpic_irqs[i].irq[OPENPIC_OUTPUT_DEBUG] = NULL;
            /* Check this */
            openpic_irqs[i].irq[OPENPIC_OUTPUT_RESET] =
                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_HRESET];
            break;
#if defined(TARGET_PPC64)
        case PPC_FLAGS_INPUT_970:
            openpic_irqs[i].irq[OPENPIC_OUTPUT_INT] =
                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
            openpic_irqs[i].irq[OPENPIC_OUTPUT_CINT] =
                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
            openpic_irqs[i].irq[OPENPIC_OUTPUT_MCK] =
                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_MCP];
            /* Not connected ? */
            openpic_irqs[i].irq[OPENPIC_OUTPUT_DEBUG] = NULL;
            /* Check this */
            openpic_irqs[i].irq[OPENPIC_OUTPUT_RESET] =
                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_HRESET];
            break;
#endif /* defined(TARGET_PPC64) */
        default:
            error_report("Bus model not supported on mac99 machine");
            exit(1);
        }
    }

    pic_dev = qdev_create(NULL, TYPE_OPENPIC);
    qdev_prop_set_uint32(pic_dev, "model", OPENPIC_MODEL_KEYLARGO);
    qdev_init_nofail(pic_dev);
    s = SYS_BUS_DEVICE(pic_dev);
    k = 0;
    for (i = 0; i < smp_cpus; i++) {
        for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
            sysbus_connect_irq(s, k++, openpic_irqs[i].irq[j]);
        }
    }
    g_free(openpic_irqs);

    if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) {
        /* 970 gets a U3 bus */
        /* Uninorth AGP bus */
        dev = qdev_create(NULL, TYPE_U3_AGP_HOST_BRIDGE);
        object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic",
                                 &error_abort);
        qdev_init_nofail(dev);
        uninorth_pci = U3_AGP_HOST_BRIDGE(dev);
        s = SYS_BUS_DEVICE(dev);
        /* PCI hole */
        memory_region_add_subregion(get_system_memory(), 0x80000000ULL,
                                    sysbus_mmio_get_region(s, 2));
        /* Register 8 MB of ISA IO space */
        memory_region_add_subregion(get_system_memory(), 0xf2000000,
                                    sysbus_mmio_get_region(s, 3));
        sysbus_mmio_map(s, 0, 0xf0800000);
        sysbus_mmio_map(s, 1, 0xf0c00000);

        machine_arch = ARCH_MAC99_U3;
    } else {
        /* Use values found on a real PowerMac */
        /* Uninorth AGP bus */
        dev = qdev_create(NULL, TYPE_UNI_NORTH_AGP_HOST_BRIDGE);
        object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic",
                                 &error_abort);
        qdev_init_nofail(dev);
        s = SYS_BUS_DEVICE(dev);
        sysbus_mmio_map(s, 0, 0xf0800000);
        sysbus_mmio_map(s, 1, 0xf0c00000);

        /* Uninorth internal bus */
        dev = qdev_create(NULL, TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE);
        object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic",
                                 &error_abort);
        qdev_init_nofail(dev);
        s = SYS_BUS_DEVICE(dev);
        sysbus_mmio_map(s, 0, 0xf4800000);
        sysbus_mmio_map(s, 1, 0xf4c00000);

        /* Uninorth main bus */
        dev = qdev_create(NULL, TYPE_UNI_NORTH_PCI_HOST_BRIDGE);
        qdev_prop_set_uint32(dev, "ofw-addr", 0xf2000000);
        object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic",
                                 &error_abort);
        qdev_init_nofail(dev);
        uninorth_pci = UNI_NORTH_PCI_HOST_BRIDGE(dev);
        s = SYS_BUS_DEVICE(dev);
        /* PCI hole */
        memory_region_add_subregion(get_system_memory(), 0x80000000ULL,
                                    sysbus_mmio_get_region(s, 2));
        /* Register 8 MB of ISA IO space */
        memory_region_add_subregion(get_system_memory(), 0xf2000000,
                                    sysbus_mmio_get_region(s, 3));
        sysbus_mmio_map(s, 0, 0xf2800000);
        sysbus_mmio_map(s, 1, 0xf2c00000);

        machine_arch = ARCH_MAC99;
    }

    machine->usb |= defaults_enabled() && !machine->usb_disabled;
    has_pmu = (core99_machine->via_config != CORE99_VIA_CONFIG_CUDA);
    has_adb = (core99_machine->via_config == CORE99_VIA_CONFIG_CUDA ||
               core99_machine->via_config == CORE99_VIA_CONFIG_PMU_ADB);

    /* Timebase Frequency */
    if (kvm_enabled()) {
        tbfreq = kvmppc_get_tbfreq();
    } else {
        tbfreq = TBFREQ;
    }

    /* init basic PC hardware */
    pci_bus = PCI_HOST_BRIDGE(uninorth_pci)->bus;

    /* MacIO */
    macio = NEWWORLD_MACIO(pci_create(pci_bus, -1, TYPE_NEWWORLD_MACIO));
    dev = DEVICE(macio);
    qdev_prop_set_uint64(dev, "frequency", tbfreq);
    qdev_prop_set_bit(dev, "has-pmu", has_pmu);
    qdev_prop_set_bit(dev, "has-adb", has_adb);
    object_property_set_link(OBJECT(macio), OBJECT(pic_dev), "pic",
                             &error_abort);
    qdev_init_nofail(dev);

    /* We only emulate 2 out of 3 IDE controllers for now */
    ide_drive_get(hd, ARRAY_SIZE(hd));

    macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
                                                        "ide[0]"));
    macio_ide_init_drives(macio_ide, hd);

    macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
                                                        "ide[1]"));
    macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]);

    if (has_adb) {
        if (has_pmu) {
            dev = DEVICE(object_resolve_path_component(OBJECT(macio), "pmu"));
        } else {
            dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda"));
        }

        adb_bus = qdev_get_child_bus(dev, "adb.0");
        dev = qdev_create(adb_bus, TYPE_ADB_KEYBOARD);
        qdev_prop_set_bit(dev, "disable-direct-reg3-writes", true);
        qdev_init_nofail(dev);

        dev = qdev_create(adb_bus, TYPE_ADB_MOUSE);
        qdev_prop_set_bit(dev, "disable-direct-reg3-writes", true);
        qdev_init_nofail(dev);
    }

    if (machine->usb) {
        pci_create_simple(pci_bus, -1, "pci-ohci");

        /* U3 needs to use USB for input because Linux doesn't support via-cuda
        on PPC64 */
        if (!has_adb || machine_arch == ARCH_MAC99_U3) {
            USBBus *usb_bus = usb_bus_find(-1);

            usb_create_simple(usb_bus, "usb-kbd");
            usb_create_simple(usb_bus, "usb-mouse");
        }
    }

    pci_vga_init(pci_bus);

    if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) {
        graphic_depth = 15;
    }

    for (i = 0; i < nb_nics; i++) {
        pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL);
    }

    /* The NewWorld NVRAM is not located in the MacIO device */
#ifdef CONFIG_KVM
    if (kvm_enabled() && getpagesize() > 4096) {
        /* We can't combine read-write and read-only in a single page, so
           move the NVRAM out of ROM again for KVM */
        nvram_addr = 0xFFE00000;
    }
#endif
    dev = qdev_create(NULL, TYPE_MACIO_NVRAM);
    qdev_prop_set_uint32(dev, "size", 0x2000);
    qdev_prop_set_uint32(dev, "it_shift", 1);
    qdev_init_nofail(dev);
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, nvram_addr);
    nvr = MACIO_NVRAM(dev);
    pmac_format_nvram_partition(nvr, 0x2000);
    /* No PCI init: the BIOS will do it */

    dev = qdev_create(NULL, TYPE_FW_CFG_MEM);
    fw_cfg = FW_CFG(dev);
    qdev_prop_set_uint32(dev, "data_width", 1);
    qdev_prop_set_bit(dev, "dma_enabled", false);
    object_property_add_child(OBJECT(qdev_get_machine()), TYPE_FW_CFG,
                              OBJECT(fw_cfg), NULL);
    qdev_init_nofail(dev);
    s = SYS_BUS_DEVICE(dev);
    sysbus_mmio_map(s, 0, CFG_ADDR);
    sysbus_mmio_map(s, 1, CFG_ADDR + 2);

    fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch);
    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
    if (kernel_cmdline) {
        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base);
        pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline);
    } else {
        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
    }
    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base);
    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device);

    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width);
    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height);
    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth);

    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_VIACONFIG, core99_machine->via_config);

    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
    if (kvm_enabled()) {
#ifdef CONFIG_KVM
        uint8_t *hypercall;

        hypercall = g_malloc(16);
        kvmppc_get_hypercall(env, hypercall, 16);
        fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
#endif
    }
    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, tbfreq);
    /* Mac OS X requires a "known good" clock-frequency value; pass it one. */
    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_CLOCKFREQ, CLOCKFREQ);
    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_BUSFREQ, BUSFREQ);
    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_NVRAM_ADDR, nvram_addr);

    /* MacOS NDRV VGA driver */
    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, NDRV_VGA_FILENAME);
    if (filename) {
        gchar *ndrv_file;
        gsize ndrv_size;

        if (g_file_get_contents(filename, &ndrv_file, &ndrv_size, NULL)) {
            fw_cfg_add_file(fw_cfg, "ndrv/qemu_vga.ndrv", ndrv_file, ndrv_size);
        }
        g_free(filename);
    }

    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
}
示例#25
0
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]);
}
示例#26
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;
    PCIDevice *macio;
    MACIOIDEState *macio_ide;
    BusState *adb_bus;
    MacIONVRAMState *nvr;
    int bios_size;
    MemoryRegion *pic_mem, *escc_mem;
    MemoryRegion *escc_bar = g_new(MemoryRegion, 1);
    int ppc_boot_device;
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
    void *fw_cfg;
    int machine_arch;
    SysBusDevice *s;
    DeviceState *dev;
    int *token = g_new(int, 1);
    hwaddr nvram_addr = 0xFFF04000;
    uint64_t tbfreq;

    linux_boot = (kernel_filename != NULL);

    /* init CPUs */
    if (machine->cpu_model == NULL) {
#ifdef TARGET_PPC64
        machine->cpu_model = "970fx";
#else
        machine->cpu_model = "G4";
#endif
    }
    for (i = 0; i < smp_cpus; i++) {
        cpu = cpu_ppc_init(machine->cpu_model);
        if (cpu == NULL) {
            fprintf(stderr, "Unable to find PowerPC CPU definition\n");
            exit(1);
        }
        env = &cpu->env;

        /* Set time-base frequency to 100 Mhz */
        cpu_ppc_tb_init(env, TBFREQ);
        qemu_register_reset(ppc_core99_reset, cpu);
    }

    /* allocate RAM */
    memory_region_allocate_system_memory(ram, NULL, "ppc_core99.ram", ram_size);
    memory_region_add_subregion(get_system_memory(), 0, ram);

    /* allocate and load BIOS */
    memory_region_init_ram(bios, NULL, "ppc_core99.bios", BIOS_SIZE,
                           &error_fatal);
    vmstate_register_ram_global(bios);

    if (bios_name == NULL)
        bios_name = PROM_FILENAME;
    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
    memory_region_set_readonly(bios, true);
    memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios);

    /* Load OpenBIOS (ELF) */
    if (filename) {
        bios_size = load_elf(filename, NULL, NULL, NULL,
                             NULL, NULL, 1, PPC_ELF_MACHINE, 0);

        g_free(filename);
    } else {
        bios_size = -1;
    }
    if (bios_size < 0 || bios_size > BIOS_SIZE) {
        error_report("could not load PowerPC bios '%s'", bios_name);
        exit(1);
    }

    if (linux_boot) {
        uint64_t lowaddr = 0;
        int bswap_needed;

#ifdef BSWAP_NEEDED
        bswap_needed = 1;
#else
        bswap_needed = 0;
#endif
        kernel_base = KERNEL_LOAD_ADDR;

        kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
                               NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE, 0);
        if (kernel_size < 0)
            kernel_size = load_aout(kernel_filename, kernel_base,
                                    ram_size - kernel_base, bswap_needed,
                                    TARGET_PAGE_SIZE);
        if (kernel_size < 0)
            kernel_size = load_image_targphys(kernel_filename,
                                              kernel_base,
                                              ram_size - kernel_base);
        if (kernel_size < 0) {
            error_report("could not load kernel '%s'", kernel_filename);
            exit(1);
        }
        /* load initrd */
        if (initrd_filename) {
            initrd_base = round_page(kernel_base + kernel_size + KERNEL_GAP);
            initrd_size = load_image_targphys(initrd_filename, initrd_base,
                                              ram_size - initrd_base);
            if (initrd_size < 0) {
                error_report("could not load initial ram disk '%s'",
                             initrd_filename);
                exit(1);
            }
            cmdline_base = round_page(initrd_base + initrd_size);
        } else {
            initrd_base = 0;
            initrd_size = 0;
            cmdline_base = round_page(kernel_base + kernel_size + KERNEL_GAP);
        }
        ppc_boot_device = 'm';
    } else {
        kernel_base = 0;
        kernel_size = 0;
        initrd_base = 0;
        initrd_size = 0;
        ppc_boot_device = '\0';
        /* We consider that NewWorld PowerMac never have any floppy drive
         * For now, OHW cannot boot from the network.
         */
        for (i = 0; boot_device[i] != '\0'; i++) {
            if (boot_device[i] >= 'c' && boot_device[i] <= 'f') {
                ppc_boot_device = boot_device[i];
                break;
            }
        }
        if (ppc_boot_device == '\0') {
            fprintf(stderr, "No valid boot device for Mac99 machine\n");
            exit(1);
        }
    }

    /* Register 8 MB of ISA IO space */
    memory_region_init_alias(isa, NULL, "isa_mmio",
                             get_system_io(), 0, 0x00800000);
    memory_region_add_subregion(get_system_memory(), 0xf2000000, isa);

    /* UniN init: XXX should be a real device */
    memory_region_init_io(unin_memory, NULL, &unin_ops, token, "unin", 0x1000);
    memory_region_add_subregion(get_system_memory(), 0xf8000000, unin_memory);

    memory_region_init_io(unin2_memory, NULL, &unin_ops, token, "unin", 0x1000);
    memory_region_add_subregion(get_system_memory(), 0xf3000000, unin2_memory);

    openpic_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
    openpic_irqs[0] =
        g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
    for (i = 0; i < smp_cpus; i++) {
        /* Mac99 IRQ connection between OpenPIC outputs pins
         * and PowerPC input pins
         */
        switch (PPC_INPUT(env)) {
        case PPC_FLAGS_INPUT_6xx:
            openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);
            openpic_irqs[i][OPENPIC_OUTPUT_INT] =
                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
            openpic_irqs[i][OPENPIC_OUTPUT_CINT] =
                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
            openpic_irqs[i][OPENPIC_OUTPUT_MCK] =
                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_MCP];
            /* Not connected ? */
            openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;
            /* Check this */
            openpic_irqs[i][OPENPIC_OUTPUT_RESET] =
                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_HRESET];
            break;
#if defined(TARGET_PPC64)
        case PPC_FLAGS_INPUT_970:
            openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);
            openpic_irqs[i][OPENPIC_OUTPUT_INT] =
                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
            openpic_irqs[i][OPENPIC_OUTPUT_CINT] =
                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
            openpic_irqs[i][OPENPIC_OUTPUT_MCK] =
                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_MCP];
            /* Not connected ? */
            openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;
            /* Check this */
            openpic_irqs[i][OPENPIC_OUTPUT_RESET] =
                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_HRESET];
            break;
#endif /* defined(TARGET_PPC64) */
        default:
            error_report("Bus model not supported on mac99 machine");
            exit(1);
        }
    }

    pic = g_new0(qemu_irq, 64);

    dev = qdev_create(NULL, TYPE_OPENPIC);
    qdev_prop_set_uint32(dev, "model", OPENPIC_MODEL_RAVEN);
    qdev_init_nofail(dev);
    s = SYS_BUS_DEVICE(dev);
    pic_mem = s->mmio[0].memory;
    k = 0;
    for (i = 0; i < smp_cpus; i++) {
        for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
            sysbus_connect_irq(s, k++, openpic_irqs[i][j]);
        }
    }

    for (i = 0; i < 64; i++) {
        pic[i] = qdev_get_gpio_in(dev, i);
    }

    if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) {
        /* 970 gets a U3 bus */
        pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io());
        machine_arch = ARCH_MAC99_U3;
    } else {
        pci_bus = pci_pmac_init(pic, get_system_memory(), get_system_io());
        machine_arch = ARCH_MAC99;
    }

    machine->usb |= defaults_enabled() && !machine->usb_disabled;

    /* Timebase Frequency */
    if (kvm_enabled()) {
        tbfreq = kvmppc_get_tbfreq();
    } else {
        tbfreq = TBFREQ;
    }

    /* init basic PC hardware */
    escc_mem = escc_init(0, pic[0x25], pic[0x24],
                         serial_hds[0], serial_hds[1], ESCC_CLOCK, 4);
    memory_region_init_alias(escc_bar, NULL, "escc-bar",
                             escc_mem, 0, memory_region_size(escc_mem));

    macio = pci_create(pci_bus, -1, TYPE_NEWWORLD_MACIO);
    dev = DEVICE(macio);
    qdev_connect_gpio_out(dev, 0, pic[0x19]); /* CUDA */
    qdev_connect_gpio_out(dev, 1, pic[0x0d]); /* IDE */
    qdev_connect_gpio_out(dev, 2, pic[0x02]); /* IDE DMA */
    qdev_connect_gpio_out(dev, 3, pic[0x0e]); /* IDE */
    qdev_connect_gpio_out(dev, 4, pic[0x03]); /* IDE DMA */
    qdev_prop_set_uint64(dev, "frequency", tbfreq);
    macio_init(macio, pic_mem, escc_bar);

    /* We only emulate 2 out of 3 IDE controllers for now */
    ide_drive_get(hd, ARRAY_SIZE(hd));

    macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
                                                        "ide[0]"));
    macio_ide_init_drives(macio_ide, hd);

    macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
                                                        "ide[1]"));
    macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]);

    dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda"));
    adb_bus = qdev_get_child_bus(dev, "adb.0");
    dev = qdev_create(adb_bus, TYPE_ADB_KEYBOARD);
    qdev_init_nofail(dev);
    dev = qdev_create(adb_bus, TYPE_ADB_MOUSE);
    qdev_init_nofail(dev);

    if (machine->usb) {
        pci_create_simple(pci_bus, -1, "pci-ohci");

        /* U3 needs to use USB for input because Linux doesn't support via-cuda
        on PPC64 */
        if (machine_arch == ARCH_MAC99_U3) {
            USBBus *usb_bus = usb_bus_find(-1);

            usb_create_simple(usb_bus, "usb-kbd");
            usb_create_simple(usb_bus, "usb-mouse");
        }
    }

    pci_vga_init(pci_bus);

    if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) {
        graphic_depth = 15;
    }

    for (i = 0; i < nb_nics; i++) {
        pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL);
    }

    /* The NewWorld NVRAM is not located in the MacIO device */
#ifdef CONFIG_KVM
    if (kvm_enabled() && getpagesize() > 4096) {
        /* We can't combine read-write and read-only in a single page, so
           move the NVRAM out of ROM again for KVM */
        nvram_addr = 0xFFE00000;
    }
#endif
    dev = qdev_create(NULL, TYPE_MACIO_NVRAM);
    qdev_prop_set_uint32(dev, "size", 0x2000);
    qdev_prop_set_uint32(dev, "it_shift", 1);
    qdev_init_nofail(dev);
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, nvram_addr);
    nvr = MACIO_NVRAM(dev);
    pmac_format_nvram_partition(nvr, 0x2000);
    /* No PCI init: the BIOS will do it */

    fw_cfg = fw_cfg_init_mem(CFG_ADDR, CFG_ADDR + 2);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch);
    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
    if (kernel_cmdline) {
        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base);
        pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline);
    } else {
        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
    }
    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base);
    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device);

    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width);
    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height);
    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth);

    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
    if (kvm_enabled()) {
#ifdef CONFIG_KVM
        uint8_t *hypercall;

        hypercall = g_malloc(16);
        kvmppc_get_hypercall(env, hypercall, 16);
        fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
#endif
    }
    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, tbfreq);
    /* Mac OS X requires a "known good" clock-frequency value; pass it one. */
    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_CLOCKFREQ, CLOCKFREQ);
    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_BUSFREQ, BUSFREQ);
    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_NVRAM_ADDR, nvram_addr);

    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
}
示例#27
0
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]));
    }
}
示例#28
0
/* PowerPC Mac99 hardware initialisation */
static void ppc_core99_init (ram_addr_t ram_size,
                             const char *boot_device,
                             const char *kernel_filename,
                             const char *kernel_cmdline,
                             const char *initrd_filename,
                             const char *cpu_model)
{
    PowerPCCPU *cpu = NULL;
    CPUPPCState *env = NULL;
    char *filename;
    qemu_irq *pic, **openpic_irqs;
    MemoryRegion *unin_memory = g_new(MemoryRegion, 1);
    int linux_boot, i;
    MemoryRegion *ram = g_new(MemoryRegion, 1), *bios = g_new(MemoryRegion, 1);
    target_phys_addr_t kernel_base, initrd_base, cmdline_base = 0;
    long kernel_size, initrd_size;
    PCIBus *pci_bus;
    MacIONVRAMState *nvr;
    int bios_size;
    MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem, *escc_mem;
    MemoryRegion *escc_bar = g_new(MemoryRegion, 1);
    MemoryRegion *ide_mem[3];
    int ppc_boot_device;
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
    void *fw_cfg;
    void *dbdma;
    int machine_arch;

    linux_boot = (kernel_filename != NULL);

    /* init CPUs */
    if (cpu_model == NULL)
#ifdef TARGET_PPC64
        cpu_model = "970fx";
#else
        cpu_model = "G4";
#endif
    for (i = 0; i < smp_cpus; i++) {
        cpu = cpu_ppc_init(cpu_model);
        if (cpu == NULL) {
            fprintf(stderr, "Unable to find PowerPC CPU definition\n");
            exit(1);
        }
        env = &cpu->env;

        /* Set time-base frequency to 100 Mhz */
        cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
        qemu_register_reset(ppc_core99_reset, cpu);
    }

    /* allocate RAM */
    memory_region_init_ram(ram, "ppc_core99.ram", ram_size);
    vmstate_register_ram_global(ram);
    memory_region_add_subregion(get_system_memory(), 0, ram);

    /* allocate and load BIOS */
    memory_region_init_ram(bios, "ppc_core99.bios", BIOS_SIZE);
    vmstate_register_ram_global(bios);
    if (bios_name == NULL)
        bios_name = PROM_FILENAME;
    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
    memory_region_set_readonly(bios, true);
    memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios);

    /* Load OpenBIOS (ELF) */
    if (filename) {
        bios_size = load_elf(filename, NULL, NULL, NULL,
                             NULL, NULL, 1, ELF_MACHINE, 0);

        g_free(filename);
    } else {
        bios_size = -1;
    }
    if (bios_size < 0 || bios_size > BIOS_SIZE) {
        hw_error("qemu: could not load PowerPC bios '%s'\n", bios_name);
        exit(1);
    }

    if (linux_boot) {
        uint64_t lowaddr = 0;
        int bswap_needed;

#ifdef BSWAP_NEEDED
        bswap_needed = 1;
#else
        bswap_needed = 0;
#endif
        kernel_base = KERNEL_LOAD_ADDR;

        kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
                               NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0);
        if (kernel_size < 0)
            kernel_size = load_aout(kernel_filename, kernel_base,
                                    ram_size - kernel_base, bswap_needed,
                                    TARGET_PAGE_SIZE);
        if (kernel_size < 0)
            kernel_size = load_image_targphys(kernel_filename,
                                              kernel_base,
                                              ram_size - kernel_base);
        if (kernel_size < 0) {
            hw_error("qemu: could not load kernel '%s'\n", kernel_filename);
            exit(1);
        }
        /* load initrd */
        if (initrd_filename) {
            initrd_base = round_page(kernel_base + kernel_size + KERNEL_GAP);
            initrd_size = load_image_targphys(initrd_filename, initrd_base,
                                              ram_size - initrd_base);
            if (initrd_size < 0) {
                hw_error("qemu: could not load initial ram disk '%s'\n",
                         initrd_filename);
                exit(1);
            }
            cmdline_base = round_page(initrd_base + initrd_size);
        } else {
            initrd_base = 0;
            initrd_size = 0;
            cmdline_base = round_page(kernel_base + kernel_size + KERNEL_GAP);
        }
        ppc_boot_device = 'm';
    } else {
        kernel_base = 0;
        kernel_size = 0;
        initrd_base = 0;
        initrd_size = 0;
        ppc_boot_device = '\0';
        /* We consider that NewWorld PowerMac never have any floppy drive
         * For now, OHW cannot boot from the network.
         */
        for (i = 0; boot_device[i] != '\0'; i++) {
            if (boot_device[i] >= 'c' && boot_device[i] <= 'f') {
                ppc_boot_device = boot_device[i];
                break;
            }
        }
        if (ppc_boot_device == '\0') {
            fprintf(stderr, "No valid boot device for Mac99 machine\n");
            exit(1);
        }
    }

    /* Register 8 MB of ISA IO space */
    isa_mmio_init(0xf2000000, 0x00800000);

    /* UniN init */
    memory_region_init_io(unin_memory, &unin_ops, NULL, "unin", 0x1000);
    memory_region_add_subregion(get_system_memory(), 0xf8000000, unin_memory);

    openpic_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
    openpic_irqs[0] =
        g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
    for (i = 0; i < smp_cpus; i++) {
        /* Mac99 IRQ connection between OpenPIC outputs pins
         * and PowerPC input pins
         */
        switch (PPC_INPUT(env)) {
        case PPC_FLAGS_INPUT_6xx:
            openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);
            openpic_irqs[i][OPENPIC_OUTPUT_INT] =
                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
            openpic_irqs[i][OPENPIC_OUTPUT_CINT] =
                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
            openpic_irqs[i][OPENPIC_OUTPUT_MCK] =
                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_MCP];
            /* Not connected ? */
            openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;
            /* Check this */
            openpic_irqs[i][OPENPIC_OUTPUT_RESET] =
                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_HRESET];
            break;
#if defined(TARGET_PPC64)
        case PPC_FLAGS_INPUT_970:
            openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);
            openpic_irqs[i][OPENPIC_OUTPUT_INT] =
                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
            openpic_irqs[i][OPENPIC_OUTPUT_CINT] =
                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
            openpic_irqs[i][OPENPIC_OUTPUT_MCK] =
                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_MCP];
            /* Not connected ? */
            openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;
            /* Check this */
            openpic_irqs[i][OPENPIC_OUTPUT_RESET] =
                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_HRESET];
            break;
#endif /* defined(TARGET_PPC64) */
        default:
            hw_error("Bus model not supported on mac99 machine\n");
            exit(1);
        }
    }
    pic = openpic_init(&pic_mem, smp_cpus, openpic_irqs, NULL);
    if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) {
        /* 970 gets a U3 bus */
        pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io());
        machine_arch = ARCH_MAC99_U3;
    } else {
        pci_bus = pci_pmac_init(pic, get_system_memory(), get_system_io());
        machine_arch = ARCH_MAC99;
    }
    /* init basic PC hardware */
    pci_vga_init(pci_bus);

    escc_mem = escc_init(0, pic[0x25], pic[0x24],
                         serial_hds[0], serial_hds[1], ESCC_CLOCK, 4);
    memory_region_init_alias(escc_bar, "escc-bar",
                             escc_mem, 0, memory_region_size(escc_mem));

    for(i = 0; i < nb_nics; i++)
        pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);

    ide_drive_get(hd, MAX_IDE_BUS);
    dbdma = DBDMA_init(&dbdma_mem);

    /* We only emulate 2 out of 3 IDE controllers for now */
    ide_mem[0] = NULL;
    ide_mem[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]);
    ide_mem[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]);

    /* cuda also initialize ADB */
    if (machine_arch == ARCH_MAC99_U3) {
        usb_enabled = 1;
    }
    cuda_init(&cuda_mem, pic[0x19]);

    adb_kbd_init(&adb_bus);
    adb_mouse_init(&adb_bus);

    macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem,
               dbdma_mem, cuda_mem, NULL, 3, ide_mem, escc_bar);

    if (usb_enabled) {
        pci_create_simple(pci_bus, -1, "pci-ohci");
    }

    /* U3 needs to use USB for input because Linux doesn't support via-cuda
       on PPC64 */
    if (machine_arch == ARCH_MAC99_U3) {
        usbdevice_create("keyboard");
        usbdevice_create("mouse");
    }

    if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
        graphic_depth = 15;

    /* The NewWorld NVRAM is not located in the MacIO device */
    nvr = macio_nvram_init(0x2000, 1);
    pmac_format_nvram_partition(nvr, 0x2000);
    macio_nvram_setup_bar(nvr, get_system_memory(), 0xFFF04000);
    /* No PCI init: the BIOS will do it */

    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch);
    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
    if (kernel_cmdline) {
        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base);
        pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline);
    } else {
        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
    }
    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base);
    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device);

    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width);
    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height);
    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth);

    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
    if (kvm_enabled()) {
#ifdef CONFIG_KVM
        uint8_t *hypercall;

        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq());
        hypercall = g_malloc(16);
        kvmppc_get_hypercall(env, hypercall, 16);
        fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
#endif
    } else {
        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec());
    }

    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
}
示例#29
0
Exynos4210State *exynos4210_init(MemoryRegion *system_mem)
{
    Exynos4210State *s = g_new(Exynos4210State, 1);
    qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
    SysBusDevice *busdev;
    DeviceState *dev;
    int i, n;

    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
        Object *cpuobj = object_new(ARM_CPU_TYPE_NAME("cortex-a9"));

        /* By default A9 CPUs have EL3 enabled.  This board does not currently
         * support EL3 so the CPU EL3 property is disabled before realization.
         */
        if (object_property_find(cpuobj, "has_el3", NULL)) {
            object_property_set_bool(cpuobj, false, "has_el3", &error_fatal);
        }

        s->cpu[n] = ARM_CPU(cpuobj);
        object_property_set_int(cpuobj, exynos4210_calc_affinity(n),
                                "mp-affinity", &error_abort);
        object_property_set_int(cpuobj, EXYNOS4210_SMP_PRIVATE_BASE_ADDR,
                                "reset-cbar", &error_abort);
        object_property_set_bool(cpuobj, true, "realized", &error_fatal);
    }

    /*** IRQs ***/

    s->irq_table = exynos4210_init_irq(&s->irqs);

    /* IRQ Gate */
    for (i = 0; i < EXYNOS4210_NCPUS; i++) {
        dev = qdev_create(NULL, "exynos4210.irq_gate");
        qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
        qdev_init_nofail(dev);
        /* Get IRQ Gate input in gate_irq */
        for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
            gate_irq[i][n] = qdev_get_gpio_in(dev, n);
        }
        busdev = SYS_BUS_DEVICE(dev);

        /* Connect IRQ Gate output to CPU's IRQ line */
        sysbus_connect_irq(busdev, 0,
                           qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
    }

    /* Private memory region and Internal GIC */
    dev = qdev_create(NULL, TYPE_A9MPCORE_PRIV);
    qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
        sysbus_connect_irq(busdev, n, gate_irq[n][0]);
    }
    for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
        s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
    }

    /* Cache controller */
    sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);

    /* External GIC */
    dev = qdev_create(NULL, "exynos4210.gic");
    qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    /* Map CPU interface */
    sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
    /* Map Distributer interface */
    sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
        sysbus_connect_irq(busdev, n, gate_irq[n][1]);
    }
    for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
        s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
    }

    /* Internal Interrupt Combiner */
    dev = qdev_create(NULL, "exynos4210.combiner");
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
        sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
    }
    exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
    sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);

    /* External Interrupt Combiner */
    dev = qdev_create(NULL, "exynos4210.combiner");
    qdev_prop_set_uint32(dev, "external", 1);
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
        sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]);
    }
    exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
    sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);

    /* Initialize board IRQs. */
    exynos4210_init_board_irqs(&s->irqs);

    /*** Memory ***/

    /* Chip-ID and OMR */
    memory_region_init_io(&s->chipid_mem, NULL, &exynos4210_chipid_and_omr_ops,
        NULL, "exynos4210.chipid", sizeof(chipid_and_omr));
    memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR,
                                &s->chipid_mem);

    /* Internal ROM */
    memory_region_init_ram(&s->irom_mem, NULL, "exynos4210.irom",
                           EXYNOS4210_IROM_SIZE, &error_fatal);
    memory_region_set_readonly(&s->irom_mem, true);
    memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR,
                                &s->irom_mem);
    /* mirror of iROM */
    memory_region_init_alias(&s->irom_alias_mem, NULL, "exynos4210.irom_alias",
                             &s->irom_mem,
                             0,
                             EXYNOS4210_IROM_SIZE);
    memory_region_set_readonly(&s->irom_alias_mem, true);
    memory_region_add_subregion(system_mem, EXYNOS4210_IROM_MIRROR_BASE_ADDR,
                                &s->irom_alias_mem);

    /* Internal RAM */
    memory_region_init_ram(&s->iram_mem, NULL, "exynos4210.iram",
                           EXYNOS4210_IRAM_SIZE, &error_fatal);
    memory_region_add_subregion(system_mem, EXYNOS4210_IRAM_BASE_ADDR,
                                &s->iram_mem);

   /* PMU.
    * The only reason of existence at the moment is that secondary CPU boot
    * loader uses PMU INFORM5 register as a holding pen.
    */
    sysbus_create_simple("exynos4210.pmu", EXYNOS4210_PMU_BASE_ADDR, NULL);

    sysbus_create_simple("exynos4210.clk", EXYNOS4210_CLK_BASE_ADDR, NULL);
    sysbus_create_simple("exynos4210.rng", EXYNOS4210_RNG_BASE_ADDR, NULL);

    /* PWM */
    sysbus_create_varargs("exynos4210.pwm", EXYNOS4210_PWM_BASE_ADDR,
                          s->irq_table[exynos4210_get_irq(22, 0)],
                          s->irq_table[exynos4210_get_irq(22, 1)],
                          s->irq_table[exynos4210_get_irq(22, 2)],
                          s->irq_table[exynos4210_get_irq(22, 3)],
                          s->irq_table[exynos4210_get_irq(22, 4)],
                          NULL);
    /* RTC */
    sysbus_create_varargs("exynos4210.rtc", EXYNOS4210_RTC_BASE_ADDR,
                          s->irq_table[exynos4210_get_irq(23, 0)],
                          s->irq_table[exynos4210_get_irq(23, 1)],
                          NULL);

    /* Multi Core Timer */
    dev = qdev_create(NULL, "exynos4210.mct");
    qdev_init_nofail(dev);
    busdev = SYS_BUS_DEVICE(dev);
    for (n = 0; n < 4; n++) {
        /* Connect global timer interrupts to Combiner gpio_in */
        sysbus_connect_irq(busdev, n,
                s->irq_table[exynos4210_get_irq(1, 4 + n)]);
    }
    /* Connect local timer interrupts to Combiner gpio_in */
    sysbus_connect_irq(busdev, 4,
            s->irq_table[exynos4210_get_irq(51, 0)]);
    sysbus_connect_irq(busdev, 5,
            s->irq_table[exynos4210_get_irq(35, 3)]);
    sysbus_mmio_map(busdev, 0, EXYNOS4210_MCT_BASE_ADDR);

    /*** I2C ***/
    for (n = 0; n < EXYNOS4210_I2C_NUMBER; n++) {
        uint32_t addr = EXYNOS4210_I2C_BASE_ADDR + EXYNOS4210_I2C_SHIFT * n;
        qemu_irq i2c_irq;

        if (n < 8) {
            i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_I2C_INTG, n)];
        } else {
            i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_HDMI_INTG, 1)];
        }

        dev = qdev_create(NULL, "exynos4210.i2c");
        qdev_init_nofail(dev);
        busdev = SYS_BUS_DEVICE(dev);
        sysbus_connect_irq(busdev, 0, i2c_irq);
        sysbus_mmio_map(busdev, 0, addr);
        s->i2c_if[n] = (I2CBus *)qdev_get_child_bus(dev, "i2c");
    }


    /*** UARTs ***/
    exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
                           EXYNOS4210_UART0_FIFO_SIZE, 0, NULL,
                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 0)]);

    exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
                           EXYNOS4210_UART1_FIFO_SIZE, 1, NULL,
                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 1)]);

    exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
                           EXYNOS4210_UART2_FIFO_SIZE, 2, NULL,
                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 2)]);

    exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
                           EXYNOS4210_UART3_FIFO_SIZE, 3, NULL,
                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 3)]);

    /*** SD/MMC host controllers ***/
    for (n = 0; n < EXYNOS4210_SDHCI_NUMBER; n++) {
        DeviceState *carddev;
        BlockBackend *blk;
        DriveInfo *di;

        /* Compatible with:
         * - SD Host Controller Specification Version 2.0
         * - SDIO Specification Version 2.0
         * - MMC Specification Version 4.3
         * - SDMA
         * - ADMA2
         *
         * As this part of the Exynos4210 is not publically available,
         * we used the "HS-MMC Controller S3C2416X RISC Microprocessor"
         * public datasheet which is very similar (implementing
         * MMC Specification Version 4.0 being the only difference noted)
         */
        dev = qdev_create(NULL, TYPE_SYSBUS_SDHCI);
        qdev_prop_set_uint64(dev, "capareg", EXYNOS4210_SDHCI_CAPABILITIES);
        qdev_init_nofail(dev);

        busdev = SYS_BUS_DEVICE(dev);
        sysbus_mmio_map(busdev, 0, EXYNOS4210_SDHCI_ADDR(n));
        sysbus_connect_irq(busdev, 0, s->irq_table[exynos4210_get_irq(29, n)]);

        di = drive_get(IF_SD, 0, n);
        blk = di ? blk_by_legacy_dinfo(di) : NULL;
        carddev = qdev_create(qdev_get_child_bus(dev, "sd-bus"), TYPE_SD_CARD);
        qdev_prop_set_drive(carddev, "drive", blk, &error_abort);
        qdev_init_nofail(carddev);
    }

    /*** Display controller (FIMD) ***/
    sysbus_create_varargs("exynos4210.fimd", EXYNOS4210_FIMD0_BASE_ADDR,
            s->irq_table[exynos4210_get_irq(11, 0)],
            s->irq_table[exynos4210_get_irq(11, 1)],
            s->irq_table[exynos4210_get_irq(11, 2)],
            NULL);

    sysbus_create_simple(TYPE_EXYNOS4210_EHCI, EXYNOS4210_EHCI_BASE_ADDR,
            s->irq_table[exynos4210_get_irq(28, 3)]);

    return s;
}
示例#30
0
static void mips_jazz_init(MachineState *machine,
                           enum jazz_model_e jazz_model)
{
    MemoryRegion *address_space = get_system_memory();
    char *filename;
    int bios_size, n;
    MIPSCPU *cpu;
    CPUClass *cc;
    CPUMIPSState *env;
    qemu_irq *i8259;
    rc4030_dma *dmas;
    IOMMUMemoryRegion *rc4030_dma_mr;
    MemoryRegion *isa_mem = g_new(MemoryRegion, 1);
    MemoryRegion *isa_io = g_new(MemoryRegion, 1);
    MemoryRegion *rtc = g_new(MemoryRegion, 1);
    MemoryRegion *i8042 = g_new(MemoryRegion, 1);
    MemoryRegion *dma_dummy = g_new(MemoryRegion, 1);
    NICInfo *nd;
    DeviceState *dev, *rc4030;
    SysBusDevice *sysbus;
    ISABus *isa_bus;
    ISADevice *pit;
    DriveInfo *fds[MAX_FD];
    qemu_irq esp_reset, dma_enable;
    MemoryRegion *ram = g_new(MemoryRegion, 1);
    MemoryRegion *bios = g_new(MemoryRegion, 1);
    MemoryRegion *bios2 = g_new(MemoryRegion, 1);

    /* init CPUs */
    cpu = MIPS_CPU(cpu_create(machine->cpu_type));
    env = &cpu->env;
    qemu_register_reset(main_cpu_reset, cpu);

    /* Chipset returns 0 in invalid reads and do not raise data exceptions.
     * However, we can't simply add a global memory region to catch
     * everything, as memory core directly call unassigned_mem_read/write
     * on some invalid accesses, which call do_unassigned_access on the
     * CPU, which raise an exception.
     * Handle that case by hijacking the do_unassigned_access method on
     * the CPU, and do not raise exceptions for data access. */
    cc = CPU_GET_CLASS(cpu);
    real_do_unassigned_access = cc->do_unassigned_access;
    cc->do_unassigned_access = mips_jazz_do_unassigned_access;

    /* allocate RAM */
    memory_region_allocate_system_memory(ram, NULL, "mips_jazz.ram",
                                         machine->ram_size);
    memory_region_add_subregion(address_space, 0, ram);

    memory_region_init_ram(bios, NULL, "mips_jazz.bios", MAGNUM_BIOS_SIZE,
                           &error_fatal);
    memory_region_set_readonly(bios, true);
    memory_region_init_alias(bios2, NULL, "mips_jazz.bios", bios,
                             0, MAGNUM_BIOS_SIZE);
    memory_region_add_subregion(address_space, 0x1fc00000LL, bios);
    memory_region_add_subregion(address_space, 0xfff00000LL, bios2);

    /* load the BIOS 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, 0xfff00000LL,
                                        MAGNUM_BIOS_SIZE);
        g_free(filename);
    } else {
        bios_size = -1;
    }
    if ((bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE) && !qtest_enabled()) {
        error_report("Could not load MIPS bios '%s'", bios_name);
        exit(1);
    }

    /* Init CPU internal devices */
    cpu_mips_irq_init_cpu(cpu);
    cpu_mips_clock_init(cpu);

    /* Chipset */
    rc4030 = rc4030_init(&dmas, &rc4030_dma_mr);
    sysbus = SYS_BUS_DEVICE(rc4030);
    sysbus_connect_irq(sysbus, 0, env->irq[6]);
    sysbus_connect_irq(sysbus, 1, env->irq[3]);
    memory_region_add_subregion(address_space, 0x80000000,
                                sysbus_mmio_get_region(sysbus, 0));
    memory_region_add_subregion(address_space, 0xf0000000,
                                sysbus_mmio_get_region(sysbus, 1));
    memory_region_init_io(dma_dummy, NULL, &dma_dummy_ops, NULL, "dummy_dma", 0x1000);
    memory_region_add_subregion(address_space, 0x8000d000, dma_dummy);

    /* ISA bus: IO space at 0x90000000, mem space at 0x91000000 */
    memory_region_init(isa_io, NULL, "isa-io", 0x00010000);
    memory_region_init(isa_mem, NULL, "isa-mem", 0x01000000);
    memory_region_add_subregion(address_space, 0x90000000, isa_io);
    memory_region_add_subregion(address_space, 0x91000000, isa_mem);
    isa_bus = isa_bus_new(NULL, isa_mem, isa_io, &error_abort);

    /* ISA devices */
    i8259 = i8259_init(isa_bus, env->irq[4]);
    isa_bus_irqs(isa_bus, i8259);
    DMA_init(isa_bus, 0);
    pit = pit_init(isa_bus, 0x40, 0, NULL);
    pcspk_init(isa_bus, pit);

    /* Video card */
    switch (jazz_model) {
    case JAZZ_MAGNUM:
        dev = qdev_create(NULL, "sysbus-g364");
        qdev_init_nofail(dev);
        sysbus = SYS_BUS_DEVICE(dev);
        sysbus_mmio_map(sysbus, 0, 0x60080000);
        sysbus_mmio_map(sysbus, 1, 0x40000000);
        sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(rc4030, 3));
        {
            /* Simple ROM, so user doesn't have to provide one */
            MemoryRegion *rom_mr = g_new(MemoryRegion, 1);
            memory_region_init_ram(rom_mr, NULL, "g364fb.rom", 0x80000,
                                   &error_fatal);
            memory_region_set_readonly(rom_mr, true);
            uint8_t *rom = memory_region_get_ram_ptr(rom_mr);
            memory_region_add_subregion(address_space, 0x60000000, rom_mr);
            rom[0] = 0x10; /* Mips G364 */
        }
        break;
    case JAZZ_PICA61:
        isa_vga_mm_init(0x40000000, 0x60000000, 0, get_system_memory());
        break;
    default:
        break;
    }

    /* Network controller */
    for (n = 0; n < nb_nics; n++) {
        nd = &nd_table[n];
        if (!nd->model)
            nd->model = g_strdup("dp83932");
        if (strcmp(nd->model, "dp83932") == 0) {
            qemu_check_nic_model(nd, "dp83932");

            dev = qdev_create(NULL, "dp8393x");
            qdev_set_nic_properties(dev, nd);
            qdev_prop_set_uint8(dev, "it_shift", 2);
            qdev_prop_set_ptr(dev, "dma_mr", rc4030_dma_mr);
            qdev_init_nofail(dev);
            sysbus = SYS_BUS_DEVICE(dev);
            sysbus_mmio_map(sysbus, 0, 0x80001000);
            sysbus_mmio_map(sysbus, 1, 0x8000b000);
            sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(rc4030, 4));
            break;
        } else if (is_help_option(nd->model)) {
            fprintf(stderr, "qemu: Supported NICs: dp83932\n");
            exit(1);
        } else {
            fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model);
            exit(1);
        }
    }

    /* SCSI adapter */
    esp_init(0x80002000, 0,
             rc4030_dma_read, rc4030_dma_write, dmas[0],
             qdev_get_gpio_in(rc4030, 5), &esp_reset, &dma_enable);

    /* Floppy */
    for (n = 0; n < MAX_FD; n++) {
        fds[n] = drive_get(IF_FLOPPY, 0, n);
    }
    /* FIXME: we should enable DMA with a custom IsaDma device */
    fdctrl_init_sysbus(qdev_get_gpio_in(rc4030, 1), -1, 0x80003000, fds);

    /* Real time clock */
    rtc_init(isa_bus, 1980, NULL);
    memory_region_init_io(rtc, NULL, &rtc_ops, NULL, "rtc", 0x1000);
    memory_region_add_subregion(address_space, 0x80004000, rtc);

    /* Keyboard (i8042) */
    i8042_mm_init(qdev_get_gpio_in(rc4030, 6), qdev_get_gpio_in(rc4030, 7),
                  i8042, 0x1000, 0x1);
    memory_region_add_subregion(address_space, 0x80005000, i8042);

    /* Serial ports */
    if (serial_hds[0]) {
        serial_mm_init(address_space, 0x80006000, 0,
                       qdev_get_gpio_in(rc4030, 8), 8000000/16,
                       serial_hds[0], DEVICE_NATIVE_ENDIAN);
    }
    if (serial_hds[1]) {
        serial_mm_init(address_space, 0x80007000, 0,
                       qdev_get_gpio_in(rc4030, 9), 8000000/16,
                       serial_hds[1], DEVICE_NATIVE_ENDIAN);
    }

    /* Parallel port */
    if (parallel_hds[0])
        parallel_mm_init(address_space, 0x80008000, 0,
                         qdev_get_gpio_in(rc4030, 0), parallel_hds[0]);

    /* FIXME: missing Jazz sound at 0x8000c000, rc4030[2] */

    /* NVRAM */
    dev = qdev_create(NULL, "ds1225y");
    qdev_init_nofail(dev);
    sysbus = SYS_BUS_DEVICE(dev);
    sysbus_mmio_map(sysbus, 0, 0x80009000);

    /* LED indicator */
    sysbus_create_simple("jazz-led", 0x8000f000, NULL);
}