Esempio n. 1
0
void tmu012_init(MemoryRegion *sysmem, hwaddr base,
                 int feat, uint32_t freq,
		 qemu_irq ch0_irq, qemu_irq ch1_irq,
		 qemu_irq ch2_irq0, qemu_irq ch2_irq1)
{
    tmu012_state *s;
    int timer_feat = (feat & TMU012_FEAT_EXTCLK) ? TIMER_FEAT_EXTCLK : 0;

    s = (tmu012_state *)g_malloc0(sizeof(tmu012_state));
    s->feat = feat;
    s->timer[0] = sh_timer_init(freq, timer_feat, ch0_irq);
    s->timer[1] = sh_timer_init(freq, timer_feat, ch1_irq);
    if (feat & TMU012_FEAT_3CHAN)
        s->timer[2] = sh_timer_init(freq, timer_feat | TIMER_FEAT_CAPT,
				    ch2_irq0); /* ch2_irq1 not supported */

    memory_region_init_io(&s->iomem, NULL, &tmu012_ops, s,
                          "timer", 0x100000000ULL);

    memory_region_init_alias(&s->iomem_p4, NULL, "timer-p4",
                             &s->iomem, 0, 0x1000);
    memory_region_add_subregion(sysmem, P4ADDR(base), &s->iomem_p4);

    memory_region_init_alias(&s->iomem_a7, NULL, "timer-a7",
                             &s->iomem, 0, 0x1000);
    memory_region_add_subregion(sysmem, A7ADDR(base), &s->iomem_a7);
    /* ??? Save/restore.  */
}
Esempio n. 2
0
static unsigned int sh_intc_register(MemoryRegion *sysmem,
                             struct intc_desc *desc,
                             const unsigned long address,
                             const char *type,
                             const char *action,
                             const unsigned int index)
{
    char name[60];
    MemoryRegion *iomem, *iomem_p4, *iomem_a7;

    if (!address) {
        return 0;
    }

    iomem = &desc->iomem;
    iomem_p4 = desc->iomem_aliases + index;
    iomem_a7 = iomem_p4 + 1;

#define SH_INTC_IOMEM_FORMAT "interrupt-controller-%s-%s-%s"
    snprintf(name, sizeof(name), SH_INTC_IOMEM_FORMAT, type, action, "p4");
    memory_region_init_alias(iomem_p4, NULL, name, iomem, INTC_A7(address), 4);
    memory_region_add_subregion(sysmem, P4ADDR(address), iomem_p4);

    snprintf(name, sizeof(name), SH_INTC_IOMEM_FORMAT, type, action, "a7");
    memory_region_init_alias(iomem_a7, NULL, name, iomem, INTC_A7(address), 4);
    memory_region_add_subregion(sysmem, A7ADDR(address), iomem_a7);
#undef SH_INTC_IOMEM_FORMAT

    /* used to increment aliases index */
    return 2;
}
Esempio n. 3
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;
}
Esempio n. 4
0
static void pnv_lpc_realize(DeviceState *dev, Error **errp)
{
    PnvLpcController *lpc = PNV_LPC(dev);
    Object *obj;
    Error *error = NULL;

    /* Reg inits */
    lpc->lpc_hc_fw_rd_acc_size = LPC_HC_FW_RD_4B;

    /* Create address space and backing MR for the OPB bus */
    memory_region_init(&lpc->opb_mr, OBJECT(dev), "lpc-opb", 0x100000000ull);
    address_space_init(&lpc->opb_as, &lpc->opb_mr, "lpc-opb");

    /* Create ISA IO and Mem space regions which are the root of
     * the ISA bus (ie, ISA address spaces). We don't create a
     * separate one for FW which we alias to memory.
     */
    memory_region_init(&lpc->isa_io, OBJECT(dev), "isa-io", ISA_IO_SIZE);
    memory_region_init(&lpc->isa_mem, OBJECT(dev), "isa-mem", ISA_MEM_SIZE);
    memory_region_init(&lpc->isa_fw, OBJECT(dev),  "isa-fw", ISA_FW_SIZE);

    /* Create windows from the OPB space to the ISA space */
    memory_region_init_alias(&lpc->opb_isa_io, OBJECT(dev), "lpc-isa-io",
                             &lpc->isa_io, 0, LPC_IO_OPB_SIZE);
    memory_region_add_subregion(&lpc->opb_mr, LPC_IO_OPB_ADDR,
                                &lpc->opb_isa_io);
    memory_region_init_alias(&lpc->opb_isa_mem, OBJECT(dev), "lpc-isa-mem",
                             &lpc->isa_mem, 0, LPC_MEM_OPB_SIZE);
    memory_region_add_subregion(&lpc->opb_mr, LPC_MEM_OPB_ADDR,
                                &lpc->opb_isa_mem);
    memory_region_init_alias(&lpc->opb_isa_fw, OBJECT(dev), "lpc-isa-fw",
                             &lpc->isa_fw, 0, LPC_FW_OPB_SIZE);
    memory_region_add_subregion(&lpc->opb_mr, LPC_FW_OPB_ADDR,
                                &lpc->opb_isa_fw);

    /* Create MMIO regions for LPC HC and OPB registers */
    memory_region_init_io(&lpc->opb_master_regs, OBJECT(dev), &opb_master_ops,
                          lpc, "lpc-opb-master", LPC_OPB_REGS_OPB_SIZE);
    memory_region_add_subregion(&lpc->opb_mr, LPC_OPB_REGS_OPB_ADDR,
                                &lpc->opb_master_regs);
    memory_region_init_io(&lpc->lpc_hc_regs, OBJECT(dev), &lpc_hc_ops, lpc,
                          "lpc-hc", LPC_HC_REGS_OPB_SIZE);
    memory_region_add_subregion(&lpc->opb_mr, LPC_HC_REGS_OPB_ADDR,
                                &lpc->lpc_hc_regs);

    /* XScom region for LPC registers */
    pnv_xscom_region_init(&lpc->xscom_regs, OBJECT(dev),
                          &pnv_lpc_xscom_ops, lpc, "xscom-lpc",
                          PNV_XSCOM_LPC_SIZE);

    /* get PSI object from chip */
    obj = object_property_get_link(OBJECT(dev), "psi", &error);
    if (!obj) {
        error_setg(errp, "%s: required link 'psi' not found: %s",
                   __func__, error_get_pretty(error));
        return;
    }
    lpc->psi = PNV_PSI(obj);
}
Esempio n. 5
0
File: q35.c Progetto: m000/panda
static void mch_realize(PCIDevice *d, Error **errp)
{
    int i;
    MCHPCIState *mch = MCH_PCI_DEVICE(d);

    /* setup pci memory mapping */
    pc_pci_as_mapping_init(OBJECT(mch), mch->system_memory,
                           mch->pci_address_space);

    /* if *disabled* show SMRAM to all CPUs */
    memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region",
                             mch->pci_address_space, 0xa0000, 0x20000);
    memory_region_add_subregion_overlap(mch->system_memory, 0xa0000,
                                        &mch->smram_region, 1);
    memory_region_set_enabled(&mch->smram_region, true);

    memory_region_init_alias(&mch->open_high_smram, OBJECT(mch), "smram-open-high",
                             mch->ram_memory, 0xa0000, 0x20000);
    memory_region_add_subregion_overlap(mch->system_memory, 0xfeda0000,
                                        &mch->open_high_smram, 1);
    memory_region_set_enabled(&mch->open_high_smram, false);

    /* smram, as seen by SMM CPUs */
    memory_region_init(&mch->smram, OBJECT(mch), "smram", 1ull << 32);
    memory_region_set_enabled(&mch->smram, true);
    memory_region_init_alias(&mch->low_smram, OBJECT(mch), "smram-low",
                             mch->ram_memory, 0xa0000, 0x20000);
    memory_region_set_enabled(&mch->low_smram, true);
    memory_region_add_subregion(&mch->smram, 0xa0000, &mch->low_smram);
    memory_region_init_alias(&mch->high_smram, OBJECT(mch), "smram-high",
                             mch->ram_memory, 0xa0000, 0x20000);
    memory_region_set_enabled(&mch->high_smram, true);
    memory_region_add_subregion(&mch->smram, 0xfeda0000, &mch->high_smram);

    memory_region_init_io(&mch->tseg_blackhole, OBJECT(mch),
                          &tseg_blackhole_ops, NULL,
                          "tseg-blackhole", 0);
    memory_region_set_enabled(&mch->tseg_blackhole, false);
    memory_region_add_subregion_overlap(mch->system_memory,
                                        mch->below_4g_mem_size,
                                        &mch->tseg_blackhole, 1);

    memory_region_init_alias(&mch->tseg_window, OBJECT(mch), "tseg-window",
                             mch->ram_memory, mch->below_4g_mem_size, 0);
    memory_region_set_enabled(&mch->tseg_window, false);
    memory_region_add_subregion(&mch->smram, mch->below_4g_mem_size,
                                &mch->tseg_window);
    object_property_add_const_link(qdev_get_machine(), "smram",
                                   OBJECT(&mch->smram), &error_abort);

    init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory,
             mch->pci_address_space, &mch->pam_regions[0],
             PAM_BIOS_BASE, PAM_BIOS_SIZE);
    for (i = 0; i < 12; ++i) {
        init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory,
                 mch->pci_address_space, &mch->pam_regions[i+1],
                 PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE);
    }
}
Esempio n. 6
0
static int exynos4210_gic_init(SysBusDevice *dev)
{
    Exynos4210GicState *s = FROM_SYSBUS(Exynos4210GicState, dev);
    uint32_t i;
    const char cpu_prefix[] = "exynos4210-gic-alias_cpu";
    const char dist_prefix[] = "exynos4210-gic-alias_dist";
    char cpu_alias_name[sizeof(cpu_prefix) + 3];
    char dist_alias_name[sizeof(cpu_prefix) + 3];
    SysBusDevice *busdev;

    s->gic = qdev_create(NULL, "arm_gic");
    qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
    qdev_prop_set_uint32(s->gic, "num-irq", EXYNOS4210_GIC_NIRQ);
    qdev_init_nofail(s->gic);
    busdev = SYS_BUS_DEVICE(s->gic);

    /* Pass through outbound IRQ lines from the GIC */
    sysbus_pass_irq(dev, busdev);

    /* Pass through inbound GPIO lines to the GIC */
    qdev_init_gpio_in(&s->busdev.qdev, exynos4210_gic_set_irq,
                      EXYNOS4210_GIC_NIRQ - 32);

    memory_region_init(&s->cpu_container, "exynos4210-cpu-container",
            EXYNOS4210_EXT_GIC_CPU_REGION_SIZE);
    memory_region_init(&s->dist_container, "exynos4210-dist-container",
            EXYNOS4210_EXT_GIC_DIST_REGION_SIZE);

    for (i = 0; i < s->num_cpu; i++) {
        /* Map CPU interface per SMP Core */
        sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
        memory_region_init_alias(&s->cpu_alias[i],
                                 cpu_alias_name,
                                 sysbus_mmio_get_region(busdev, 1),
                                 0,
                                 EXYNOS4210_GIC_CPU_REGION_SIZE);
        memory_region_add_subregion(&s->cpu_container,
                EXYNOS4210_EXT_GIC_CPU_GET_OFFSET(i), &s->cpu_alias[i]);

        /* Map Distributor per SMP Core */
        sprintf(dist_alias_name, "%s%x", dist_prefix, i);
        memory_region_init_alias(&s->dist_alias[i],
                                 dist_alias_name,
                                 sysbus_mmio_get_region(busdev, 0),
                                 0,
                                 EXYNOS4210_GIC_DIST_REGION_SIZE);
        memory_region_add_subregion(&s->dist_container,
                EXYNOS4210_EXT_GIC_DIST_GET_OFFSET(i), &s->dist_alias[i]);
    }

    sysbus_init_mmio(dev, &s->cpu_container);
    sysbus_init_mmio(dev, &s->dist_container);

    return 0;
}
Esempio n. 7
0
static void nios2_generic_nommu_init(MachineState *machine)
{
    Nios2CPU *cpu;
    MemoryRegion *address_space_mem = get_system_memory();
    MemoryRegion *phys_tcm = g_new(MemoryRegion, 1);
    MemoryRegion *phys_tcm_alias = g_new(MemoryRegion, 1);
    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
    MemoryRegion *phys_ram_alias = g_new(MemoryRegion, 1);
    ram_addr_t tcm_base = 0x0;
    ram_addr_t tcm_size = 0x1000;    /* 1 kiB, but QEMU limit is 4 kiB */
    ram_addr_t ram_base = 0x10000000;
    ram_addr_t ram_size = 0x08000000;

    /* Physical TCM (tb_ram_1k) with alias at 0xc0000000 */
    memory_region_init_ram(phys_tcm, NULL, "nios2.tcm", tcm_size,
                           &error_abort);
    memory_region_init_alias(phys_tcm_alias, NULL, "nios2.tcm.alias",
                             phys_tcm, 0, tcm_size);
    memory_region_add_subregion(address_space_mem, tcm_base, phys_tcm);
    memory_region_add_subregion(address_space_mem, 0xc0000000 + tcm_base,
                                phys_tcm_alias);

    /* Physical DRAM with alias at 0xc0000000 */
    memory_region_init_ram(phys_ram, NULL, "nios2.ram", ram_size,
                           &error_abort);
    memory_region_init_alias(phys_ram_alias, NULL, "nios2.ram.alias",
                             phys_ram, 0, ram_size);
    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
    memory_region_add_subregion(address_space_mem, 0xc0000000 + ram_base,
                                phys_ram_alias);

    cpu = NIOS2_CPU(cpu_create(TYPE_NIOS2_CPU));

    /* Remove MMU */
    cpu->mmu_present = false;

    /* Reset vector is the first 32 bytes of RAM.  */
    cpu->reset_addr = ram_base;

    /* The interrupt vector comes right after reset.  */
    cpu->exception_addr = ram_base + 0x20;

    /*
     * The linker script does have a TLB miss memory region declared,
     * but this should never be used with no MMU.
     */
    cpu->fast_tlb_miss_addr = 0x7fff400;

    nios2_load_kernel(cpu, ram_base, ram_size, machine->initrd_filename,
                      BINARY_DEVICE_TREE_FILE, NULL);
}
Esempio n. 8
0
static int mch_init(PCIDevice *d)
{
    int i;
    hwaddr pci_hole64_size;
    MCHPCIState *mch = MCH_PCI_DEVICE(d);

    /* Leave enough space for the biggest MCFG BAR */
    /* TODO: this matches current bios behaviour, but
     * it's not a power of two, which means an MTRR
     * can't cover it exactly.
     */
    mch->guest_info->pci_info.w32.begin = MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT +
        MCH_HOST_BRIDGE_PCIEXBAR_MAX;

    /* setup pci memory regions */
    memory_region_init_alias(&mch->pci_hole, OBJECT(mch), "pci-hole",
                             mch->pci_address_space,
                             mch->below_4g_mem_size,
                             0x100000000ULL - mch->below_4g_mem_size);
    memory_region_add_subregion(mch->system_memory, mch->below_4g_mem_size,
                                &mch->pci_hole);
    pci_hole64_size = (sizeof(hwaddr) == 4 ? 0 :
                       ((uint64_t)1 << 62));
    memory_region_init_alias(&mch->pci_hole_64bit, OBJECT(mch), "pci-hole64",
                             mch->pci_address_space,
                             0x100000000ULL + mch->above_4g_mem_size,
                             pci_hole64_size);
    if (pci_hole64_size) {
        memory_region_add_subregion(mch->system_memory,
                                    0x100000000ULL + mch->above_4g_mem_size,
                                    &mch->pci_hole_64bit);
    }
    /* smram */
    cpu_smm_register(&mch_set_smm, mch);
    memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region",
                             mch->pci_address_space, 0xa0000, 0x20000);
    memory_region_add_subregion_overlap(mch->system_memory, 0xa0000,
                                        &mch->smram_region, 1);
    memory_region_set_enabled(&mch->smram_region, false);
    init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space,
             &mch->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE);
    for (i = 0; i < 12; ++i) {
        init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space,
                 &mch->pam_regions[i+1], PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE,
                 PAM_EXPAN_SIZE);
    }
    return 0;
}
Esempio n. 9
0
/*
 * The mac-io has two interfaces to the ESCC. One is called "escc-legacy",
 * while the other one is the normal, current ESCC interface.
 *
 * The magic below creates memory aliases to spawn the escc-legacy device
 * purely by rerouting the respective registers to our escc region. This
 * works because the only difference between the two memory regions is the
 * register layout, not their semantics.
 *
 * Reference: ftp://ftp.software.ibm.com/rs6000/technology/spec/chrp/inwork/CHRP_IORef_1.0.pdf
 */
