Register Name | Offset | R/W | Description |
VICxIRQStatus | 0x00 | R | One bit for each interrupt source
1 if interrupt is asserted and not masked |
VICxFIQStatus | 0x04 | R | As above, for FIQ |
VICxRawIntr | 0x08 | R | As above, not masked |
VICxIntSelect | 0x0c | R/W | 0: IRQ, 1: FIQ |
VICxIntEnable | 0x10 | R/W | 0: Masked, 1: Enabled |
VICxIntEnClear | 0x14 | W | Clears bits in VICxIntEnable |
VICxSoftInt | 0x18 | R/W | Asserts interrupt from software |
VICxSoftIntClear | 0x1c | W | Clears interrupt from software |
VICxProtection | 0x20 | R/W | Bit 0 enables protection from user mode access |
VICxVectAddr | 0x30 | R/W | Enables priority hardware
See documentation. |
Initialization
When an interrupt occurs
Look carefully at what's in 0x18
ldr pc, [pc, #offset]
<IRQ>
is the offset from the pc to the kernel
entry0x18 + 0x8 - 0xffc = -0xfdc
=
0xfffff020
0x18 + 0x8 + 0xffc = 0x1020
0x800b0030
0x800c0030
Register Name | Offset | R/W | Description |
VICxVectAddr | 0x030 | R/W | Read: address of vector for highest priority interrupt
Write: service complete, enable priority hardware |
VICxDefVectAddr | 0x034 | R/W | Default vector address |
VICxVectAddry | 0x100+4y | R/W | Vector address for interrupt y |
VICxVectCntly | 0x200+4y | R/W | Control register for interrupt y
Bit[0-4]: interrupt source for interrupt y Bit[5]: enable vectored interrupt y |
main( ) { Tid server; int evtType, data; Receive( &server, &evtType, ... ); // Other initialization Reply( server, ... ); FOREVER { data = AwaitEvent( evtType ); Send( server, &data, ... ); } }
main( ) { notifier = Create( HIGHEST, ... ); // other initialization Send( notifier, &evtType, ... ); FOREVER { Receive( &requester, &request, ... ); switch ( request.type ) { case NOTIFIER: data = request.data; Reply( notifier ); break; case CLIENT: ... } } }
Related to three free choices discussed in last lecture.
Strategy 1: Kernel does it all
movs
)movs
)Return value (or buffer) contains the volatile data
Strategy 2: Notifier does most of it
movs
)The second disbling of interrupts seems unnecessary. Why do we do it?
int Time( )
int Delay( int ticks )
int DelayUntil( int ticks )
main( ) { notifier = Create( HIGHEST, ... ); time = 0 Send( notifier, &evtType, ... ); FOREVER { Receive( &requester, &request, ... ); switch ( request.type ) { case NOTIFIER: Reply( notifier, ... ) time++; Check suspended tasks and reply break; case TIME_REQUEST: Reply( requester, time,... ) break; case DELAY_REQUEST: Add requester to list of suspended tasks Check suspended tasks and reply break; } } }
Comments:
Return to: