Esempio n. 1
0
static void ipi_realize(DeviceState *dev, Error **errp)
{
    IPI *s = XILINX_IPI(dev);
    const char *prefix = object_get_canonical_path(OBJECT(dev));
    unsigned int i;

    for (i = 0; i < ARRAY_SIZE(ipi_regs_info); ++i) {
        DepRegisterInfo *r = &s->regs_info[ipi_regs_info[i].decode.addr/4];

        *r = (DepRegisterInfo) {
            .data = (uint8_t *)&s->regs[
                    ipi_regs_info[i].decode.addr/4],
            .data_size = sizeof(uint32_t),
            .access = &ipi_regs_info[i],
            .debug = XILINX_IPI_ERR_DEBUG,
            .prefix = prefix,
            .opaque = s,
        };
        dep_register_init(r);
        qdev_pass_all_gpios(DEVICE(r), dev);
    }

    qdev_init_gpio_in_named(dev, ipi_handler, "IPI_INPUTS", 32);
    qdev_init_gpio_in_named(dev, obs_handler, "OBS_INPUTS", 32);
}

static void ipi_init(Object *obj)
{
    IPI *s = XILINX_IPI(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    memory_region_init_io(&s->iomem, obj, &ipi_ops, s,
                          TYPE_XILINX_IPI, R_MAX * 4);
    sysbus_init_mmio(sbd, &s->iomem);
    sysbus_init_irq(sbd, &s->irq);
}
Esempio n. 2
0
static void rpu_realize(DeviceState *dev, Error **errp)
{
    RPU *s = XILINX_RPU(dev);
    const char *prefix = object_get_canonical_path(OBJECT(dev));
    unsigned int i;

    for (i = 0; i < ARRAY_SIZE(rpu_regs_info); ++i) {
        RegisterInfo *r = &s->regs_info[rpu_regs_info[i].decode.addr/4];

        *r = (RegisterInfo) {
            .data = (uint8_t *)&s->regs[
                    rpu_regs_info[i].decode.addr/4],
            .data_size = sizeof(uint32_t),
            .access = &rpu_regs_info[i],
            .debug = XILINX_RPU_ERR_DEBUG,
            .prefix = prefix,
            .opaque = s,
        };
        register_init(r);
        qdev_pass_all_gpios(DEVICE(r), dev);
    }

    if (!s->atcm1_for_rpu0) {
        error_set(errp, QERR_MISSING_PARAMETER, "atcm1-for-rpu0");
        return;
    }

    if (!s->btcm1_for_rpu0) {
        error_set(errp, QERR_MISSING_PARAMETER, "btcm1-for-rpu0");
        return;
    }

    if (!s->icache_for_rpu1) {
        error_set(errp, QERR_MISSING_PARAMETER, "icache-for-rpu1");
        return;
    }

    if (!s->dcache_for_rpu1) {
        error_set(errp, QERR_MISSING_PARAMETER, "dcache-for-rpu1");
        return;
    }

    if (!s->ddr) {
        error_set(errp, QERR_MISSING_PARAMETER, "ddr-mem-for-rpu");
        return;
    }

    /* RPUs starts in lockstep mode, so the rpu1 caches are not accessible. */
    memory_region_set_enabled(s->icache_for_rpu1, false);
    memory_region_set_enabled(s->dcache_for_rpu1, false);
    memory_region_set_enabled(s->ddr, false);
}

static void rpu_init(Object *obj)
{
    RPU *s = XILINX_RPU(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    memory_region_init_io(&s->iomem, obj, &rpu_ops, s,
                          TYPE_XILINX_RPU, R_MAX * 4);
    sysbus_init_mmio(sbd, &s->iomem);
    sysbus_init_irq(sbd, &s->irq_rpu_1);
    sysbus_init_irq(sbd, &s->irq_rpu_0);

    /* xtcm1-for-rpu0 are the aliases for the tcm in lockstep mode.
     * This link allows to enable/disable those aliases when we are in
     * lock-step/normal mode.
     */
    object_property_add_link(obj, "atcm1-for-rpu0", TYPE_MEMORY_REGION,
                             (Object **)&s->atcm1_for_rpu0,
                             qdev_prop_allow_set_link_before_realize,
                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
                             &error_abort);
    object_property_add_link(obj, "btcm1-for-rpu0", TYPE_MEMORY_REGION,
                             (Object **)&s->btcm1_for_rpu0,
                             qdev_prop_allow_set_link_before_realize,
                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
                             &error_abort);
    object_property_add_link(obj, "rpu1-for-main-bus", TYPE_MEMORY_REGION,
                             (Object **)&s->atcm1_for_rpu0,
                             qdev_prop_allow_set_link_before_realize,
                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
                             &error_abort);

    /* This link allows to enable/disable those memory region when we are in
     * lock-step/normal mode.
     */
    object_property_add_link(obj, "icache-for-rpu1", TYPE_MEMORY_REGION,
                             (Object **)&s->icache_for_rpu1,
                             qdev_prop_allow_set_link_before_realize,
                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
                             &error_abort);
    object_property_add_link(obj, "dcache-for-rpu1", TYPE_MEMORY_REGION,
                             (Object **)&s->dcache_for_rpu1,
                             qdev_prop_allow_set_link_before_realize,
                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
                             &error_abort);

    /* Link to the second part of the DDR which is enabled in split mode and
     * disabled in lockstep mode.
     */
    object_property_add_link(obj, "ddr-mem-for-rpu", TYPE_MEMORY_REGION,
                             (Object **)&s->ddr,
                             qdev_prop_allow_set_link_before_realize,
                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
                             &error_abort);

    /* wfi_out is used to connect to PMU GPIs. */
    qdev_init_gpio_out_named(DEVICE(obj), s->wfi_out, "wfi_out", 2);
    /* wfi_in is used as input from CPUs as wfi request. */
    qdev_init_gpio_in_named(DEVICE(obj), zynqmp_rpu_0_handle_wfi, "wfi_in_0", 1);
    qdev_init_gpio_in_named(DEVICE(obj), zynqmp_rpu_1_handle_wfi, "wfi_in_1", 1);
}