コード例 #1
0
static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
                              const char *name, hwaddr size)
{
    MPS2SCC *scc = opaque;
    DeviceState *sccdev;
    MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);

    object_initialize(scc, sizeof(mms->scc), TYPE_MPS2_SCC);
    sccdev = DEVICE(scc);
    qdev_set_parent_bus(sccdev, sysbus_get_default());
    qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
    qdev_prop_set_uint32(sccdev, "scc-aid", 0x02000008);
    qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
    object_property_set_bool(OBJECT(scc), true, "realized", &error_fatal);
    return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
}
コード例 #2
0
ファイル: mps2-tz.c プロジェクト: MaddTheSane/qemu
static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
{
    /* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
    MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);

    assert(irqno < MPS2TZ_NUMIRQ);

    switch (mmc->fpga_type) {
    case FPGA_AN505:
        return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
    case FPGA_AN521:
        return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
    default:
        g_assert_not_reached();
    }
}
コード例 #3
0
ファイル: mps2-tz.c プロジェクト: MaddTheSane/qemu
static void mps2tz_common_init(MachineState *machine)
{
    MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
    MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
    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), mmc->armsse_type);
    iotkitdev = DEVICE(&mms->iotkit);
    object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
                             "memory", &error_abort);
    qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
    qdev_prop_set_uint32(iotkitdev, "MAINCLK", SYSCLK_FRQ);
    object_property_set_bool(OBJECT(&mms->iotkit), true, "realized",
                             &error_fatal);

    /*
     * The AN521 needs us to create splitters to feed the IRQ inputs
     * for each CPU in the SSE-200 from each device in the board.
     */
    if (mmc->fpga_type == FPGA_AN521) {
        for (i = 0; i < MPS2TZ_NUMIRQ; i++) {
            char *name = g_strdup_printf("mps2-irq-splitter%d", i);
            SplitIRQ *splitter = &mms->cpu_irq_splitter[i];

            object_initialize_child(OBJECT(machine), name,
                                    splitter, sizeof(*splitter),
                                    TYPE_SPLIT_IRQ, &error_fatal, NULL);
            g_free(name);

            object_property_set_int(OBJECT(splitter), 2, "num-lines",
                                    &error_fatal);
            object_property_set_bool(OBJECT(splitter), true, "realized",
                                     &error_fatal);
            qdev_connect_gpio_out(DEVICE(splitter), 0,
                                  qdev_get_gpio_in_named(DEVICE(&mms->iotkit),
                                                         "EXP_IRQ", i));
            qdev_connect_gpio_out(DEVICE(splitter), 1,
                                  qdev_get_gpio_in_named(DEVICE(&mms->iotkit),
                                                         "EXP_CPU1_IRQ", i));
        }
    }

    /* The sec_resp_cfg output from the IoTKit must be split into multiple
     * lines, one for each of the PPCs we create here, plus one per MSC.
     */
    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),
                            ARRAY_SIZE(mms->ppc) + ARRAY_SIZE(mms->msc),
                            "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,
                          get_sse_irq_in(mms, 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",