head -r317015 (and before) vs. Pine64+ 2GB (an aarch64) and spurious interrupts: [the A64 IRQ numbers involved other than 1023]
Mark Millard
markmi at dsl-only.net
Tue Apr 25 09:55:44 UTC 2017
On 2017-Apr-25, at 12:25 AM, Mark Millard <markmi at dsl-only.net> wrote:
> On 2017-Apr-24, at 10:03 PM, Mark Millard <markmi at dsl-only.net> wrote:
>
>> I found some basic reference material for the
>> "last irq" numbers for the A64 that is in the
>> Pine64+ 2GB (and 1GB). . .
>>
>> IRQ 27: PPI 11 interrupt, vector 0x006C
>> (I've no clue about this one beyond it being a
>> "Private Peripheral Interrupt" example, somehow
>> specific to each core separately.)
>
> Looks to be a timer, not that I can tell
> much about it:
>
> timer {
> compatible = "arm,armv8-timer";
> interrupts = <GIC_PPI 13
> (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
> <GIC_PPI 14
> (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
> <GIC_PPI 11
> (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
> <GIC_PPI 10
> (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
> };
>
> But looking around I've seen references to needing IRQ_TYPE_NONE
> if the register is read-only, avoiding writes to read-only
> registers, --with such timers as examples (not necessarily
> A64 specific material though).
Looking around more the read-only status seems to be
an implementation defined area for PPI's.
But I have other notes later below on what appears to
me to be a mismatch between _HIGH vs. _LOW use and what
arm_gic_architecture_specification_v2.0.pdf says.
>> The rest of the IRQs are "Shared Peripheral
>> Interrupt"s. . .
>>
>> IRQ 92: SD/MMC Host Controller 0 interrupt, vector 0x0170
>>
>> IRQ 106: USB-EHCI0 interrupt, vector 0x01A8
>>
>>
>> There were some:
>>
>> IRQ 114: EMAC interrupt, vector 0x01C8
>> IRQ 32: UART 0 interrupt, vector 0x0080
>>
>> And the first "last irq:" for each boot was
>> one of:
>>
>> IRQ 107: USB-OHCIO interrupt, vector 0x0A1C
>> IRQ 64: External Non-Mask Interrupt, vector 0x0100
>>
>> Neither 107 or 64 occurred again after the first
>> message for a boot. 64 showed up when no USB device
>> was plugged in; 107 showed when one was left plugged
>> in (plugged in before powering on the Pine64+ 2GB).
>>
>> 1023 for the current irq number is special
>> and not specific to the A64.
>>
>>
>> So far I can not tell if the kernel mishandles the
>> A64 in some way that leads to 1023's vs. if this
>> is just what an A64 does for some odd reason, even
>> with fully-correct software.
Looking around I see in sys/arm/arm/gic_common.h :
#define GICD_ICFGR(n) (0x0C00 + (((n) >> 4) * 4)) /* v1 ICDICFR */
#define GICD_I_PER_ICFGRn 16
/* First bit is a polarity bit (0 - low, 1 - high) */
#define GICD_ICFGR_POL_LOW (0 << 0)
#define GICD_ICFGR_POL_HIGH (1 << 0)
#define GICD_ICFGR_POL_MASK 0x1
/* Second bit is a trigger bit (0 - level, 1 - edge) */
#define GICD_ICFGR_TRIG_LVL (0 << 1)
#define GICD_ICFGR_TRIG_EDGE (1 << 1)
#define GICD_ICFGR_TRIG_MASK 0x2
But Pine64+ is based on (from what I read):
arm_gic_architecture_specification_v2.0.pdf
and that does not match for the "polarity" part
of GICD_ICFGR code in the above.
Quoting (for both bits, focused on PPI to some
extent but some material applies to SPIs as well). . .
For each supported PPI, it is IMPLEMENTATION DEFINED whether software
can program the corresponding Int_config field.
[2F+1:2F] Int_config, field F
For Int_config[1], the most significant bit, bit [2F+1], the encoding is:
• 0 Corresponding interrupt is level-sensitive.
• 1 Corresponding interrupt is edge-triggered.
Int_config[0], the least significant bit, bit [2F], is reserved, but see
Table 4-19 for the encoding of this bit on some early implementations of
this GIC architecture.
[so reserved instead of polarity in general]
For SGIs:
Int_config[1] Not programmable, RAO/WI.
[So 1's fit with SGIs for Int_config[1].]
For PPIs and SPIs:
Int_config[1] For SPIs, this bit is programmable.a For PPIs it is IMPLEMENTATION DEFINED
whether this bit is programmable. A read of this bit always returns the correct value
to indicate whether the corresponding interrupt is level-sensitive or edge-triggered.
[But SGIs and PPIs are not the same for Int_config[1].]
As for what reserved bits are intended to be,
quoting more places. . .
Bit positions described as Reserved are UNK/SBZP.
UNK/SBZP
UNKNOWN on reads, Should-Be-Zero-or-Preserved on writes.
In any implementation, the bit must read as 0, or all 0s for a bit field,
and writes to the field must be ignored. Software must not rely on the field
reading as 0, or all 0s for a bit field, and must use an SBZP policy to
write to the field.
[The Int_config[1] wording overrides the read part of the above.]
So it would appear that use of IRQ_TYPE_LEVEL_HIGH is a
violation of the intent for PPI's by it translating to
include use of GICD_ICFGR_POL_HIGH which uses 1 instead
of 0 for the reserved bit.
[As for those "early" implementations. . .]
On a GIC where the handling mode of peripheral interrupts is configurable,
the encoding of Int_config[0] for PPIs and SPIs, is:
• 0 Corresponding interrupt is handled using the N-N model.
• 1 Corresponding interrupt is handled using the 1-N model.
[which I do not think applies to the A64, instead
the N-N model applies to PPIs and the 1-N model
to SPIs with no control to do otherwise. But it
is very different from a high vs. low polarity
when it does apply.]
Quoting another place. . .
In a multiprocessor implementation, if bit[1] of the Int_config field
for any PPI is programmable then GICD_ICFGR1 is banked for each
connected processor. This register holds the Int_config fields for the
PPIs, interrupts 16-31.
===
Mark Millard
markmi at dsl-only.net
More information about the freebsd-hackers
mailing list