ARM PL190.
The standard way of programming the ICU requires the kernel to query the ICU. Sometimes (!), this is unacceptably inefficient. Then, you have another alternative, vectored interrupts.
Relevant registers:
| Register Name | Offset | R/W | Description | Comments |
| VICxVectAddry | 0x100+4y | R/W | Vector address for interrupt y | Entry point of ISR 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 |
| 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 |
Initialization
When an interrupt occurs
ldr pc, #<VicVectAddr>
(Note that this is similar to the instruction in 0x014. Could we do it all in one?)
Look carefully at what's in 0x18
ldr pc, [pc, #offset]
Can you make [pc, #offset] calculate
<VicVectAddr>?
0x18 + 0x8 - 0xffc = -0xfdc
=0xfffff0200x18 + 0x8 + 0xffc = 0x10200x800b00300x800c00300xfffff000.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:
Reply( notifier );
data = request.data;
break;
case CLIENT:
...
}
}
}
Related to 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 disabling of interrupts seems unnecessary. Why do we do it?
What do you do when there are no tasks to run?
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++;
break;
case TIME_REQUEST:
Reply( requester, time,... )
break;
case DELAY_REQUEST:
Add requester to list of suspended tasks
break;
}
Check list of suspended tasks and reply
}
}
Comments:
Return to: