qemu-arm
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-arm] [PATCH 26/27] hw/arm/iotkit: Wire up MPC interrupt lines


From: Alex Bennée
Subject: Re: [Qemu-arm] [PATCH 26/27] hw/arm/iotkit: Wire up MPC interrupt lines
Date: Wed, 23 May 2018 12:39:36 +0100
User-agent: mu4e 1.1.0; emacs 26.1

Peter Maydell <address@hidden> writes:

> The interrupt outputs from the MPC in the IoTKit and the expansion
> MPCs in the board must be wired up to the security controller, and
> also all ORed together to produce a single line to the NVIC.
>
> Signed-off-by: Peter Maydell <address@hidden>

Reviewed-by: Alex Bennée <address@hidden>

> ---
>  include/hw/arm/iotkit.h |  6 ++++
>  hw/arm/iotkit.c         | 74 +++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 80 insertions(+)
>
> diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
> index b21cf1ab9d..2cddde55dd 100644
> --- a/include/hw/arm/iotkit.h
> +++ b/include/hw/arm/iotkit.h
> @@ -42,6 +42,9 @@
>   *  + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_enable
>   *  + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_clear
>   *  + named GPIO inputs ahb_ppcexp{0,1,2,3}_irq_status
> + * Controlling each of the 16 expansion MPCs which a system using the IoTKit
> + * might provide:
> + *  + named GPIO inputs mpcexp_status[0..15]
>   */
>
>  #ifndef IOTKIT_H
> @@ -81,6 +84,8 @@ typedef struct IoTKit {
>      qemu_or_irq ppc_irq_orgate;
>      SplitIRQ sec_resp_splitter;
>      SplitIRQ ppc_irq_splitter[NUM_PPCS];
> +    SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC];
> +    qemu_or_irq mpc_irq_orgate;
>
>      UnimplementedDeviceState dualtimer;
>      UnimplementedDeviceState s32ktimer;
> @@ -99,6 +104,7 @@ typedef struct IoTKit {
>      qemu_irq nsc_cfg_in;
>
>      qemu_irq irq_status_in[NUM_EXTERNAL_PPCS];
> +    qemu_irq mpcexp_status_in[IOTS_NUM_EXP_MPC];
>
>      uint32_t nsccfg;
>
> diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
> index 160e40c744..133d5bb34f 100644
> --- a/hw/arm/iotkit.c
> +++ b/hw/arm/iotkit.c
> @@ -131,6 +131,18 @@ static void iotkit_init(Object *obj)
>      init_sysbus_child(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1),
>                        TYPE_TZ_PPC);
>      init_sysbus_child(obj, "mpc", &s->mpc, sizeof(s->mpc), TYPE_TZ_MPC);
> +    object_initialize(&s->mpc_irq_orgate, sizeof(s->mpc_irq_orgate),
> +                      TYPE_OR_IRQ);
> +    object_property_add_child(obj, "mpc-irq-orgate",
> +                              OBJECT(&s->mpc_irq_orgate), &error_abort);
> +    for (i = 0; i < ARRAY_SIZE(s->mpc_irq_splitter); i++) {
> +        char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
> +        SplitIRQ *splitter = &s->mpc_irq_splitter[i];
> +
> +        object_initialize(splitter, sizeof(*splitter), TYPE_SPLIT_IRQ);
> +        object_property_add_child(obj, name, OBJECT(splitter), &error_abort);
> +        g_free(name);
> +    }
>      init_sysbus_child(obj, "timer0", &s->timer0, sizeof(s->timer0),
>                        TYPE_CMSDK_APB_TIMER);
>      init_sysbus_child(obj, "timer1", &s->timer1, sizeof(s->timer1),
> @@ -163,6 +175,12 @@ static void iotkit_exp_irq(void *opaque, int n, int 
> level)
>      qemu_set_irq(s->exp_irqs[n], level);
>  }
>
> +static void iotkit_mpcexp_status(void *opaque, int n, int level)
> +{
> +    IoTKit *s = IOTKIT(opaque);
> +    qemu_set_irq(s->mpcexp_status_in[n], level);
> +}
> +
>  static void iotkit_realize(DeviceState *dev, Error **errp)
>  {
>      IoTKit *s = IOTKIT(dev);
> @@ -328,6 +346,22 @@ static void iotkit_realize(DeviceState *dev, Error 
> **errp)
>                                  
> sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
>                                                         0));
>
> +    /* We must OR together lines from the MPC splitters to go to the NVIC */
> +    object_property_set_int(OBJECT(&s->mpc_irq_orgate),
> +                            IOTS_NUM_EXP_MPC + IOTS_NUM_MPC, "num-lines", 
> &err);
> +    if (err) {
> +        error_propagate(errp, err);
> +        return;
> +    }
> +    object_property_set_bool(OBJECT(&s->mpc_irq_orgate), true,
> +                             "realized", &err);
> +    if (err) {
> +        error_propagate(errp, err);
> +        return;
> +    }
> +    qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
> +                          qdev_get_gpio_in(DEVICE(&s->armv7m), 9));
> +
>      /* Devices behind APB PPC0:
>       *   0x40000000: timer0
>       *   0x40001000: timer1
> @@ -536,6 +570,46 @@ static void iotkit_realize(DeviceState *dev, Error 
> **errp)
>          g_free(gpioname);
>      }
>
> +    /* Wire up the splitters for the MPC IRQs */
> +    for (i = 0; i < IOTS_NUM_EXP_MPC + IOTS_NUM_MPC; i++) {
> +        SplitIRQ *splitter = &s->mpc_irq_splitter[i];
> +        DeviceState *dev_splitter = DEVICE(splitter);
> +
> +        object_property_set_int(OBJECT(splitter), 2, "num-lines", &err);
> +        if (err) {
> +            error_propagate(errp, err);
> +            return;
> +        }
> +        object_property_set_bool(OBJECT(splitter), true, "realized", &err);
> +        if (err) {
> +            error_propagate(errp, err);
> +            return;
> +        }
> +
> +        if (i < IOTS_NUM_EXP_MPC) {
> +            /* Splitter input is from GPIO input line */
> +            s->mpcexp_status_in[i] = qdev_get_gpio_in(dev_splitter, 0);
> +            qdev_connect_gpio_out(dev_splitter, 0,
> +                                  qdev_get_gpio_in_named(dev_secctl,
> +                                                         "mpcexp_status", 
> i));
> +        } else {
> +            /* Splitter input is from our own MPC */
> +            qdev_connect_gpio_out_named(DEVICE(&s->mpc), "irq", 0,
> +                                        qdev_get_gpio_in(dev_splitter, 0));
> +            qdev_connect_gpio_out(dev_splitter, 0,
> +                                  qdev_get_gpio_in_named(dev_secctl,
> +                                                         "mpc_status", 0));
> +        }
> +
> +        qdev_connect_gpio_out(dev_splitter, 1,
> +                              qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), 
> i));
> +    }
> +    /* Create GPIO inputs which will pass the line state for our
> +     * mpcexp_irq inputs to the correct splitter devices.
> +     */
> +    qdev_init_gpio_in_named(dev, iotkit_mpcexp_status, "mpcexp_status",
> +                            IOTS_NUM_EXP_MPC);
> +
>      iotkit_forward_sec_resp_cfg(s);
>
>      system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;


--
Alex Bennée



reply via email to

[Prev in Thread] Current Thread [Next in Thread]