aboutsummaryrefslogtreecommitdiffstats
path: root/.github
diff options
context:
space:
mode:
authorMarkus Stockhausen <markus.stockhausen@gmx.de>2022-09-07 17:02:35 +0200
committerSander Vanheule <sander@svanheule.net>2022-09-18 20:38:56 +0200
commitbcb5d6b21ba574db1d02385b494eb01fe46bf8aa (patch)
treed3e9cc719796b6706d94bae064c0f1e6aaa64644 /.github
parentf0ea3df439c796dc6d4e5fee1cc6a15e7fed8085 (diff)
downloadupstream-bcb5d6b21ba574db1d02385b494eb01fe46bf8aa.tar.gz
upstream-bcb5d6b21ba574db1d02385b494eb01fe46bf8aa.tar.bz2
upstream-bcb5d6b21ba574db1d02385b494eb01fe46bf8aa.zip
realtek: avoid wrong interrupt routing
The interrupt controller depends on two control registers. GIMR enables or disables interrupts and IRRx routes these to MIPS CPU interrupts 2-7. Wiki currently states "A value of '0' (in IRRx) disconnects this input from the output line, independent of the line's setting in GIMR." Contrary to normal intuition this statement DOES NOT mean, that interrupts can be disabled by IRRx alone. The sad truth was discovered by enabling SMP for an Zyxel XGS1010 on the 930x target. It shows that driver and interrupts behave as follows: - Timer 0 interrupt 7 has active routing to CPU0 and no routing to CPU1 - Timer 1 interrupt 8 has no routing to CPU0 and active routing to CPU1 - Unmasking (enabling) interrupts writes 1 bits to all GIMR registers - Masking (disabling) interrupts writes 0 bits to both GIMR registers During operation we can encounter a situation like - GIMR bit for a interrupt/CPU combination is set to enabed (=1) - IRRx routing bits for a interrupt/CPU combination are set to disabed (=0) This setting already allows the hardware to fire interrupts to the target CPU/VPE if the other CPU/VPE is currently busy. Especially for CPU bound timer interrupts this is lethal. If timer interrupt 7 arrives at CPU1 and vice versa for interrupt 8 the restart trigger gets lost. The timer dies and a msleep() operation in the kernel will halt endlessly. Fix this by tracking the IRRx active routing setting in a new bitfield with 0="routing active" and 1="no routing". Enable interrupts in GIMR only for a interrupt & CPU if routing is active. Thus we have - GIMR = 0 / IRRx = 0 -> everything disabled - GIMR = 1 / IRRx > 0 -> active and normal routing - GIMR = 0 / IRRx > 0 -> masked (disabled) with normal routing - GIMR = 1 / IRRx = 0 -> no longer possible Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Diffstat (limited to '.github')
0 files changed, 0 insertions, 0 deletions