qemu-arm
[Top][All Lists]
Advanced

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

Re: [Qemu-arm] [Qemu-devel] [PATCH v2 12/22] hw/intc/arm_gicv3: Implemen


From: Peter Maydell
Subject: Re: [Qemu-arm] [Qemu-devel] [PATCH v2 12/22] hw/intc/arm_gicv3: Implement GICv3 redistributor registers
Date: Tue, 14 Jun 2016 13:25:31 +0100

On 14 June 2016 at 04:09, Shannon Zhao <address@hidden> wrote:
>
>
> On 2016/5/26 22:55, Peter Maydell wrote:
>> Implement the redistributor registers of a GICv3.

>> +    case GICR_ISENABLER0:
>> +    case GICR_ICENABLER0:
>> +        *data = gicr_read_bitmap_reg(cs, attrs, cs->gicr_ienabler0);

> GICv3 SPEC says when GICD_CTLR.DS == 0, for GICD_ICENABLER<n> bits
> corresponding to Group 0 and Secure Group 1 interrupts are RAZ/WI to
> Non-secure accesses. But for GICR_ICENABLER0 all bits are RAZ/WI to
> Non-secure accesses. It doesn't care the interrupt Group. If so,
> gicr_read_bitmap_reg() wrongly uses the return value of mask_group() as
> the mask.

The spec says for GICR_ICENABLER0 "When GICD_CTLR.DS == 0, bits corresponding
to Secure SGIs and PPIs are RAZ/WI to Non-secure accesses". So we are
correct to look at the group bit I think.

>> +        return MEMTX_OK;
>> +    case GICR_ISPENDR0:
>> +    case GICR_ICPENDR0:
>> +    {
>> +        /* The pending register reads as the logical OR of the pending
>> +         * latch and the input line level for level-triggered interrupts.
>> +         */
>> +        uint32_t val = cs->gicr_ipendr0 | (~cs->edge_trigger & cs->level);
>> +        *data = gicr_read_bitmap_reg(cs, attrs, val);
>> +        return MEMTX_OK;
>> +    }
>> +    case GICR_ISACTIVER0:
>> +    case GICR_ICACTIVER0:
>> +        *data = gicr_read_bitmap_reg(cs, attrs, cs->gicr_iactiver0);
>> +        return MEMTX_OK;
>> +    case GICR_IPRIORITYR ... GICR_IPRIORITYR + 0x1f:
>> +    {
>> +        int i, irq = offset - GICR_IPRIORITYR;
>> +        uint32_t value = 0;
>> +
>> +        for (i = irq + 3; i >= irq; i--, value <<= 8) {
>> +            value |= gicr_read_ipriorityr(cs, attrs, i);
>> +        }
>> +        *data = value;
>> +        return MEMTX_OK;
>> +    }
>> +    case GICR_ICFGR0:
>> +    case GICR_ICFGR1:
>> +    {
>> +        /* Our edge_trigger bitmap is one bit per irq; take the correct
>> +         * half of it, and spread it out into the odd bits.
>> +         */
>> +        uint32_t value;
>> +
>> +        value = cs->edge_trigger & mask_group(cs, attrs);
> For GICR_ICFGR0, it doesn't need to use mask_group() as mask because the
> SPEC doesn't say it's RAZ/WI to a Group 0 or Secure Group 1 interrupt.

This is a bug in the GICv3 spec which will be fixed in a newer
rev of the document. GICR_ICFGR0 should say that "When GICD_CTLR.DS==0,
a register bit that corresponds to a Group 0 or Secure Group 1
interrupt is RAZ/WI to Non-secure accesses".

>> +        value = extract32(value, (offset == GICR_ICFGR1) ? 16 : 0, 16);
>> +        value = half_shuffle32(value) << 1;
>> +        *data = value;
>> +        return MEMTX_OK;
>> +    }
>> +    case GICR_IGRPMODR0:
>> +        if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
>> +            /* RAZ/WI if security disabled, or if
>> +             * security enabled and this is an NS access
>> +             */
>> +            *data = 0;
>> +            return MEMTX_OK;
>> +        }
>> +        *data = cs->gicr_igrpmodr0;
>> +        return MEMTX_OK;
>> +    case GICR_NSACR:
>> +        if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
>> +            *data = 0;
>> +            return MEMTX_OK;
>> +        }
>> +        *data = cs->gicr_nsacr;
> Look like this is not consistent with the SPEC.
> The SPEC says
> "When GICD_CTLR.DS == 1, this register is RAZ/WI.
> When GICD_CTLR.DS == 0, this register is Secure, and is RAZ/WI to
> Non-secure accesses."
>
> So when GICD_CTLR.DS == 1, it should make *data = 0.

Agreed. This should have the same kind of condition as GICR_IGRPMODR0:

        if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
            /* RAZ/WI if security disabled, or if
             * security enabled and this is an NS access
             */
            *data = 0;
            return MEMTX_OK;

(similarly for writes)

thanks
-- PMM



reply via email to

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