static void macio_escc_legacy_setup(MacIOState *s)
{
    ESCCState *escc = ESCC(&s->escc);
    SysBusDevice *sbd = SYS_BUS_DEVICE(escc);
    MemoryRegion *escc_legacy = g_new(MemoryRegion, 1);
    MemoryRegion *bar = &s->bar;
    int i;
    static const int maps[] = {
        0x00, 0x00, /* Command B */
        0x02, 0x20, /* Command A */
        0x04, 0x10, /* Data B */
        0x06, 0x30, /* Data A */
        0x08, 0x40, /* Enhancement B */
        0x0A, 0x50, /* Enhancement A */
        0x80, 0x80, /* Recovery count */
        0x90, 0x90, /* Start A */
        0xa0, 0xa0, /* Start B */
        0xb0, 0xb0, /* Detect AB */
    };

    memory_region_init(escc_legacy, OBJECT(s), "escc-legacy", 256);
    for (i = 0; i < ARRAY_SIZE(maps); i += 2) {
        MemoryRegion *port = g_new(MemoryRegion, 1);
        memory_region_init_alias(port, OBJECT(s), "escc-legacy-port",
                                 sysbus_mmio_get_region(sbd, 0),
                                 maps[i + 1], 0x2);
        memory_region_add_subregion(escc_legacy, maps[i], port);
    }

    memory_region_add_subregion(bar, 0x12000, escc_legacy);
}
Esempio n. 10
0
File: q35.c Progetto: AlexHai/qemu
static int mch_init(PCIDevice *d)
{
    int i;
    MCHPCIState *mch = MCH_PCI_DEVICE(d);

    /* setup pci memory mapping */
    pc_pci_as_mapping_init(OBJECT(mch), mch->system_memory,
                           mch->pci_address_space);

    /* smram */
    cpu_smm_register(&mch_set_smm, mch);
    memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region",
                             mch->pci_address_space, 0xa0000, 0x20000);
    memory_region_add_subregion_overlap(mch->system_memory, 0xa0000,
                                        &mch->smram_region, 1);
    memory_region_set_enabled(&mch->smram_region, false);
    init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory,
             mch->pci_address_space, &mch->pam_regions[0],
             PAM_BIOS_BASE, PAM_BIOS_SIZE);
    for (i = 0; i < 12; ++i) {
        init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory,
                 mch->pci_address_space, &mch->pam_regions[i+1],
                 PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE);
    }
    /* Intel IOMMU (VT-d) */
    if (qemu_opt_get_bool(qemu_get_machine_opts(), "iommu", false)) {
        mch_init_dmar(mch);
    }
    return 0;
}
Esempio n. 11
0
/* Create an alias of an entire original MemoryRegion @orig
 * located at @base in the memory map.
 */
