| 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
=0xfffff0200x18 + 0x8 + 0xffc = 0x10200x800b00300x800c0030| 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: