From: Shannon Zhao <zhaoshenglong@huawei.com>
To: Peter Maydell <peter.maydell@linaro.org>,
qemu-arm@nongnu.org, qemu-devel@nongnu.org
Cc: patches@linaro.org, Shlomo Pongratz <shlomo.pongratz@huawei.com>,
Shlomo Pongratz <shlomopongratz@gmail.com>,
Pavel Fedin <p.fedin@samsung.com>,
Shannon Zhao <shannon.zhao@linaro.org>,
Christoffer Dall <christoffer.dall@linaro.org>
Subject: Re: [Qemu-devel] [PATCH v2 17/22] hw/intc/arm_gicv3: Implement CPU i/f SGI generation registers
Date: Tue, 14 Jun 2016 14:24:07 +0800 [thread overview]
Message-ID: <575FA307.1020907@huawei.com> (raw)
In-Reply-To: <1464274540-19693-18-git-send-email-peter.maydell@linaro.org>
On 2016/5/26 22:55, Peter Maydell wrote:
> Implement the registers in the GICv3 CPU interface which generate
> new SGI interrupts.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Shannon Zhao <shannon.zhao@linaro.org>
> ---
> hw/intc/arm_gicv3_cpuif.c | 125 +++++++++++++++++++++++++++++++++++++++++++++
> hw/intc/arm_gicv3_redist.c | 40 +++++++++++++++
> hw/intc/gicv3_internal.h | 1 +
> trace-events | 2 +
> 4 files changed, 168 insertions(+)
>
> diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
> index 7faf3c0..a368dbb 100644
> --- a/hw/intc/arm_gicv3_cpuif.c
> +++ b/hw/intc/arm_gicv3_cpuif.c
> @@ -331,6 +331,95 @@ static void icc_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
> gicv3_cpuif_update(cs);
> }
>
> +static void icc_generate_sgi(CPUARMState *env, GICv3CPUState *cs,
> + uint64_t value, int grp, bool ns)
> +{
> + GICv3State *s = cs->gic;
> +
> + /* Extract Aff3/Aff2/Aff1 and shift into the bottom 24 bits */
> + uint64_t aff = extract64(value, 48, 8) << 16 |
> + extract64(value, 32, 8) << 8 |
> + extract64(value, 16, 8);
> + uint32_t targetlist = extract64(value, 0, 16);
> + uint32_t irq = extract64(value, 24, 4);
> + bool irm = extract64(value, 40, 1);
> + int i;
> +
> + if (grp == GICV3_G1 && s->gicd_ctlr & GICD_CTLR_DS) {
> + /* If GICD_CTLR.DS == 1, the Distributor treats Secure Group 1
> + * interrupts as Group 0 interrupts and must send Secure Group 0
> + * interrupts to the target CPUs.
> + */
> + grp = GICV3_G0;
> + }
> +
> + trace_gicv3_icc_generate_sgi(gicv3_redist_affid(cs), irq, irm,
> + aff, targetlist);
> +
> + for (i = 0; i < s->num_cpu; i++) {
> + GICv3CPUState *ocs = &s->cpu[i];
> +
> + if (irm) {
> + /* IRM == 1 : route to all CPUs except self */
> + if (cs == ocs) {
> + continue;
> + }
> + } else {
> + /* IRM == 0 : route to Aff3.Aff2.Aff1.n for all n in [0..15]
> + * where the corresponding bit is set in targetlist
> + */
> + int aff0;
> +
> + if (ocs->gicr_typer >> 40 != aff) {
> + continue;
> + }
> + aff0 = extract64(ocs->gicr_typer, 32, 8);
> + if (aff0 > 15 || extract32(targetlist, aff0, 1) == 0) {
> + continue;
> + }
> + }
> +
> + /* The redistributor will check against its own GICR_NSACR as needed */
> + gicv3_redist_send_sgi(ocs, grp, irq, ns);
> + }
> +}
> +
> +static void icc_sgi0r_write(CPUARMState *env, const ARMCPRegInfo *ri,
> + uint64_t value)
> +{
> + /* Generate Secure Group 0 SGI. */
> + GICv3CPUState *cs = icc_cs_from_env(env);
> + bool ns = !arm_is_secure(env);
> +
> + icc_generate_sgi(env, cs, value, GICV3_G0, ns);
> +}
> +
> +static void icc_sgi1r_write(CPUARMState *env, const ARMCPRegInfo *ri,
> + uint64_t value)
> +{
> + /* Generate Group 1 SGI for the current Security state */
> + GICv3CPUState *cs = icc_cs_from_env(env);
> + int grp;
> + bool ns = !arm_is_secure(env);
> +
> + grp = ns ? GICV3_G1NS : GICV3_G1;
> + icc_generate_sgi(env, cs, value, grp, ns);
> +}
> +
> +static void icc_asgi1r_write(CPUARMState *env, const ARMCPRegInfo *ri,
> + uint64_t value)
> +{
> + /* Generate Group 1 SGI for the Security state that is not
> + * the current state
> + */
> + GICv3CPUState *cs = icc_cs_from_env(env);
> + int grp;
> + bool ns = !arm_is_secure(env);
> +
> + grp = ns ? GICV3_G1 : GICV3_G1NS;
> + icc_generate_sgi(env, cs, value, grp, ns);
> +}
> +
> static uint64_t icc_igrpen_read(CPUARMState *env, const ARMCPRegInfo *ri)
> {
> GICv3CPUState *cs = icc_cs_from_env(env);
> @@ -673,6 +762,42 @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
> .readfn = icc_ap_read,
> .writefn = icc_ap_write,
> },
> + { .name = "ICC_SGI1R_EL1", .state = ARM_CP_STATE_AA64,
> + .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 5,
> + .type = ARM_CP_IO | ARM_CP_NO_RAW,
> + .access = PL1_W, .accessfn = gicv3_irqfiq_access,
> + .writefn = icc_sgi1r_write,
> + },
> + { .name = "ICC_SGI1R",
> + .cp = 15, .opc1 = 0, .crm = 12,
> + .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_RAW,
> + .access = PL1_W, .accessfn = gicv3_irqfiq_access,
> + .writefn = icc_sgi1r_write,
> + },
> + { .name = "ICC_ASGI1R_EL1", .state = ARM_CP_STATE_AA64,
> + .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 6,
> + .type = ARM_CP_IO | ARM_CP_NO_RAW,
> + .access = PL1_W, .accessfn = gicv3_irqfiq_access,
> + .writefn = icc_asgi1r_write,
> + },
> + { .name = "ICC_ASGI1R",
> + .cp = 15, .opc1 = 1, .crm = 12,
> + .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_RAW,
> + .access = PL1_W, .accessfn = gicv3_irqfiq_access,
> + .writefn = icc_asgi1r_write,
> + },
> + { .name = "ICC_SGI0R_EL1", .state = ARM_CP_STATE_AA64,
> + .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 7,
> + .type = ARM_CP_IO | ARM_CP_NO_RAW,
> + .access = PL1_W, .accessfn = gicv3_irqfiq_access,
> + .writefn = icc_sgi0r_write,
> + },
> + { .name = "ICC_SGI0R",
> + .cp = 15, .opc1 = 2, .crm = 12,
> + .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_RAW,
> + .access = PL1_W, .accessfn = gicv3_irqfiq_access,
> + .writefn = icc_sgi0r_write,
> + },
> /* This register is banked */
> { .name = "ICC_BPR1_EL1", .state = ARM_CP_STATE_BOTH,
> .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 3,
> diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
> index 16b3422..13893d3 100644
> --- a/hw/intc/arm_gicv3_redist.c
> +++ b/hw/intc/arm_gicv3_redist.c
> @@ -27,6 +27,13 @@ static uint32_t mask_group(GICv3CPUState *cs, MemTxAttrs attrs)
> return 0xFFFFFFFFU;
> }
>
> +static int gicr_ns_access(GICv3CPUState *cs, int irq)
> +{
> + /* Return the 2 bit NSACR.NS_access field for this SGI */
> + assert(irq < 16);
> + return extract32(cs->gicr_nsacr, irq * 2, 2);
> +}
> +
> static void gicr_write_set_bitmap_reg(GICv3CPUState *cs, MemTxAttrs attrs,
> uint32_t *reg, uint32_t val)
> {
> @@ -514,3 +521,36 @@ void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level)
>
> gicv3_redist_update(cs);
> }
> +
> +void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns)
> +{
> + /* Update redistributor state for a generated SGI */
> + int irqgrp = gicv3_irq_group(cs->gic, cs, irq);
> +
> + /* If we are asked for a Secure Group 1 SGI and it's actually
> + * configured as Secure Group 0 this is OK (subject to the usual
> + * NSACR checks).
> + */
> + if (grp == GICV3_G1 && irqgrp == GICV3_G0) {
> + grp = GICV3_G0;
> + }
> +
> + if (grp != irqgrp) {
> + return;
> + }
> +
> + if (ns && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
> + /* If security is enabled we must test the NSACR bits */
> + int nsaccess = gicr_ns_access(cs, irq);
> +
> + if ((irqgrp == GICV3_G0 && nsaccess < 1) ||
> + (irqgrp == GICV3_G1 && nsaccess < 2)) {
> + return;
> + }
> + }
> +
> + /* OK, we can accept the SGI */
> + trace_gicv3_redist_send_sgi(gicv3_redist_affid(cs), irq);
> + cs->gicr_ipendr0 = deposit32(cs->gicr_ipendr0, irq, 1, 1);
> + gicv3_redist_update(cs);
> +}
> diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
> index d06ef3e..561849c 100644
> --- a/hw/intc/gicv3_internal.h
> +++ b/hw/intc/gicv3_internal.h
> @@ -211,6 +211,7 @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
> unsigned size, MemTxAttrs attrs);
> void gicv3_dist_set_irq(GICv3State *s, int irq, int level);
> void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level);
> +void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns);
> void gicv3_init_cpuif(GICv3State *s);
>
> /**
> diff --git a/trace-events b/trace-events
> index e84cea9..762f5a0 100644
> --- a/trace-events
> +++ b/trace-events
> @@ -1934,6 +1934,7 @@ gicv3_icc_ctlr_el3_read(uint32_t cpu, uint64_t val) "GICv3 ICC_CTLR_EL3 read cpu
> gicv3_icc_ctlr_el3_write(uint32_t cpu, uint64_t val) "GICv3 ICC_CTLR_EL3 write cpu %x value 0x%" PRIx64
> gicv3_cpuif_update(uint32_t cpuid, int irq, int grp, int prio) "GICv3 CPU i/f %x HPPI update: irq %d group %d prio %d"
> gicv3_cpuif_set_irqs(uint32_t cpuid, int fiqlevel, int irqlevel) "GICv3 CPU i/f %x HPPI update: setting FIQ %d IRQ %d"
> +gicv3_icc_generate_sgi(uint32_t cpuid, int irq, int irm, uint32_t aff, uint32_t targetlist) "GICv3 CPU i/f %x generating SGI %d IRM %d target affinity 0x%xxx targetlist 0x%x"
>
> # hw/intc/arm_gicv3_dist.c
> gicv3_dist_read(uint64_t offset, uint64_t data, unsigned size, bool secure) "GICv3 distributor read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u secure %d"
> @@ -1948,3 +1949,4 @@ gicv3_redist_badread(uint32_t cpu, uint64_t offset, unsigned size, bool secure)
> gicv3_redist_write(uint32_t cpu, uint64_t offset, uint64_t data, unsigned size, bool secure) "GICv3 redistributor %x write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u secure %d"
> gicv3_redist_badwrite(uint32_t cpu, uint64_t offset, uint64_t data, unsigned size, bool secure) "GICv3 redistributor %x write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u secure %d: error"
> gicv3_redist_set_irq(uint32_t cpu, int irq, int level) "GICv3 redistributor %x interrupt %d level changed to %d"
> +gicv3_redist_send_sgi(uint32_t cpu, int irq) "GICv3 redistributor %x pending SGI %d"
>
--
Shannon
next prev parent reply other threads:[~2016-06-14 6:24 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-05-26 14:55 [Qemu-devel] [PATCH v2 00/22] GICv3 emulation Peter Maydell
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 01/22] migration: Define VMSTATE_UINT64_2DARRAY Peter Maydell
2016-06-07 3:32 ` Shannon Zhao
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 02/22] bitops.h: Implement half-shuffle and half-unshuffle ops Peter Maydell
2016-06-07 6:35 ` Shannon Zhao
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 03/22] target-arm: Define new arm_is_el3_or_mon() function Peter Maydell
2016-06-07 6:32 ` Shannon Zhao
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 04/22] target-arm: Provide hook to tell GICv3 about changes of security state Peter Maydell
2016-06-14 1:49 ` Shannon Zhao
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 05/22] target-arm: Add mp-affinity property for ARM CPU class Peter Maydell
2016-06-07 7:55 ` Shannon Zhao
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 06/22] hw/intc/arm_gicv3: Add state information Peter Maydell
2016-06-07 7:51 ` Shannon Zhao
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 07/22] hw/intc/arm_gicv3: Move irq lines into GICv3CPUState structure Peter Maydell
2016-06-07 8:33 ` Shannon Zhao
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 08/22] hw/intc/arm_gicv3: Add vmstate descriptors Peter Maydell
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 09/22] hw/intc/arm_gicv3: ARM GICv3 device framework Peter Maydell
2016-06-07 9:01 ` Shannon Zhao
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 10/22] hw/intc/arm_gicv3: Implement functions to identify next pending irq Peter Maydell
2016-06-08 1:57 ` Shannon Zhao
2016-06-09 15:24 ` Peter Maydell
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 11/22] hw/intc/arm_gicv3: Implement GICv3 distributor registers Peter Maydell
2016-06-13 6:27 ` Shannon Zhao
2016-06-13 9:04 ` Peter Maydell
2016-06-13 9:35 ` Shannon Zhao
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 12/22] hw/intc/arm_gicv3: Implement GICv3 redistributor registers Peter Maydell
2016-06-14 3:09 ` Shannon Zhao
2016-06-14 12:25 ` Peter Maydell
2016-06-14 12:28 ` Peter Maydell
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 13/22] hw/intc/arm_gicv3: Wire up distributor and redistributor MMIO regions Peter Maydell
2016-06-13 7:19 ` Shannon Zhao
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 14/22] hw/intc/arm_gicv3: Implement gicv3_set_irq() Peter Maydell
2016-06-13 7:49 ` Shannon Zhao
2016-06-13 9:07 ` Peter Maydell
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 15/22] hw/intc/arm_gicv3: Implement GICv3 CPU interface registers Peter Maydell
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 16/22] hw/intc/arm_gicv3: Implement gicv3_cpuif_update() Peter Maydell
2016-06-13 7:56 ` Shannon Zhao
2016-06-13 9:10 ` Peter Maydell
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 17/22] hw/intc/arm_gicv3: Implement CPU i/f SGI generation registers Peter Maydell
2016-06-14 6:24 ` Shannon Zhao [this message]
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 18/22] hw/intc/arm_gicv3: Add IRQ handling CPU interface registers Peter Maydell
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 19/22] target-arm/machine.c: Allow user to request GICv3 emulation Peter Maydell
2016-06-13 11:38 ` Shannon Zhao
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 20/22] target-arm/monitor.c: Advertise emulated GICv3 in capabilities Peter Maydell
2016-06-13 11:40 ` Shannon Zhao
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 21/22] NOT-FOR-UPSTREAM: kernel: Add definitions for GICv3 attributes Peter Maydell
2016-06-13 11:51 ` Shannon Zhao
2016-06-13 12:02 ` Peter Maydell
2016-05-26 14:55 ` [Qemu-devel] [PATCH v2 22/22] RFC: hw/intc/arm_gicv3_kvm: Implement get/put functions Peter Maydell
2016-05-30 11:15 ` [Qemu-devel] [PATCH v2 00/22] GICv3 emulation Andrew Jones
2016-06-06 14:42 ` [Qemu-devel] [Qemu-arm] " Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=575FA307.1020907@huawei.com \
--to=zhaoshenglong@huawei.com \
--cc=christoffer.dall@linaro.org \
--cc=p.fedin@samsung.com \
--cc=patches@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=shannon.zhao@linaro.org \
--cc=shlomo.pongratz@huawei.com \
--cc=shlomopongratz@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).