static void make_ram_alias(MemoryRegion *mr, const char *name,
                           MemoryRegion *orig, hwaddr base)
{
    memory_region_init_alias(mr, NULL, name, orig, 0,
                             memory_region_size(orig));
    memory_region_add_subregion(get_system_memory(), base, mr);
}
Esempio n. 12
0
/* BAR mapping */
static void ppc440_pcix_update_pom(PPC440PCIXState *s, int idx)
{
    MemoryRegion *mem = &s->pom[idx].mr;
    MemoryRegion *address_space_mem = get_system_memory();
    char *name;
    uint32_t size;

    /* Before we modify anything, unmap and destroy the region */
    ppc440_pcix_clear_region(address_space_mem, mem);

    if (!(s->pom[idx].sa & 1)) {
        /* Not enabled, nothing to do */
        return;
    }

    name = g_strdup_printf("PCI Outbound Window %d", idx);
    size = ~(s->pom[idx].sa & 0xfffffffe) + 1;
    if (!size) {
        size = 0xffffffff;
    }
    memory_region_init_alias(mem, OBJECT(s), name, &s->busmem,
                             s->pom[idx].pcia, size);
    memory_region_add_subregion(address_space_mem, s->pom[idx].la, mem);
    g_free(name);

    trace_ppc440_pcix_update_pom(idx, size, s->pom[idx].la, s->pom[idx].pcia);
}
Esempio n. 13
0
/*
 * The mac-io has two interfaces to the ESCC. One is called "escc-legacy",
 * while the other one is the normal, current ESCC interface.
 *
 * The magic below creates memory aliases to spawn the escc-legacy device
 * purely by rerouting the respective registers to our escc region. This
 * works because the only difference between the two memory regions is the
 * register layout, not their semantics.
 *
 * Reference: ftp://ftp.software.ibm.com/rs6000/technology/spec/chrp/inwork/CHRP_IORef_1.0.pdf
 */
