You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
3.1 KiB
81 lines
3.1 KiB
20 years ago
|
README on the Vectored Interrupt Controller of the LH7A404
|
||
|
==========================================================
|
||
|
|
||
|
The 404 revision of the LH7A40X series comes with two vectored
|
||
|
interrupts controllers. While the kernel does use some of the
|
||
|
features of these devices, it is far from the purpose for which they
|
||
|
were designed.
|
||
|
|
||
|
When this README was written, the implementation of the VICs was in
|
||
|
flux. It is possible that some details, especially with priorities,
|
||
|
will change.
|
||
|
|
||
|
The VIC support code is inspired by routines written by Sharp.
|
||
|
|
||
|
|
||
|
Priority Control
|
||
|
----------------
|
||
|
|
||
|
The significant reason for using the VIC's vectoring is to control
|
||
|
interrupt priorities. There are two tables in
|
||
|
arch/arm/mach-lh7a40x/irq-lh7a404.c that look something like this.
|
||
|
|
||
|
static unsigned char irq_pri_vic1[] = { IRQ_GPIO3INTR, };
|
||
|
static unsigned char irq_pri_vic2[] = {
|
||
|
IRQ_T3UI, IRQ_GPIO7INTR,
|
||
|
IRQ_UART1INTR, IRQ_UART2INTR, IRQ_UART3INTR, };
|
||
|
|
||
|
The initialization code reads these tables and inserts a vector
|
||
|
address and enable for each indicated IRQ. Vectored interrupts have
|
||
|
higher priority than non-vectored interrupts. So, on VIC1,
|
||
|
IRQ_GPIO3INTR will be served before any other non-FIQ interrupt. Due
|
||
|
to the way that the vectoring works, IRQ_T3UI is the next highest
|
||
|
priority followed by the other vectored interrupts on VIC2. After
|
||
|
that, the non-vectored interrupts are scanned in VIC1 then in VIC2.
|
||
|
|
||
|
|
||
|
ISR
|
||
|
---
|
||
|
|
||
|
The interrupt service routine macro get_irqnr() in
|
||
|
arch/arm/kernel/entry-armv.S scans the VICs for the next active
|
||
|
interrupt. The vectoring makes this code somewhat larger than it was
|
||
|
before using vectoring (refer to the LH7A400 implementation). In the
|
||
|
case where an interrupt is vectored, the implementation will tend to
|
||
|
be faster than the non-vectored version. However, the worst-case path
|
||
|
is longer.
|
||
|
|
||
|
It is worth noting that at present, there is no need to read
|
||
|
VIC2_VECTADDR because the register appears to be shared between the
|
||
|
controllers. The code is written such that if this changes, it ought
|
||
|
to still work properly.
|
||
|
|
||
|
|
||
|
Vector Addresses
|
||
|
----------------
|
||
|
|
||
|
The proper use of the vectoring hardware would jump to the ISR
|
||
|
specified by the vectoring address. Linux isn't structured to take
|
||
|
advantage of this feature, though it might be possible to change
|
||
|
things to support it.
|
||
|
|
||
|
In this implementation, the vectoring address is used to speed the
|
||
|
search for the active IRQ. The address is coded such that the lowest
|
||
|
6 bits store the IRQ number for vectored interrupts. These numbers
|
||
|
correspond to the bits in the interrupt status registers. IRQ zero is
|
||
|
the lowest interrupt bit in VIC1. IRQ 32 is the lowest interrupt bit
|
||
|
in VIC2. Because zero is a valid IRQ number and because we cannot
|
||
|
detect whether or not there is a valid vectoring address if that
|
||
|
address is zero, the eigth bit (0x100) is set for vectored interrupts.
|
||
|
The address for IRQ 0x18 (VIC2) is 0x118. Only the ninth bit is set
|
||
|
for the default handler on VIC1 and only the tenth bit is set for the
|
||
|
default handler on VIC2.
|
||
|
|
||
|
In other words.
|
||
|
|
||
|
0x000 - no active interrupt
|
||
|
0x1ii - vectored interrupt 0xii
|
||
|
0x2xx - unvectored interrupt on VIC1 (xx is don't care)
|
||
|
0x4xx - unvectored interrupt on VIC2 (xx is don't care)
|
||
|
|