Beispiel #1
0
static void microbit_init(MachineState *machine)
{
    MicrobitMachineState *s = MICROBIT_MACHINE(machine);
    MemoryRegion *system_memory = get_system_memory();
    MemoryRegion *mr;
    Object *soc = OBJECT(&s->nrf51);
    Object *i2c = OBJECT(&s->i2c);

    sysbus_init_child_obj(OBJECT(machine), "nrf51", soc, sizeof(s->nrf51),
                          TYPE_NRF51_SOC);
    qdev_prop_set_chr(DEVICE(&s->nrf51), "serial0", serial_hd(0));
    object_property_set_link(soc, OBJECT(system_memory), "memory",
                             &error_fatal);
    object_property_set_bool(soc, true, "realized", &error_fatal);

    /*
     * Overlap the TWI stub device into the SoC.  This is a microbit-specific
     * hack until we implement the nRF51 TWI controller properly and the
     * magnetometer/accelerometer devices.
     */
    sysbus_init_child_obj(OBJECT(machine), "microbit.twi", i2c,
                          sizeof(s->i2c), TYPE_MICROBIT_I2C);
    object_property_set_bool(i2c, true, "realized", &error_fatal);
    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(i2c), 0);
    memory_region_add_subregion_overlap(&s->nrf51.container, NRF51_TWI_BASE,
                                        mr, -1);

    armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
                       NRF51_SOC(soc)->flash_size);
}
Beispiel #2
0
static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
                              const char *name, hwaddr size)
{
    PL080State *dma = opaque;
    int i = dma - &mms->dma[0];
    SysBusDevice *s;
    char *mscname = g_strdup_printf("%s-msc", name);
    TZMSC *msc = &mms->msc[i];
    DeviceState *iotkitdev = DEVICE(&mms->iotkit);
    MemoryRegion *msc_upstream;
    MemoryRegion *msc_downstream;

    /*
     * Each DMA device is a PL081 whose transaction master interface
     * is guarded by a Master Security Controller. The downstream end of
     * the MSC connects to the IoTKit AHB Slave Expansion port, so the
     * DMA devices can see all devices and memory that the CPU does.
     */
    sysbus_init_child_obj(OBJECT(mms), mscname, msc, sizeof(*msc), TYPE_TZ_MSC);
    msc_downstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(&mms->iotkit), 0);
    object_property_set_link(OBJECT(msc), OBJECT(msc_downstream),
                             "downstream", &error_fatal);
    object_property_set_link(OBJECT(msc), OBJECT(mms),
                             "idau", &error_fatal);
    object_property_set_bool(OBJECT(msc), true, "realized", &error_fatal);

    qdev_connect_gpio_out_named(DEVICE(msc), "irq", 0,
                                qdev_get_gpio_in_named(iotkitdev,
                                                       "mscexp_status", i));
    qdev_connect_gpio_out_named(iotkitdev, "mscexp_clear", i,
                                qdev_get_gpio_in_named(DEVICE(msc),
                                                       "irq_clear", 0));
    qdev_connect_gpio_out_named(iotkitdev, "mscexp_ns", i,
                                qdev_get_gpio_in_named(DEVICE(msc),
                                                       "cfg_nonsec", 0));
    qdev_connect_gpio_out(DEVICE(&mms->sec_resp_splitter),
                          ARRAY_SIZE(mms->ppc) + i,
                          qdev_get_gpio_in_named(DEVICE(msc),
                                                 "cfg_sec_resp", 0));
    msc_upstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(msc), 0);

    sysbus_init_child_obj(OBJECT(mms), name, dma, sizeof(*dma), TYPE_PL081);
    object_property_set_link(OBJECT(dma), OBJECT(msc_upstream),
                             "downstream", &error_fatal);
    object_property_set_bool(OBJECT(dma), true, "realized", &error_fatal);

    s = SYS_BUS_DEVICE(dma);
    /* Wire up DMACINTR, DMACINTERR, DMACINTTC */
    sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 58 + i * 3));
    sysbus_connect_irq(s, 1, get_sse_irq_in(mms, 56 + i * 3));
    sysbus_connect_irq(s, 2, get_sse_irq_in(mms, 57 + i * 3));

    g_free(mscname);
    return sysbus_mmio_get_region(s, 0);
}
Beispiel #3
0
static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
                               const char *name, hwaddr size)
{
    CMSDKAPBUART *uart = opaque;
    int i = uart - &mms->uart[0];
    int rxirqno = i * 2;
    int txirqno = i * 2 + 1;
    int combirqno = i + 10;
    SysBusDevice *s;
    DeviceState *iotkitdev = DEVICE(&mms->iotkit);
    DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);

    sysbus_init_child_obj(OBJECT(mms), name, uart, sizeof(mms->uart[0]),
                          TYPE_CMSDK_APB_UART);
    qdev_prop_set_chr(DEVICE(uart), "chardev", serial_hd(i));
    qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", SYSCLK_FRQ);
    object_property_set_bool(OBJECT(uart), true, "realized", &error_fatal);
    s = SYS_BUS_DEVICE(uart);
    sysbus_connect_irq(s, 0, qdev_get_gpio_in_named(iotkitdev,
                                                    "EXP_IRQ", txirqno));
    sysbus_connect_irq(s, 1, qdev_get_gpio_in_named(iotkitdev,
                                                    "EXP_IRQ", rxirqno));
    sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
    sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
    sysbus_connect_irq(s, 4, qdev_get_gpio_in_named(iotkitdev,
                                                    "EXP_IRQ", combirqno));
    return sysbus_mmio_get_region(SYS_BUS_DEVICE(uart), 0);
}
Beispiel #4
0
static void fsl_imx31_init(Object *obj)
{
    FslIMX31State *s = FSL_IMX31(obj);
    int i;

    object_initialize(&s->cpu, sizeof(s->cpu), "arm1136-" TYPE_ARM_CPU);

    sysbus_init_child_obj(obj, "avic", &s->avic, sizeof(s->avic),
                          TYPE_IMX_AVIC);

    sysbus_init_child_obj(obj, "ccm", &s->ccm, sizeof(s->ccm), TYPE_IMX31_CCM);

    for (i = 0; i < FSL_IMX31_NUM_UARTS; i++) {
        sysbus_init_child_obj(obj, "uart[*]", &s->uart[i], sizeof(s->uart[i]),
                              TYPE_IMX_SERIAL);
    }

    sysbus_init_child_obj(obj, "gpt", &s->gpt, sizeof(s->gpt), TYPE_IMX31_GPT);

    for (i = 0; i < FSL_IMX31_NUM_EPITS; i++) {
        sysbus_init_child_obj(obj, "epit[*]", &s->epit[i], sizeof(s->epit[i]),
                              TYPE_IMX_EPIT);
    }

    for (i = 0; i < FSL_IMX31_NUM_I2CS; i++) {
        sysbus_init_child_obj(obj, "i2c[*]", &s->i2c[i], sizeof(s->i2c[i]),
                              TYPE_IMX_I2C);
    }

    for (i = 0; i < FSL_IMX31_NUM_GPIOS; i++) {
        sysbus_init_child_obj(obj, "gpio[*]", &s->gpio[i], sizeof(s->gpio[i]),
                              TYPE_IMX_GPIO);
    }
}
Beispiel #5
0
static void aw_a10_init(Object *obj)
{
    AwA10State *s = AW_A10(obj);

    object_initialize_child(obj, "cpu", &s->cpu, sizeof(s->cpu),
                            "cortex-a8-" TYPE_ARM_CPU, &error_abort, NULL);

    sysbus_init_child_obj(obj, "intc", &s->intc, sizeof(s->intc),
                          TYPE_AW_A10_PIC);

    sysbus_init_child_obj(obj, "timer", &s->timer, sizeof(s->timer),
                          TYPE_AW_A10_PIT);

    sysbus_init_child_obj(obj, "emac", &s->emac, sizeof(s->emac), TYPE_AW_EMAC);

    sysbus_init_child_obj(obj, "sata", &s->sata, sizeof(s->sata),
                          TYPE_ALLWINNER_AHCI);
}
Beispiel #6
0
static void xlnx_zynqmp_pmu_soc_init(Object *obj)
{
    XlnxZynqMPPMUSoCState *s = XLNX_ZYNQMP_PMU_SOC(obj);

    object_initialize_child(obj, "pmu-cpu", &s->cpu, sizeof(s->cpu),
                            TYPE_MICROBLAZE_CPU, &error_abort, NULL);

    sysbus_init_child_obj(obj, "intc", &s->intc, sizeof(s->intc),
                          TYPE_XLNX_PMU_IO_INTC);
}
Beispiel #7
0
static void m2sxxx_soc_initfn(Object *obj)
{
    MSF2State *s = MSF2_SOC(obj);
    int i;

    sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m),
                          TYPE_ARMV7M);

    sysbus_init_child_obj(obj, "sysreg", &s->sysreg, sizeof(s->sysreg),
                          TYPE_MSF2_SYSREG);

    sysbus_init_child_obj(obj, "timer", &s->timer, sizeof(s->timer),
                          TYPE_MSS_TIMER);

    for (i = 0; i < MSF2_NUM_SPIS; i++) {
        sysbus_init_child_obj(obj, "spi[*]", &s->spi[i], sizeof(s->spi[i]),
                          TYPE_MSS_SPI);
    }
}
Beispiel #8
0
static void digic_init(Object *obj)
{
    DigicState *s = DIGIC(obj);
    int i;

    object_initialize_child(obj, "cpu", &s->cpu, sizeof(s->cpu),
                            "arm946-" TYPE_ARM_CPU, &error_abort, NULL);

    for (i = 0; i < DIGIC4_NB_TIMERS; i++) {
#define DIGIC_TIMER_NAME_MLEN    11
        char name[DIGIC_TIMER_NAME_MLEN];

        snprintf(name, DIGIC_TIMER_NAME_MLEN, "timer[%d]", i);
        sysbus_init_child_obj(obj, name, &s->timer[i], sizeof(s->timer[i]),
                              TYPE_DIGIC_TIMER);
    }

    sysbus_init_child_obj(obj, "uart", &s->uart, sizeof(s->uart),
                          TYPE_DIGIC_UART);
}
Beispiel #9
0
static void a15mp_priv_initfn(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    A15MPPrivState *s = A15MPCORE_PRIV(obj);

    memory_region_init(&s->container, obj, "a15mp-priv-container", 0x8000);
    sysbus_init_mmio(sbd, &s->container);

    sysbus_init_child_obj(obj, "gic", &s->gic, sizeof(s->gic),
                          gic_class_name());
    qdev_prop_set_uint32(DEVICE(&s->gic), "revision", 2);
}
Beispiel #10
0
static void nrf51_soc_init(Object *obj)
{
    NRF51State *s = NRF51_SOC(obj);

    memory_region_init(&s->container, obj, "nrf51-container", UINT64_MAX);

    sysbus_init_child_obj(OBJECT(s), "armv6m", OBJECT(&s->cpu), sizeof(s->cpu),
                          TYPE_ARMV7M);
    qdev_prop_set_string(DEVICE(&s->cpu), "cpu-type",
                         ARM_CPU_TYPE_NAME("cortex-m0"));
    qdev_prop_set_uint32(DEVICE(&s->cpu), "num-irq", 32);
}
Beispiel #11
0
static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
                                       void *opaque,
                                       const char *name, hwaddr size)
{
    /* Initialize, configure and realize a TYPE_UNIMPLEMENTED_DEVICE,
     * and return a pointer to its MemoryRegion.
     */
    UnimplementedDeviceState *uds = opaque;

    sysbus_init_child_obj(OBJECT(mms), name, uds,
                          sizeof(UnimplementedDeviceState),
                          TYPE_UNIMPLEMENTED_DEVICE);
    qdev_prop_set_string(DEVICE(uds), "name", name);
    qdev_prop_set_uint64(DEVICE(uds), "size", size);
    object_property_set_bool(OBJECT(uds), true, "realized", &error_fatal);
    return sysbus_mmio_get_region(SYS_BUS_DEVICE(uds), 0);
}
Beispiel #12
0
static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
                              const char *name, hwaddr size)
{
    /*
     * The AN505 has five PL022 SPI controllers.
     * One of these should have the LCD controller behind it; the others
     * are connected only to the FPGA's "general purpose SPI connector"
     * or "shield" expansion connectors.
     * Note that if we do implement devices behind SPI, the chip select
     * lines are set via the "MISC" register in the MPS2 FPGAIO device.
     */
    PL022State *spi = opaque;
    int i = spi - &mms->spi[0];
    SysBusDevice *s;

    sysbus_init_child_obj(OBJECT(mms), name, spi, sizeof(mms->spi[0]),
                          TYPE_PL022);
    object_property_set_bool(OBJECT(spi), true, "realized", &error_fatal);
    s = SYS_BUS_DEVICE(spi);
    sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 51 + i));
    return sysbus_mmio_get_region(s, 0);
}
Beispiel #13
0
static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
                              const char *name, hwaddr size)
{
    TZMPC *mpc = opaque;
    int i = mpc - &mms->ssram_mpc[0];
    MemoryRegion *ssram = &mms->ssram[i];
    MemoryRegion *upstream;
    char *mpcname = g_strdup_printf("%s-mpc", name);
    static uint32_t ramsize[] = { 0x00400000, 0x00200000, 0x00200000 };
    static uint32_t rambase[] = { 0x00000000, 0x28000000, 0x28200000 };

    memory_region_init_ram(ssram, NULL, name, ramsize[i], &error_fatal);

    sysbus_init_child_obj(OBJECT(mms), mpcname, mpc, sizeof(mms->ssram_mpc[0]),
                          TYPE_TZ_MPC);
    object_property_set_link(OBJECT(mpc), OBJECT(ssram),
                             "downstream", &error_fatal);
    object_property_set_bool(OBJECT(mpc), true, "realized", &error_fatal);
    /* Map the upstream end of the MPC into system memory */
    upstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 1);
    memory_region_add_subregion(get_system_memory(), rambase[i], upstream);
    /* and connect its interrupt to the IoTKit */
    qdev_connect_gpio_out_named(DEVICE(mpc), "irq", 0,
                                qdev_get_gpio_in_named(DEVICE(&mms->iotkit),
                                                       "mpcexp_status", i));

    /* The first SSRAM is a special case as it has an alias; accesses to
     * the alias region at 0x00400000 must also go to the MPC upstream.
     */
    if (i == 0) {
        make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", upstream, 0x00400000);
    }

    g_free(mpcname);
    /* Return the register interface MR for our caller to map behind the PPC */
    return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0);
}
Beispiel #14
0
static void fsl_imx6ul_init(Object *obj)
{
    FslIMX6ULState *s = FSL_IMX6UL(obj);
    char name[NAME_SIZE];
    int i;

    for (i = 0; i < MIN(smp_cpus, FSL_IMX6UL_NUM_CPUS); i++) {
        snprintf(name, NAME_SIZE, "cpu%d", i);
        object_initialize_child(obj, name, &s->cpu[i], sizeof(s->cpu[i]),
                                "cortex-a7-" TYPE_ARM_CPU, &error_abort, NULL);
    }

    /*
     * A7MPCORE
     */
    sysbus_init_child_obj(obj, "a7mpcore", &s->a7mpcore, sizeof(s->a7mpcore),
                          TYPE_A15MPCORE_PRIV);

    /*
     * CCM
     */
    sysbus_init_child_obj(obj, "ccm", &s->ccm, sizeof(s->ccm), TYPE_IMX6UL_CCM);

    /*
     * SRC
     */
    sysbus_init_child_obj(obj, "src", &s->src, sizeof(s->src), TYPE_IMX6_SRC);

    /*
     * GPCv2
     */
    sysbus_init_child_obj(obj, "gpcv2", &s->gpcv2, sizeof(s->gpcv2),
                          TYPE_IMX_GPCV2);

    /*
     * SNVS
     */
    sysbus_init_child_obj(obj, "snvs", &s->snvs, sizeof(s->snvs),
                          TYPE_IMX7_SNVS);

    /*
     * GPR
     */
    sysbus_init_child_obj(obj, "gpr", &s->gpr, sizeof(s->gpr),
                          TYPE_IMX7_GPR);

    /*
     * GPIOs 1 to 5
     */
    for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
        snprintf(name, NAME_SIZE, "gpio%d", i);
        sysbus_init_child_obj(obj, name, &s->gpio[i], sizeof(s->gpio[i]),
                              TYPE_IMX_GPIO);
    }

    /*
     * GPT 1, 2
     */
    for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
        snprintf(name, NAME_SIZE, "gpt%d", i);
        sysbus_init_child_obj(obj, name, &s->gpt[i], sizeof(s->gpt[i]),
                              TYPE_IMX7_GPT);
    }

    /*
     * EPIT 1, 2
     */
    for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
        snprintf(name, NAME_SIZE, "epit%d", i + 1);
        sysbus_init_child_obj(obj, name, &s->epit[i], sizeof(s->epit[i]),
                              TYPE_IMX_EPIT);
    }

    /*
     * eCSPI
     */
    for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
        snprintf(name, NAME_SIZE, "spi%d", i + 1);
        sysbus_init_child_obj(obj, name, &s->spi[i], sizeof(s->spi[i]),
                              TYPE_IMX_SPI);
    }

    /*
     * I2C
     */
    for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
        snprintf(name, NAME_SIZE, "i2c%d", i + 1);
        sysbus_init_child_obj(obj, name, &s->i2c[i], sizeof(s->i2c[i]),
                              TYPE_IMX_I2C);
    }

    /*
     * UART
     */
    for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
        snprintf(name, NAME_SIZE, "uart%d", i);
        sysbus_init_child_obj(obj, name, &s->uart[i], sizeof(s->uart[i]),
                              TYPE_IMX_SERIAL);
    }

    /*
     * Ethernet
     */
    for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
        snprintf(name, NAME_SIZE, "eth%d", i);
        sysbus_init_child_obj(obj, name, &s->eth[i], sizeof(s->eth[i]),
                              TYPE_IMX_ENET);
    }

    /*
     * SDHCI
     */
    for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
        snprintf(name, NAME_SIZE, "usdhc%d", i);
        sysbus_init_child_obj(obj, name, &s->usdhc[i], sizeof(s->usdhc[i]),
                              TYPE_IMX_USDHC);
    }

    /*
     * Watchdog
     */
    for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
        snprintf(name, NAME_SIZE, "wdt%d", i);
        sysbus_init_child_obj(obj, name, &s->wdt[i], sizeof(s->wdt[i]),
                              TYPE_IMX2_WDT);
    }
}
Beispiel #15
0
static void mps2tz_common_init(MachineState *machine)
{
    MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
    MachineClass *mc = MACHINE_GET_CLASS(machine);
    MemoryRegion *system_memory = get_system_memory();
    DeviceState *iotkitdev;
    DeviceState *dev_splitter;
    int i;

    if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
        error_report("This board can only be used with CPU %s",
                     mc->default_cpu_type);
        exit(1);
    }

    sysbus_init_child_obj(OBJECT(machine), "iotkit", &mms->iotkit,
                          sizeof(mms->iotkit), TYPE_IOTKIT);
    iotkitdev = DEVICE(&mms->iotkit);
    object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
                             "memory", &error_abort);
    qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", 92);
    qdev_prop_set_uint32(iotkitdev, "MAINCLK", SYSCLK_FRQ);
    object_property_set_bool(OBJECT(&mms->iotkit), true, "realized",
                             &error_fatal);

    /* The sec_resp_cfg output from the IoTKit must be split into multiple
     * lines, one for each of the PPCs we create here.
     */
    object_initialize(&mms->sec_resp_splitter, sizeof(mms->sec_resp_splitter),
                      TYPE_SPLIT_IRQ);
    object_property_add_child(OBJECT(machine), "sec-resp-splitter",
                              OBJECT(&mms->sec_resp_splitter), &error_abort);
    object_property_set_int(OBJECT(&mms->sec_resp_splitter), 5,
                            "num-lines", &error_fatal);
    object_property_set_bool(OBJECT(&mms->sec_resp_splitter), true,
                             "realized", &error_fatal);
    dev_splitter = DEVICE(&mms->sec_resp_splitter);
    qdev_connect_gpio_out_named(iotkitdev, "sec_resp_cfg", 0,
                                qdev_get_gpio_in(dev_splitter, 0));

    /* The IoTKit sets up much of the memory layout, including
     * the aliases between secure and non-secure regions in the
     * address space. The FPGA itself contains:
     *
     * 0x00000000..0x003fffff  SSRAM1
     * 0x00400000..0x007fffff  alias of SSRAM1
     * 0x28000000..0x283fffff  4MB SSRAM2 + SSRAM3
     * 0x40100000..0x4fffffff  AHB Master Expansion 1 interface devices
     * 0x80000000..0x80ffffff  16MB PSRAM
     */

    /* The FPGA images have an odd combination of different RAMs,
     * because in hardware they are different implementations and
     * connected to different buses, giving varying performance/size
     * tradeoffs. For QEMU they're all just RAM, though. We arbitrarily
     * call the 16MB our "system memory", as it's the largest lump.
     */
    memory_region_allocate_system_memory(&mms->psram,
                                         NULL, "mps.ram", 0x01000000);
    memory_region_add_subregion(system_memory, 0x80000000, &mms->psram);

    /* The overflow IRQs for all UARTs are ORed together.
     * Tx, Rx and "combined" IRQs are sent to the NVIC separately.
     * Create the OR gate for this.
     */
    object_initialize(&mms->uart_irq_orgate, sizeof(mms->uart_irq_orgate),
                      TYPE_OR_IRQ);
    object_property_add_child(OBJECT(mms), "uart-irq-orgate",
                              OBJECT(&mms->uart_irq_orgate), &error_abort);
    object_property_set_int(OBJECT(&mms->uart_irq_orgate), 10, "num-lines",
                            &error_fatal);
    object_property_set_bool(OBJECT(&mms->uart_irq_orgate), true,
                             "realized", &error_fatal);
    qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
                          qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 15));

    /* Most of the devices in the FPGA are behind Peripheral Protection
     * Controllers. The required order for initializing things is:
     *  + initialize the PPC
     *  + initialize, configure and realize downstream devices
     *  + connect downstream device MemoryRegions to the PPC
     *  + realize the PPC
     *  + map the PPC's MemoryRegions to the places in the address map
     *    where the downstream devices should appear
     *  + wire up the PPC's control lines to the IoTKit object
     */

    const PPCInfo ppcs[] = { {
            .name = "apb_ppcexp0",
            .ports = {
                { "ssram-0", make_mpc, &mms->ssram_mpc[0], 0x58007000, 0x1000 },
                { "ssram-1", make_mpc, &mms->ssram_mpc[1], 0x58008000, 0x1000 },
                { "ssram-2", make_mpc, &mms->ssram_mpc[2], 0x58009000, 0x1000 },
            },
        }, {
            .name = "apb_ppcexp1",
Beispiel #16
0
static void fsl_imx7_init(Object *obj)
{
    FslIMX7State *s = FSL_IMX7(obj);
    char name[NAME_SIZE];
    int i;


    for (i = 0; i < MIN(smp_cpus, FSL_IMX7_NUM_CPUS); i++) {
        snprintf(name, NAME_SIZE, "cpu%d", i);
        object_initialize_child(obj, name, &s->cpu[i], sizeof(s->cpu[i]),
                                ARM_CPU_TYPE_NAME("cortex-a7"), &error_abort,
                                NULL);
    }

    /*
     * A7MPCORE
     */
    sysbus_init_child_obj(obj, "a7mpcore", &s->a7mpcore, sizeof(s->a7mpcore),
                          TYPE_A15MPCORE_PRIV);

    /*
     * GPIOs 1 to 7
     */
    for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
        snprintf(name, NAME_SIZE, "gpio%d", i);
        sysbus_init_child_obj(obj, name, &s->gpio[i], sizeof(s->gpio[i]),
                          TYPE_IMX_GPIO);
    }

    /*
     * GPT1, 2, 3, 4
     */
    for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
        snprintf(name, NAME_SIZE, "gpt%d", i);
        sysbus_init_child_obj(obj, name, &s->gpt[i], sizeof(s->gpt[i]),
                              TYPE_IMX7_GPT);
    }

    /*
     * CCM
     */
    sysbus_init_child_obj(obj, "ccm", &s->ccm, sizeof(s->ccm), TYPE_IMX7_CCM);

    /*
     * Analog
     */
    sysbus_init_child_obj(obj, "analog", &s->analog, sizeof(s->analog),
                          TYPE_IMX7_ANALOG);

    /*
     * GPCv2
     */
    sysbus_init_child_obj(obj, "gpcv2", &s->gpcv2, sizeof(s->gpcv2),
                          TYPE_IMX_GPCV2);

    for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
        snprintf(name, NAME_SIZE, "spi%d", i + 1);
        sysbus_init_child_obj(obj, name, &s->spi[i], sizeof(s->spi[i]),
                              TYPE_IMX_SPI);
    }


    for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
        snprintf(name, NAME_SIZE, "i2c%d", i + 1);
        sysbus_init_child_obj(obj, name, &s->i2c[i], sizeof(s->i2c[i]),
                              TYPE_IMX_I2C);
    }

    /*
     * UART
     */
    for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
            snprintf(name, NAME_SIZE, "uart%d", i);
            sysbus_init_child_obj(obj, name, &s->uart[i], sizeof(s->uart[i]),
                                  TYPE_IMX_SERIAL);
    }

    /*
     * Ethernet
     */
    for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
            snprintf(name, NAME_SIZE, "eth%d", i);
            sysbus_init_child_obj(obj, name, &s->eth[i], sizeof(s->eth[i]),
                                  TYPE_IMX_ENET);
    }

    /*
     * SDHCI
     */
    for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
            snprintf(name, NAME_SIZE, "usdhc%d", i);
            sysbus_init_child_obj(obj, name, &s->usdhc[i], sizeof(s->usdhc[i]),
                              TYPE_IMX_USDHC);
    }

    /*
     * SNVS
     */
    sysbus_init_child_obj(obj, "snvs", &s->snvs, sizeof(s->snvs),
                          TYPE_IMX7_SNVS);

    /*
     * Watchdog
     */
    for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
            snprintf(name, NAME_SIZE, "wdt%d", i);
            sysbus_init_child_obj(obj, name, &s->wdt[i], sizeof(s->wdt[i]),
                                  TYPE_IMX2_WDT);
    }

    /*
     * GPR
     */
    sysbus_init_child_obj(obj, "gpr", &s->gpr, sizeof(s->gpr), TYPE_IMX7_GPR);

    sysbus_init_child_obj(obj, "pcie", &s->pcie, sizeof(s->pcie),
                          TYPE_DESIGNWARE_PCIE_HOST);

    for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
        snprintf(name, NAME_SIZE, "usb%d", i);
        sysbus_init_child_obj(obj, name, &s->usb[i], sizeof(s->usb[i]),
                              TYPE_CHIPIDEA);
    }
}
Beispiel #17
0
static void mps2_common_init(MachineState *machine)
{
    MPS2MachineState *mms = MPS2_MACHINE(machine);
    MPS2MachineClass *mmc = MPS2_MACHINE_GET_CLASS(machine);
    MemoryRegion *system_memory = get_system_memory();
    MachineClass *mc = MACHINE_GET_CLASS(machine);
    DeviceState *armv7m, *sccdev;

    if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
        error_report("This board can only be used with CPU %s",
                     mc->default_cpu_type);
        exit(1);
    }

    /* The FPGA images have an odd combination of different RAMs,
     * because in hardware they are different implementations and
     * connected to different buses, giving varying performance/size
     * tradeoffs. For QEMU they're all just RAM, though. We arbitrarily
     * call the 16MB our "system memory", as it's the largest lump.
     *
     * Common to both boards:
     *  0x21000000..0x21ffffff : PSRAM (16MB)
     * AN385 only:
     *  0x00000000 .. 0x003fffff : ZBT SSRAM1
     *  0x00400000 .. 0x007fffff : mirror of ZBT SSRAM1
     *  0x20000000 .. 0x203fffff : ZBT SSRAM 2&3
     *  0x20400000 .. 0x207fffff : mirror of ZBT SSRAM 2&3
     *  0x01000000 .. 0x01003fff : block RAM (16K)
     *  0x01004000 .. 0x01007fff : mirror of above
     *  0x01008000 .. 0x0100bfff : mirror of above
     *  0x0100c000 .. 0x0100ffff : mirror of above
     * AN511 only:
     *  0x00000000 .. 0x0003ffff : FPGA block RAM
     *  0x00400000 .. 0x007fffff : ZBT SSRAM1
     *  0x20000000 .. 0x2001ffff : SRAM
     *  0x20400000 .. 0x207fffff : ZBT SSRAM 2&3
     *
     * The AN385 has a feature where the lowest 16K can be mapped
     * either to the bottom of the ZBT SSRAM1 or to the block RAM.
     * This is of no use for QEMU so we don't implement it (as if
     * zbt_boot_ctrl is always zero).
     */
    memory_region_allocate_system_memory(&mms->psram,
                                         NULL, "mps.ram", 0x1000000);
    memory_region_add_subregion(system_memory, 0x21000000, &mms->psram);

    switch (mmc->fpga_type) {
    case FPGA_AN385:
        make_ram(&mms->ssram1, "mps.ssram1", 0x0, 0x400000);
        make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", &mms->ssram1, 0x400000);
        make_ram(&mms->ssram23, "mps.ssram23", 0x20000000, 0x400000);
        make_ram_alias(&mms->ssram23_m, "mps.ssram23_m",
                       &mms->ssram23, 0x20400000);
        make_ram(&mms->blockram, "mps.blockram", 0x01000000, 0x4000);
        make_ram_alias(&mms->blockram_m1, "mps.blockram_m1",
                       &mms->blockram, 0x01004000);
        make_ram_alias(&mms->blockram_m2, "mps.blockram_m2",
                       &mms->blockram, 0x01008000);
        make_ram_alias(&mms->blockram_m3, "mps.blockram_m3",
                       &mms->blockram, 0x0100c000);
        break;
    case FPGA_AN511:
        make_ram(&mms->blockram, "mps.blockram", 0x0, 0x40000);
        make_ram(&mms->ssram1, "mps.ssram1", 0x00400000, 0x00800000);
        make_ram(&mms->sram, "mps.sram", 0x20000000, 0x20000);
        make_ram(&mms->ssram23, "mps.ssram23", 0x20400000, 0x400000);
        break;
    default:
        g_assert_not_reached();
    }

    sysbus_init_child_obj(OBJECT(mms), "armv7m", &mms->armv7m,
                          sizeof(mms->armv7m), TYPE_ARMV7M);
    armv7m = DEVICE(&mms->armv7m);
    switch (mmc->fpga_type) {
    case FPGA_AN385:
        qdev_prop_set_uint32(armv7m, "num-irq", 32);
        break;
    case FPGA_AN511:
        qdev_prop_set_uint32(armv7m, "num-irq", 64);
        break;
    default:
        g_assert_not_reached();
    }
    qdev_prop_set_string(armv7m, "cpu-type", machine->cpu_type);
    qdev_prop_set_bit(armv7m, "enable-bitband", true);
    object_property_set_link(OBJECT(&mms->armv7m), OBJECT(system_memory),
                             "memory", &error_abort);
    object_property_set_bool(OBJECT(&mms->armv7m), true, "realized",
                             &error_fatal);

    create_unimplemented_device("zbtsmram mirror", 0x00400000, 0x00400000);
    create_unimplemented_device("RESERVED 1", 0x00800000, 0x00800000);
    create_unimplemented_device("Block RAM", 0x01000000, 0x00010000);
    create_unimplemented_device("RESERVED 2", 0x01010000, 0x1EFF0000);
    create_unimplemented_device("RESERVED 3", 0x20800000, 0x00800000);
    create_unimplemented_device("PSRAM", 0x21000000, 0x01000000);
    /* These three ranges all cover multiple devices; we may implement
     * some of them below (in which case the real device takes precedence
     * over the unimplemented-region mapping).
     */
    create_unimplemented_device("CMSDK APB peripheral region @0x40000000",
                                0x40000000, 0x00010000);
    create_unimplemented_device("CMSDK peripheral region @0x40010000",
                                0x40010000, 0x00010000);
    create_unimplemented_device("Extra peripheral region @0x40020000",
                                0x40020000, 0x00010000);
    create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
    create_unimplemented_device("VGA", 0x41000000, 0x0200000);

    switch (mmc->fpga_type) {
    case FPGA_AN385:
    {
        /* The overflow IRQs for UARTs 0, 1 and 2 are ORed together.
         * Overflow for UARTs 4 and 5 doesn't trigger any interrupt.
         */
        Object *orgate;
        DeviceState *orgate_dev;
        int i;

        orgate = object_new(TYPE_OR_IRQ);
        object_property_set_int(orgate, 6, "num-lines", &error_fatal);
        object_property_set_bool(orgate, true, "realized", &error_fatal);
        orgate_dev = DEVICE(orgate);
        qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));

        for (i = 0; i < 5; i++) {
            static const hwaddr uartbase[] = {0x40004000, 0x40005000,
                                              0x40006000, 0x40007000,
                                              0x40009000};
            /* RX irq number; TX irq is always one greater */
            static const int uartirq[] = {0, 2, 4, 18, 20};
            qemu_irq txovrint = NULL, rxovrint = NULL;

            if (i < 3) {
                txovrint = qdev_get_gpio_in(orgate_dev, i * 2);
                rxovrint = qdev_get_gpio_in(orgate_dev, i * 2 + 1);
            }

            cmsdk_apb_uart_create(uartbase[i],
                                  qdev_get_gpio_in(armv7m, uartirq[i] + 1),
                                  qdev_get_gpio_in(armv7m, uartirq[i]),
                                  txovrint, rxovrint,
                                  NULL,
                                  serial_hd(i), SYSCLK_FRQ);
        }
        break;
    }
    case FPGA_AN511:
    {
        /* The overflow IRQs for all UARTs are ORed together.
         * Tx and Rx IRQs for each UART are ORed together.
         */
        Object *orgate;
        DeviceState *orgate_dev;
        int i;

        orgate = object_new(TYPE_OR_IRQ);
        object_property_set_int(orgate, 10, "num-lines", &error_fatal);
        object_property_set_bool(orgate, true, "realized", &error_fatal);
        orgate_dev = DEVICE(orgate);
        qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));

        for (i = 0; i < 5; i++) {
            /* system irq numbers for the combined tx/rx for each UART */
            static const int uart_txrx_irqno[] = {0, 2, 45, 46, 56};
            static const hwaddr uartbase[] = {0x40004000, 0x40005000,
                                              0x4002c000, 0x4002d000,
                                              0x4002e000};
            Object *txrx_orgate;
            DeviceState *txrx_orgate_dev;

            txrx_orgate = object_new(TYPE_OR_IRQ);
            object_property_set_int(txrx_orgate, 2, "num-lines", &error_fatal);
            object_property_set_bool(txrx_orgate, true, "realized",
                                     &error_fatal);
            txrx_orgate_dev = DEVICE(txrx_orgate);
            qdev_connect_gpio_out(txrx_orgate_dev, 0,
                                  qdev_get_gpio_in(armv7m, uart_txrx_irqno[i]));
            cmsdk_apb_uart_create(uartbase[i],
                                  qdev_get_gpio_in(txrx_orgate_dev, 0),
                                  qdev_get_gpio_in(txrx_orgate_dev, 1),
                                  qdev_get_gpio_in(orgate_dev, i * 2),
                                  qdev_get_gpio_in(orgate_dev, i * 2 + 1),
                                  NULL,
                                  serial_hd(i), SYSCLK_FRQ);
        }
        break;
    }
    default:
        g_assert_not_reached();
    }

    cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
    cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);

    sysbus_init_child_obj(OBJECT(mms), "dualtimer", &mms->dualtimer,
                          sizeof(mms->dualtimer), TYPE_CMSDK_APB_DUALTIMER);
    qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
    object_property_set_bool(OBJECT(&mms->dualtimer), true, "realized",
                             &error_fatal);
    sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
                       qdev_get_gpio_in(armv7m, 10));
    sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);

    sysbus_init_child_obj(OBJECT(mms), "scc", &mms->scc,
                          sizeof(mms->scc), TYPE_MPS2_SCC);
    sccdev = DEVICE(&mms->scc);
    qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
    qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
    qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
    object_property_set_bool(OBJECT(&mms->scc), true, "realized",
                             &error_fatal);
    sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);

    /* In hardware this is a LAN9220; the LAN9118 is software compatible
     * except that it doesn't support the checksum-offload feature.
     */
    lan9118_init(&nd_table[0], 0x40200000,
                 qdev_get_gpio_in(armv7m,
                                  mmc->fpga_type == FPGA_AN385 ? 13 : 47));

    system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;

    armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
                       0x400000);
}
Beispiel #18
0
static void versal_virt_init(MachineState *machine)
{
    VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
    int psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;

    /*
     * If the user provides an Operating System to be loaded, we expect them
     * to use the -kernel command line option.
     *
     * Users can load firmware or boot-loaders with the -device loader options.
     *
     * When loading an OS, we generate a dtb and let arm_load_kernel() select
     * where it gets loaded. This dtb will be passed to the kernel in x0.
     *
     * If there's no -kernel option, we generate a DTB and place it at 0x1000
     * for the bootloaders or firmware to pick up.
     *
     * If users want to provide their own DTB, they can use the -dtb option.
     * These dtb's will have their memory nodes modified to match QEMU's
     * selected ram_size option before they get passed to the kernel or fw.
     *
     * When loading an OS, we turn on QEMU's PSCI implementation with SMC
     * as the PSCI conduit. When there's no -kernel, we assume the user
     * provides EL3 firmware to handle PSCI.
     */
    if (machine->kernel_filename) {
        psci_conduit = QEMU_PSCI_CONDUIT_SMC;
    }

    memory_region_allocate_system_memory(&s->mr_ddr, NULL, "ddr",
                                         machine->ram_size);

    sysbus_init_child_obj(OBJECT(machine), "xlnx-ve", &s->soc,
                          sizeof(s->soc), TYPE_XLNX_VERSAL);
    object_property_set_link(OBJECT(&s->soc), OBJECT(&s->mr_ddr),
                             "ddr", &error_abort);
    object_property_set_int(OBJECT(&s->soc), psci_conduit,
                            "psci-conduit", &error_abort);
    object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal);

    fdt_create(s);
    create_virtio_regions(s);
    fdt_add_gem_nodes(s);
    fdt_add_uart_nodes(s);
    fdt_add_gic_nodes(s);
    fdt_add_timer_nodes(s);
    fdt_add_cpu_nodes(s, psci_conduit);
    fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
    fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);

    /* Make the APU cpu address space visible to virtio and other
     * modules unaware of muliple address-spaces.  */
    memory_region_add_subregion_overlap(get_system_memory(),
                                        0, &s->soc.fpd.apu.mr, 0);

    s->binfo.ram_size = machine->ram_size;
    s->binfo.kernel_filename = machine->kernel_filename;
    s->binfo.kernel_cmdline = machine->kernel_cmdline;
    s->binfo.initrd_filename = machine->initrd_filename;
    s->binfo.loader_start = 0x0;
    s->binfo.get_dtb = versal_virt_get_dtb;
    s->binfo.modify_dtb = versal_virt_modify_dtb;
    if (machine->kernel_filename) {
        arm_load_kernel(s->soc.fpd.apu.cpu[0], &s->binfo);
    } else {
        AddressSpace *as = arm_boot_address_space(s->soc.fpd.apu.cpu[0],
                                                  &s->binfo);
        /* Some boot-loaders (e.g u-boot) don't like blobs at address 0 (NULL).
         * Offset things by 4K.  */
        s->binfo.loader_start = 0x1000;
        s->binfo.dtb_limit = 0x1000000;
        if (arm_load_dtb(s->binfo.loader_start,
                         &s->binfo, s->binfo.dtb_limit, as) < 0) {
            exit(EXIT_FAILURE);
        }
    }
}
Beispiel #19
0
Datei: cps.c Projekt: jnsnow/qemu
static void mips_cps_realize(DeviceState *dev, Error **errp)
{
    MIPSCPSState *s = MIPS_CPS(dev);
    CPUMIPSState *env;
    MIPSCPU *cpu;
    int i;
    Error *err = NULL;
    target_ulong gcr_base;
    bool itu_present = false;
    bool saar_present = false;

    for (i = 0; i < s->num_vp; i++) {
        cpu = MIPS_CPU(cpu_create(s->cpu_type));

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

        env = &cpu->env;
        if (cpu_mips_itu_supported(env)) {
            itu_present = true;
            /* Attach ITC Tag to the VP */
            env->itc_tag = mips_itu_get_tag_region(&s->itu);
            env->itu = &s->itu;
        }
        qemu_register_reset(main_cpu_reset, cpu);
    }

    cpu = MIPS_CPU(first_cpu);
    env = &cpu->env;
    saar_present = (bool)env->saarp;

    /* Inter-Thread Communication Unit */
    if (itu_present) {
        sysbus_init_child_obj(OBJECT(dev), "itu", &s->itu, sizeof(s->itu),
                              TYPE_MIPS_ITU);
        object_property_set_int(OBJECT(&s->itu), 16, "num-fifo", &err);
        object_property_set_int(OBJECT(&s->itu), 16, "num-semaphores", &err);
        object_property_set_bool(OBJECT(&s->itu), saar_present, "saar-present",
                                 &err);
        if (saar_present) {
            qdev_prop_set_ptr(DEVICE(&s->itu), "saar", (void *)&env->CP0_SAAR);
        }
        object_property_set_bool(OBJECT(&s->itu), true, "realized", &err);
        if (err != NULL) {
            error_propagate(errp, err);
            return;
        }

        memory_region_add_subregion(&s->container, 0,
                           sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->itu), 0));
    }

    /* Cluster Power Controller */
    sysbus_init_child_obj(OBJECT(dev), "cpc", &s->cpc, sizeof(s->cpc),
                          TYPE_MIPS_CPC);
    object_property_set_int(OBJECT(&s->cpc), s->num_vp, "num-vp", &err);
    object_property_set_int(OBJECT(&s->cpc), 1, "vp-start-running", &err);
    object_property_set_bool(OBJECT(&s->cpc), true, "realized", &err);
    if (err != NULL) {
        error_propagate(errp, err);
        return;
    }

    memory_region_add_subregion(&s->container, 0,
                            sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpc), 0));

    /* Global Interrupt Controller */
    sysbus_init_child_obj(OBJECT(dev), "gic", &s->gic, sizeof(s->gic),
                          TYPE_MIPS_GIC);
    object_property_set_int(OBJECT(&s->gic), s->num_vp, "num-vp", &err);
    object_property_set_int(OBJECT(&s->gic), 128, "num-irq", &err);
    object_property_set_bool(OBJECT(&s->gic), true, "realized", &err);
    if (err != NULL) {
        error_propagate(errp, err);
        return;
    }

    memory_region_add_subregion(&s->container, 0,
                            sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gic), 0));

    /* Global Configuration Registers */
    gcr_base = env->CP0_CMGCRBase << 4;

    sysbus_init_child_obj(OBJECT(dev), "gcr", &s->gcr, sizeof(s->gcr),
                          TYPE_MIPS_GCR);
    object_property_set_int(OBJECT(&s->gcr), s->num_vp, "num-vp", &err);
    object_property_set_int(OBJECT(&s->gcr), 0x800, "gcr-rev", &err);
    object_property_set_int(OBJECT(&s->gcr), gcr_base, "gcr-base", &err);
    object_property_set_link(OBJECT(&s->gcr), OBJECT(&s->gic.mr), "gic", &err);
    object_property_set_link(OBJECT(&s->gcr), OBJECT(&s->cpc.mr), "cpc", &err);
    object_property_set_bool(OBJECT(&s->gcr), true, "realized", &err);
    if (err != NULL) {
        error_propagate(errp, err);
        return;
    }

    memory_region_add_subregion(&s->container, gcr_base,
                            sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gcr), 0));
}
Beispiel #20
0
static void boston_mach_init(MachineState *machine)
{
    DeviceState *dev;
    BostonState *s;
    Error *err = NULL;
    MemoryRegion *flash, *ddr, *ddr_low_alias, *lcd, *platreg;
    MemoryRegion *sys_mem = get_system_memory();
    XilinxPCIEHost *pcie2;
    PCIDevice *ahci;
    DriveInfo *hd[6];
    Chardev *chr;
    int fw_size, fit_err;
    bool is_64b;

    if ((machine->ram_size % GiB) ||
        (machine->ram_size > (2 * GiB))) {
        error_report("Memory size must be 1GB or 2GB");
        exit(1);
    }

    dev = qdev_create(NULL, TYPE_MIPS_BOSTON);
    qdev_init_nofail(dev);

    s = BOSTON(dev);
    s->mach = machine;

    if (!cpu_supports_cps_smp(machine->cpu_type)) {
        error_report("Boston requires CPUs which support CPS");
        exit(1);
    }

    is_64b = cpu_supports_isa(machine->cpu_type, ISA_MIPS64);

    sysbus_init_child_obj(OBJECT(machine), "cps", OBJECT(&s->cps),
                          sizeof(s->cps), TYPE_MIPS_CPS);
    object_property_set_str(OBJECT(&s->cps), machine->cpu_type, "cpu-type",
                            &err);
    object_property_set_int(OBJECT(&s->cps), smp_cpus, "num-vp", &err);
    object_property_set_bool(OBJECT(&s->cps), true, "realized", &err);

    if (err != NULL) {
        error_report("%s", error_get_pretty(err));
        exit(1);
    }

    sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->cps), 0, 0, 1);

    flash =  g_new(MemoryRegion, 1);
    memory_region_init_rom(flash, NULL, "boston.flash", 128 * MiB, &err);
    memory_region_add_subregion_overlap(sys_mem, 0x18000000, flash, 0);

    ddr = g_new(MemoryRegion, 1);
    memory_region_allocate_system_memory(ddr, NULL, "boston.ddr",
                                         machine->ram_size);
    memory_region_add_subregion_overlap(sys_mem, 0x80000000, ddr, 0);

    ddr_low_alias = g_new(MemoryRegion, 1);
    memory_region_init_alias(ddr_low_alias, NULL, "boston_low.ddr",
                             ddr, 0, MIN(machine->ram_size, (256 * MiB)));
    memory_region_add_subregion_overlap(sys_mem, 0, ddr_low_alias, 0);

    xilinx_pcie_init(sys_mem, 0,
                     0x10000000, 32 * MiB,
                     0x40000000, 1 * GiB,
                     get_cps_irq(&s->cps, 2), false);

    xilinx_pcie_init(sys_mem, 1,
                     0x12000000, 32 * MiB,
                     0x20000000, 512 * MiB,
                     get_cps_irq(&s->cps, 1), false);

    pcie2 = xilinx_pcie_init(sys_mem, 2,
                             0x14000000, 32 * MiB,
                             0x16000000, 1 * MiB,
                             get_cps_irq(&s->cps, 0), true);

    platreg = g_new(MemoryRegion, 1);
    memory_region_init_io(platreg, NULL, &boston_platreg_ops, s,
                          "boston-platregs", 0x1000);
    memory_region_add_subregion_overlap(sys_mem, 0x17ffd000, platreg, 0);

    s->uart = serial_mm_init(sys_mem, 0x17ffe000, 2,
                             get_cps_irq(&s->cps, 3), 10000000,
                             serial_hd(0), DEVICE_NATIVE_ENDIAN);

    lcd = g_new(MemoryRegion, 1);
    memory_region_init_io(lcd, NULL, &boston_lcd_ops, s, "boston-lcd", 0x8);
    memory_region_add_subregion_overlap(sys_mem, 0x17fff000, lcd, 0);

    chr = qemu_chr_new("lcd", "vc:320x240", NULL);
    qemu_chr_fe_init(&s->lcd_display, chr, NULL);
    qemu_chr_fe_set_handlers(&s->lcd_display, NULL, NULL,
                             boston_lcd_event, NULL, s, NULL, true);

    ahci = pci_create_simple_multifunction(&PCI_BRIDGE(&pcie2->root)->sec_bus,
                                           PCI_DEVFN(0, 0),
                                           true, TYPE_ICH9_AHCI);
    g_assert(ARRAY_SIZE(hd) == ahci_get_num_ports(ahci));
    ide_drive_get(hd, ahci_get_num_ports(ahci));
    ahci_ide_create_devs(ahci, hd);

    if (machine->firmware) {
        fw_size = load_image_targphys(machine->firmware,
                                      0x1fc00000, 4 * MiB);
        if (fw_size == -1) {
            error_report("unable to load firmware image '%s'",
                          machine->firmware);
            exit(1);
        }
    } else if (machine->kernel_filename) {
        fit_err = load_fit(&boston_fit_loader, machine->kernel_filename, s);
        if (fit_err) {
            error_report("unable to load FIT image");
            exit(1);
        }

        gen_firmware(memory_region_get_ram_ptr(flash) + 0x7c00000,
                     s->kernel_entry, s->fdt_base, is_64b);
    } else if (!qtest_enabled()) {
        error_report("Please provide either a -kernel or -bios argument");
        exit(1);
    }
}
Beispiel #21
0
static void fsl_imx6_init(Object *obj)
{
    FslIMX6State *s = FSL_IMX6(obj);
    char name[NAME_SIZE];
    int i;

    for (i = 0; i < MIN(smp_cpus, FSL_IMX6_NUM_CPUS); i++) {
        snprintf(name, NAME_SIZE, "cpu%d", i);
        object_initialize_child(obj, name, &s->cpu[i], sizeof(s->cpu[i]),
                                "cortex-a9-" TYPE_ARM_CPU, &error_abort, NULL);
    }

    sysbus_init_child_obj(obj, "a9mpcore", &s->a9mpcore, sizeof(s->a9mpcore),
                          TYPE_A9MPCORE_PRIV);

    sysbus_init_child_obj(obj, "ccm", &s->ccm, sizeof(s->ccm), TYPE_IMX6_CCM);

    sysbus_init_child_obj(obj, "src", &s->src, sizeof(s->src), TYPE_IMX6_SRC);

    for (i = 0; i < FSL_IMX6_NUM_UARTS; i++) {
        snprintf(name, NAME_SIZE, "uart%d", i + 1);
        sysbus_init_child_obj(obj, name, &s->uart[i], sizeof(s->uart[i]),
                              TYPE_IMX_SERIAL);
    }

    sysbus_init_child_obj(obj, "gpt", &s->gpt, sizeof(s->gpt), TYPE_IMX6_GPT);

    for (i = 0; i < FSL_IMX6_NUM_EPITS; i++) {
        snprintf(name, NAME_SIZE, "epit%d", i + 1);
        sysbus_init_child_obj(obj, name, &s->epit[i], sizeof(s->epit[i]),
                              TYPE_IMX_EPIT);
    }

    for (i = 0; i < FSL_IMX6_NUM_I2CS; i++) {
        snprintf(name, NAME_SIZE, "i2c%d", i + 1);
        sysbus_init_child_obj(obj, name, &s->i2c[i], sizeof(s->i2c[i]),
                              TYPE_IMX_I2C);
    }

    for (i = 0; i < FSL_IMX6_NUM_GPIOS; i++) {
        snprintf(name, NAME_SIZE, "gpio%d", i + 1);
        sysbus_init_child_obj(obj, name, &s->gpio[i], sizeof(s->gpio[i]),
                              TYPE_IMX_GPIO);
    }

    for (i = 0; i < FSL_IMX6_NUM_ESDHCS; i++) {
        snprintf(name, NAME_SIZE, "sdhc%d", i + 1);
        sysbus_init_child_obj(obj, name, &s->esdhc[i], sizeof(s->esdhc[i]),
                              TYPE_IMX_USDHC);
    }

    for (i = 0; i < FSL_IMX6_NUM_ECSPIS; i++) {
        snprintf(name, NAME_SIZE, "spi%d", i + 1);
        sysbus_init_child_obj(obj, name, &s->spi[i], sizeof(s->spi[i]),
                              TYPE_IMX_SPI);
    }

    sysbus_init_child_obj(obj, "eth", &s->eth, sizeof(s->eth), TYPE_IMX_ENET);
}