static void macio_escc_legacy_setup(MacIOState *macio_state)
{
    MemoryRegion *escc_legacy = g_new(MemoryRegion, 1);
    MemoryRegion *bar = &macio_state->bar;
    int i;
    static const int maps[] = {
        0x00, 0x00,
        0x02, 0x20,
        0x04, 0x10,
        0x06, 0x30,
        0x08, 0x40,
        0x0A, 0x50,
        0x60, 0x60,
        0x70, 0x70,
        0x80, 0x70,
        0x90, 0x80,
        0xA0, 0x90,
        0xB0, 0xA0,
        0xC0, 0xB0,
        0xD0, 0xC0,
        0xE0, 0xD0,
        0xF0, 0xE0,
    };

    memory_region_init(escc_legacy, NULL, "escc-legacy", 256);
    for (i = 0; i < ARRAY_SIZE(maps); i += 2) {
        MemoryRegion *port = g_new(MemoryRegion, 1);
        memory_region_init_alias(port, NULL, "escc-legacy-port",
                                 macio_state->escc_mem, maps[i+1], 0x2);
        memory_region_add_subregion(escc_legacy, maps[i], port);
    }

    memory_region_add_subregion(bar, 0x12000, escc_legacy);
}
Esempio n. 14
0
static void nvdimm_realize(PCDIMMDevice *dimm, Error **errp)
{
    MemoryRegion *mr = host_memory_backend_get_memory(dimm->hostmem, errp);
    NVDIMMDevice *nvdimm = NVDIMM(dimm);
    uint64_t align, pmem_size, size = memory_region_size(mr);

    align = memory_region_get_alignment(mr);

    pmem_size = size - nvdimm->label_size;
    nvdimm->label_data = memory_region_get_ram_ptr(mr) + pmem_size;
    pmem_size = QEMU_ALIGN_DOWN(pmem_size, align);

    if (size <= nvdimm->label_size || !pmem_size) {
        HostMemoryBackend *hostmem = dimm->hostmem;
        char *path = object_get_canonical_path_component(OBJECT(hostmem));

        error_setg(errp, "the size of memdev %s (0x%" PRIx64 ") is too "
                   "small to contain nvdimm label (0x%" PRIx64 ") and "
                   "aligned PMEM (0x%" PRIx64 ")",
                   path, memory_region_size(mr), nvdimm->label_size, align);
        g_free(path);
        return;
    }

    memory_region_init_alias(&nvdimm->nvdimm_mr, OBJECT(dimm),
                             "nvdimm-memory", mr, 0, pmem_size);
    nvdimm->nvdimm_mr.align = align;
}
Esempio n. 15
0
static void pnv_lpc_realize(DeviceState *dev, Error **errp)
{
    PnvLpcController *lpc = PNV_LPC(dev);

    /* Reg inits */
    lpc->lpc_hc_fw_rd_acc_size = LPC_HC_FW_RD_4B;

    /* Create address space and backing MR for the OPB bus */
    memory_region_init(&lpc->opb_mr, OBJECT(dev), "lpc-opb", 0x100000000ull);
    address_space_init(&lpc->opb_as, &lpc->opb_mr, "lpc-opb");

    /* Create ISA IO and Mem space regions which are the root of
     * the ISA bus (ie, ISA address spaces). We don't create a
     * separate one for FW which we alias to memory.
     */
    memory_region_init(&lpc->isa_io, OBJECT(dev), "isa-io", ISA_IO_SIZE);
    memory_region_init(&lpc->isa_mem, OBJECT(dev), "isa-mem", ISA_MEM_SIZE);

    /* Create windows from the OPB space to the ISA space */
    memory_region_init_alias(&lpc->opb_isa_io, OBJECT(dev), "lpc-isa-io",
                             &lpc->isa_io, 0, LPC_IO_OPB_SIZE);
    memory_region_add_subregion(&lpc->opb_mr, LPC_IO_OPB_ADDR,
                                &lpc->opb_isa_io);
    memory_region_init_alias(&lpc->opb_isa_mem, OBJECT(dev), "lpc-isa-mem",
                             &lpc->isa_mem, 0, LPC_MEM_OPB_SIZE);
    memory_region_add_subregion(&lpc->opb_mr, LPC_MEM_OPB_ADDR,
                                &lpc->opb_isa_mem);
    memory_region_init_alias(&lpc->opb_isa_fw, OBJECT(dev), "lpc-isa-fw",
                             &lpc->isa_mem, 0, LPC_FW_OPB_SIZE);
    memory_region_add_subregion(&lpc->opb_mr, LPC_FW_OPB_ADDR,
                                &lpc->opb_isa_fw);

    /* Create MMIO regions for LPC HC and OPB registers */
    memory_region_init_io(&lpc->opb_master_regs, OBJECT(dev), &opb_master_ops,
                          lpc, "lpc-opb-master", LPC_OPB_REGS_OPB_SIZE);
    memory_region_add_subregion(&lpc->opb_mr, LPC_OPB_REGS_OPB_ADDR,
                                &lpc->opb_master_regs);
    memory_region_init_io(&lpc->lpc_hc_regs, OBJECT(dev), &lpc_hc_ops, lpc,
                          "lpc-hc", LPC_HC_REGS_OPB_SIZE);
    memory_region_add_subregion(&lpc->opb_mr, LPC_HC_REGS_OPB_ADDR,
                                &lpc->lpc_hc_regs);

    /* XScom region for LPC registers */
    pnv_xscom_region_init(&lpc->xscom_regs, OBJECT(dev),
                          &pnv_lpc_xscom_ops, lpc, "xscom-lpc",
                          PNV_XSCOM_LPC_SIZE);
}
Esempio n. 16
0
static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
                                  ram_addr_t ram_size,
                                  const char *cpu_model,
                                  qemu_irq *pic)
{
    MemoryRegion *sysmem = get_system_memory();
    MemoryRegion *ram = g_new(MemoryRegion, 1);
    MemoryRegion *lowram = g_new(MemoryRegion, 1);
    ram_addr_t low_ram_size;

    if (!cpu_model) {
        cpu_model = "cortex-a9";
    }

    if (ram_size > 0x40000000) {
        /* 1GB is the maximum the address space permits */
        fprintf(stderr, "vexpress-a9: cannot model more than 1GB RAM\n");
        exit(1);
    }

    memory_region_init_ram(ram, NULL, "vexpress.highmem", ram_size,
                           &error_abort);
    vmstate_register_ram_global(ram);
    low_ram_size = ram_size;
    if (low_ram_size > 0x4000000) {
        low_ram_size = 0x4000000;
    }
    /* RAM is from 0x60000000 upwards. The bottom 64MB of the
     * address space should in theory be remappable to various
     * things including ROM or RAM; we always map the RAM there.
     */
    memory_region_init_alias(lowram, NULL, "vexpress.lowmem", ram, 0, low_ram_size);
    memory_region_add_subregion(sysmem, 0x0, lowram);
    memory_region_add_subregion(sysmem, 0x60000000, ram);

    /* 0x1e000000 A9MPCore (SCU) private memory region */
    init_cpus(cpu_model, "a9mpcore_priv", 0x1e000000, pic);

    /* Daughterboard peripherals : 0x10020000 .. 0x20000000 */

    /* 0x10020000 PL111 CLCD (daughterboard) */
    sysbus_create_simple("pl111", 0x10020000, pic[44]);

    /* 0x10060000 AXI RAM */
    /* 0x100e0000 PL341 Dynamic Memory Controller */
    /* 0x100e1000 PL354 Static Memory Controller */
    /* 0x100e2000 System Configuration Controller */

    sysbus_create_simple("sp804", 0x100e4000, pic[48]);
    /* 0x100e5000 SP805 Watchdog module */
    /* 0x100e6000 BP147 TrustZone Protection Controller */
    /* 0x100e9000 PL301 'Fast' AXI matrix */
    /* 0x100ea000 PL301 'Slow' AXI matrix */
    /* 0x100ec000 TrustZone Address Space Controller */
    /* 0x10200000 CoreSight debug APB */
    /* 0x1e00a000 PL310 L2 Cache Controller */
    sysbus_create_varargs("l2x0", 0x1e00a000, NULL);
}
Esempio n. 17
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);
}
Esempio n. 18
0
static int exynos4210_gic_init(SysBusDevice *dev)
{
    Exynos4210GicState *s = FROM_SYSBUSGIC(Exynos4210GicState, dev);
    uint32_t i;
    const char cpu_prefix[] = "exynos4210-gic-alias_cpu";
    const char dist_prefix[] = "exynos4210-gic-alias_dist";
    char cpu_alias_name[sizeof(cpu_prefix) + 3];
    char dist_alias_name[sizeof(cpu_prefix) + 3];

    gic_init(&s->gic, s->num_cpu, EXYNOS4210_GIC_NIRQ);

    memory_region_init(&s->cpu_container, "exynos4210-cpu-container",
            EXYNOS4210_EXT_GIC_CPU_REGION_SIZE);
    memory_region_init(&s->dist_container, "exynos4210-dist-container",
            EXYNOS4210_EXT_GIC_DIST_REGION_SIZE);

    for (i = 0; i < s->num_cpu; i++) {
        /* Map CPU interface per SMP Core */
        sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
        memory_region_init_alias(&s->cpu_alias[i],
                                 cpu_alias_name,
                                 &s->gic.cpuiomem[0],
                                 0,
                                 EXYNOS4210_GIC_CPU_REGION_SIZE);
        memory_region_add_subregion(&s->cpu_container,
                EXYNOS4210_EXT_GIC_CPU_GET_OFFSET(i), &s->cpu_alias[i]);

        /* Map Distributor per SMP Core */
        sprintf(dist_alias_name, "%s%x", dist_prefix, i);
        memory_region_init_alias(&s->dist_alias[i],
                                 dist_alias_name,
                                 &s->gic.iomem,
                                 0,
                                 EXYNOS4210_GIC_DIST_REGION_SIZE);
        memory_region_add_subregion(&s->dist_container,
                EXYNOS4210_EXT_GIC_DIST_GET_OFFSET(i), &s->dist_alias[i]);
    }

    sysbus_init_mmio(dev, &s->cpu_container);
    sysbus_init_mmio(dev, &s->dist_container);

    gic_cpu_write(&s->gic, 1, 0, 1);

    return 0;
}
Esempio n. 19
0
static int mch_init(PCIDevice *d)
{
    int i;
    MCHPCIState *mch = MCH_PCI_DEVICE(d);
    uint64_t pci_hole64_size;

    /* setup pci memory regions */
    memory_region_init_alias(&mch->pci_hole, OBJECT(mch), "pci-hole",
                             mch->pci_address_space,
                             mch->below_4g_mem_size,
                             0x100000000ULL - mch->below_4g_mem_size);
    memory_region_add_subregion(mch->system_memory, mch->below_4g_mem_size,
                                &mch->pci_hole);

    pci_hole64_size = pci_host_get_hole64_size(mch->pci_hole64_size);
    pc_init_pci64_hole(&mch->pci_info, 0x100000000ULL + mch->above_4g_mem_size,
                       pci_hole64_size);
    memory_region_init_alias(&mch->pci_hole_64bit, OBJECT(mch), "pci-hole64",
                             mch->pci_address_space,
                             mch->pci_info.w64.begin,
                             pci_hole64_size);
    if (pci_hole64_size) {
        memory_region_add_subregion(mch->system_memory,
                                    mch->pci_info.w64.begin,
                                    &mch->pci_hole_64bit);
    }
    /* smram */
    cpu_smm_register(&mch_set_smm, mch);
    memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region",
                             mch->pci_address_space, 0xa0000, 0x20000);
    memory_region_add_subregion_overlap(mch->system_memory, 0xa0000,
                                        &mch->smram_region, 1);
    memory_region_set_enabled(&mch->smram_region, false);
    init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space,
             &mch->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE);
    for (i = 0; i < 12; ++i) {
        init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space,
                 &mch->pam_regions[i+1], PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE,
                 PAM_EXPAN_SIZE);
    }
    return 0;
}
Esempio n. 20
0
File: sun4u.c Progetto: cardoe/qemu
static int
pci_ebus_init1(PCIDevice *pci_dev)
{
    EbusState *s = DO_UPCAST(EbusState, pci_dev, pci_dev);

    isa_bus_new(&pci_dev->qdev, pci_address_space_io(pci_dev));

    pci_dev->config[0x04] = 0x06; // command = bus master, pci mem
    pci_dev->config[0x05] = 0x00;
    pci_dev->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
    pci_dev->config[0x07] = 0x03; // status = medium devsel
    pci_dev->config[0x09] = 0x00; // programming i/f
    pci_dev->config[0x0D] = 0x0a; // latency_timer

    memory_region_init_alias(&s->bar0, OBJECT(s), "bar0", get_system_io(),
                             0, 0x1000000);
    pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar0);
    memory_region_init_alias(&s->bar1, OBJECT(s), "bar1", get_system_io(),
                             0, 0x800000);
    pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar1);
    return 0;
}
Esempio n. 21
0
static void pci_bridge_init_vga_aliases(PCIBridge *br, PCIBus *parent,
                                        MemoryRegion *alias_vga)
{
    PCIDevice *pd = PCI_DEVICE(br);
    uint16_t brctl = pci_get_word(pd->config + PCI_BRIDGE_CONTROL);

    memory_region_init_alias(&alias_vga[QEMU_PCI_VGA_IO_LO], OBJECT(br),
                             "pci_bridge_vga_io_lo", &br->address_space_io,
                             QEMU_PCI_VGA_IO_LO_BASE, QEMU_PCI_VGA_IO_LO_SIZE);
    memory_region_init_alias(&alias_vga[QEMU_PCI_VGA_IO_HI], OBJECT(br),
                             "pci_bridge_vga_io_hi", &br->address_space_io,
                             QEMU_PCI_VGA_IO_HI_BASE, QEMU_PCI_VGA_IO_HI_SIZE);
    memory_region_init_alias(&alias_vga[QEMU_PCI_VGA_MEM], OBJECT(br),
                             "pci_bridge_vga_mem", &br->address_space_mem,
                             QEMU_PCI_VGA_MEM_BASE, QEMU_PCI_VGA_MEM_SIZE);

    if (brctl & PCI_BRIDGE_CTL_VGA) {
        pci_register_vga(pd, &alias_vga[QEMU_PCI_VGA_MEM],
                         &alias_vga[QEMU_PCI_VGA_IO_LO],
                         &alias_vga[QEMU_PCI_VGA_IO_HI]);
    }
}
Esempio n. 22
0
/*
 * Set up replicated mappings of the same region.
 */
