Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 25 Apr 2017 02:55:40 -0700
From:      Mark Millard <markmi@dsl-only.net>
To:        freebsd-arm <freebsd-arm@freebsd.org>, freebsd-hackers@freebsd.org
Subject:   Re: head -r317015 (and before) vs. Pine64+ 2GB (an aarch64) and spurious interrupts: [the A64 IRQ numbers involved other than 1023]
Message-ID:  <62AF263E-8028-44AB-8AFA-B5F08C96673D@dsl-only.net>
In-Reply-To: <C6B9A15F-D8C7-46F6-B59A-DBCB70BE3C44@dsl-only.net>
References:  <B4FDA80F-1E72-4A2B-BE0C-E6F7BE6CDC5F@dsl-only.net> <D128A050-9688-4BDB-9D16-50DFEF15D6A5@dsl-only.net> <49C0BC5D-8A31-4E77-AFC6-6F027CA3AB1E@dsl-only.net> <C6B9A15F-D8C7-46F6-B59A-DBCB70BE3C44@dsl-only.net>

next in thread | previous in thread | raw e-mail | index | archive | help
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:
>=20
>> I found some basic reference material for the=20
>> "last irq" numbers for the A64 that is in the
>> Pine64+ 2GB (and 1GB). . .
>>=20
>> 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.)
>=20
> Looks to be a timer, not that I can tell
> much about it:
>=20
>        timer {
>                compatible =3D "arm,armv8-timer";
>                interrupts =3D <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)>;
>        };
>=20
> 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. . .
>>=20
>> IRQ  92: SD/MMC Host Controller 0 interrupt, vector 0x0170
>>=20
>> IRQ 106: USB-EHCI0                interrupt, vector 0x01A8
>>=20
>>=20
>> There were some:
>>=20
>> IRQ 114: EMAC                     interrupt, vector 0x01C8
>> IRQ  32: UART 0                   interrupt, vector 0x0080
>>=20
>> And the first "last irq:" for each boot was
>> one of:
>>=20
>> IRQ 107: USB-OHCIO                interrupt, vector 0x0A1C
>> IRQ  64: External Non-Mask        Interrupt, vector 0x0100
>>=20
>> 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).
>>=20
>> 1023 for the current irq number is special
>> and not specific to the A64.
>>=20
>>=20
>> 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:

	=E2=80=A2 0  Corresponding interrupt is level-sensitive.

	=E2=80=A2 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:

	=E2=80=A2 0  Corresponding interrupt is handled using the N-N =
model.

	=E2=80=A2 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.

=3D=3D=3D
Mark Millard
markmi at dsl-only.net




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?62AF263E-8028-44AB-8AFA-B5F08C96673D>