static void pflash_setup_mappings(PFlashCFI02 *pfl)
{
    unsigned i;
    hwaddr size = memory_region_size(&pfl->orig_mem);

    memory_region_init(&pfl->mem, OBJECT(pfl), "pflash", pfl->mappings * size);
    pfl->mem_mappings = g_new(MemoryRegion, pfl->mappings);
    for (i = 0; i < pfl->mappings; ++i) {
        memory_region_init_alias(&pfl->mem_mappings[i], OBJECT(pfl),
                                 "pflash-alias", &pfl->orig_mem, 0, size);
        memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i]);
    }
}
Esempio n. 23
0
/*
 * Set up replicated mappings of the same region.
 */
static void pflash_setup_mappings(pflash_t *pfl)
{
    unsigned i;
    target_phys_addr_t size = memory_region_size(&pfl->orig_mem);

    memory_region_init(&pfl->mem, "pflash", pfl->mappings * size);
    pfl->mem_mappings = g_new(MemoryRegion, pfl->mappings);
    for (i = 0; i < pfl->mappings; ++i) {
        memory_region_init_alias(&pfl->mem_mappings[i], "pflash-alias",
                                 &pfl->orig_mem, 0, size);
        memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i]);
    }
}
Esempio n. 24
0
static void pci_bridge_init_alias(PCIBridge *bridge, MemoryRegion *alias,
                                  uint8_t type, const char *name,
                                  MemoryRegion *space,
                                  MemoryRegion *parent_space,
                                  bool enabled)
{
    pcibus_t base = pci_bridge_get_base(&bridge->dev, type);
    pcibus_t limit = pci_bridge_get_limit(&bridge->dev, type);
    /* TODO: this doesn't handle base = 0 limit = 2^64 - 1 correctly.
     * Apparently no way to do this with existing memory APIs. */
    pcibus_t size = enabled && limit >= base ? limit + 1 - base : 0;

    memory_region_init_alias(alias, name, space, base, size);
    memory_region_add_subregion_overlap(parent_space, base, alias, 1);
}
Esempio n. 25
0
static void onenand_mem_setup(OneNANDState *s)
{
    /* XXX: We should use IO_MEM_ROMD but we broke it earlier...
     * Both 0x0000 ... 0x01ff and 0x8000 ... 0x800f can be used to
     * write boot commands.  Also take note of the BWPS bit.  */
    memory_region_init(&s->container, "onenand", 0x10000 << s->shift);
    memory_region_add_subregion(&s->container, 0, &s->iomem);
    memory_region_init_alias(&s->mapped_ram, "onenand-mapped-ram",
                             &s->ram, 0x0200 << s->shift,
                             0xbe00 << s->shift);
    memory_region_add_subregion_overlap(&s->container,
                                        0x0200 << s->shift,
                                        &s->mapped_ram,
                                        1);
}
Esempio n. 26
0
static void portio_list_add_1(PortioList *piolist,
                              const MemoryRegionPortio *pio_init,
                              unsigned count, unsigned start,
                              unsigned off_low, unsigned off_high)
{
    MemoryRegionPortio *pio;
    MemoryRegionOps *ops;
    MemoryRegion *region, *alias;
    unsigned i;

    /* Copy the sub-list and null-terminate it.  */
    pio = g_new(MemoryRegionPortio, count + 1);
    memcpy(pio, pio_init, sizeof(MemoryRegionPortio) * count);
    memset(pio + count, 0, sizeof(MemoryRegionPortio));

    /* Adjust the offsets to all be zero-based for the region.  */
    for (i = 0; i < count; ++i) {
        pio[i].offset -= off_low;
    }

    ops = g_new0(MemoryRegionOps, 1);
    ops->old_portio = pio;

    region = g_new(MemoryRegion, 1);
    alias = g_new(MemoryRegion, 1);
    /*
     * Use an alias so that the callback is called with an absolute address,
     * rather than an offset relative to to start + off_low.
     */
    memory_region_init_io(region, ops, piolist->opaque, piolist->name,
                          INT64_MAX);
    memory_region_init_alias(alias, piolist->name,
                             region, start + off_low, off_high - off_low);
    memory_region_add_subregion(piolist->address_space,
                                start + off_low, alias);
    piolist->regions[piolist->nr] = region;
    piolist->aliases[piolist->nr] = alias;
    ++piolist->nr;
}
Esempio n. 27
0
/* DMA mapping */
static void ppc440_pcix_update_pim(PPC440PCIXState *s, int idx)
{
    MemoryRegion *mem = &s->pim[idx].mr;
    char *name;
    uint64_t size;

    /* Before we modify anything, unmap and destroy the region */
    ppc440_pcix_clear_region(&s->bm, mem);

    if (!(s->pim[idx].sa & 1)) {
        /* Not enabled, nothing to do */
        return;
    }

    name = g_strdup_printf("PCI Inbound Window %d", idx);
    size = ~(s->pim[idx].sa & ~7ULL) + 1;
    memory_region_init_alias(mem, OBJECT(s), name, get_system_memory(),
                             s->pim[idx].la, size);
    memory_region_add_subregion_overlap(&s->bm, 0, mem, -1);
    g_free(name);

    trace_ppc440_pcix_update_pim(idx, size, s->pim[idx].la);
}
static void labx_nios2_init(QEMUMachineInitArgs *args)
{
    MemoryRegion *address_space_mem = get_system_memory();

    int kernel_size;
    int fdt_size;
    void *fdt = get_device_tree(&fdt_size);
    hwaddr ddr_base = get_dram_base(fdt);
    MemoryRegion *phys_lmb_bram = g_new(MemoryRegion, 1);
    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
    MemoryRegion *phys_ram_alias = g_new(MemoryRegion, 1);

    /* Attach emulated BRAM through the LMB. LMB size is not specified
       in the device-tree but there must be one to hold the vector table. */
    memory_region_init_ram(phys_lmb_bram, "nios2.lmb_bram", LMB_BRAM_SIZE);
    vmstate_register_ram_global(phys_lmb_bram);
    memory_region_add_subregion(address_space_mem, 0x00000000, phys_lmb_bram);

    memory_region_init_ram(phys_ram, "nios2.ram", ram_size);
    vmstate_register_ram_global(phys_ram);
    memory_region_add_subregion(address_space_mem, ddr_base, phys_ram);
    memory_region_init_alias(phys_ram_alias, "nios2.ram.mirror",
                             phys_ram, 0, ram_size);
    memory_region_add_subregion(address_space_mem, ddr_base + 0xc0000000,
                                phys_ram_alias);

    /* Create cpus listed in the device-tree */
    add_to_force_table(cpus_probe, "cpu-probe", NULL);

    /* Create other devices listed in the device-tree */
    fdt_init_destroy_fdti(fdt_generic_create_machine(fdt, NULL));

    if (args->kernel_filename) {
        uint64_t entry = 0, low = 0, high = 0;
        uint32_t base32 = 0;

        /* Boots a kernel elf binary.  */
        kernel_size = load_elf(args->kernel_filename, NULL, NULL,
                               &entry, &low, &high,
                               0, ELF_MACHINE, 0);
        base32 = entry;
        if (base32 == 0xc0000000) {
            kernel_size = load_elf(args->kernel_filename, translate_kernel_address,
                                   NULL, &entry, NULL, NULL,
                                   0, ELF_MACHINE, 0);
        }
        /* Always boot into physical ram.  */
        boot_info.bootstrap_pc = ddr_base + 0xc0000000 + (entry & 0x07ffffff);

        /* If it wasn't an ELF image, try an u-boot image.  */
        if (kernel_size < 0) {
            hwaddr uentry, loadaddr;

            kernel_size = load_uimage(args->kernel_filename, &uentry, &loadaddr, 0);
            boot_info.bootstrap_pc = uentry;
            high = (loadaddr + kernel_size + 3) & ~3;
        }

        /* Not an ELF image nor an u-boot image, try a RAW image.  */
        if (kernel_size < 0) {
            kernel_size = load_image_targphys(args->kernel_filename, ddr_base,
                                              ram_size);
            boot_info.bootstrap_pc = ddr_base;
            high = (ddr_base + kernel_size + 3) & ~3;
        }

        if (args->initrd_filename) {
            uint32_t initrd_base = 0x88c00000;
            uint32_t initrd_size =
                load_image_targphys(args->initrd_filename, initrd_base,
                                    ram_size - initrd_base);
            if (initrd_size <= 0) {
                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
                        args->initrd_filename);
                exit(1);
            }

            boot_info.initrd = initrd_base;
        } else {
            boot_info.initrd = 0x00000000;
        }

        boot_info.cmdline = high + 4096;
        if (args->kernel_cmdline && strlen(args->kernel_cmdline)) {
            pstrcpy_targphys("cmdline", boot_info.cmdline, 256, args->kernel_cmdline);
        }
        /* Provide a device-tree.  */
        boot_info.fdt = boot_info.cmdline + 4096;
        labx_load_device_tree(boot_info.fdt, ram_size,
                              0, 0,
                              args->kernel_cmdline);
    }
}
Esempio n. 29
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]));
    }
}
Esempio n. 30
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);
}