The interrupt management hardware in the cache consists of two registers, InterruptStatus and InterruptMask, and some related hardware. The logical function is very simple:
- an interrupt reason is posted by setting a bit in InterruptStatus
- interrupts are visible when they are set and that the corresponding InterruptMask bit is set
- Reschedule to the processor is pulsed whenever an interrupt that was not visible before the operation becomes visible.
SetInterruptStatus:
PROC [n: DevNum, itStatus:
WORD] ~
INLINE {
DragonOpsIO.IOWrite[Addr[n, itStatusReg], itStatus];
};
OR itStatus into InterruptStatus for the specified Cache. Reschedule will be pulsed if new interrupts are posted.
pulseReschedule ← (itMask AND InterruptMask)#0
InterruptStatus ← InterruptStatus OR itStatus
SetInterruptStatusBroadcast:
PROC [itStatus:
WORD] ~
INLINE {
DragonOpsIO.BIOWrite[BroadcastAddr[itStatusReg], itStatus];
};
OR itStatus into InterruptStatus for all Caches. In each cache, pulse Reschedule if new interrupts are posted.
pulseReschedule ← (itMask AND InterruptMask)#0
InterruptStatus ← InterruptStatus OR itStatus
SetInterruptStatusSelf:
PROC [itStatus:
WORD] ~
INLINE {
DragonOpsIO.IOWrite[SelfAddr[itStatusReg], itStatus];
};
OR itStatus into InterruptStatus for the calling processor's EU Cache. Reschedule will be pulsed if new interrupts are posted.
pulseReschedule ← (itMask AND InterruptMask)#0
InterruptStatus ← InterruptStatus OR itStatus
ClearInterruptStatus:
PROC [n: DevNum, clrMask:
WORD] ~
INLINE {
DragonOpsIO.IOWrite[Addr[n, itClearReg], clrMask];
};
Remove clrMask from InterruptStatus for the specified Cache.
InterruptStatus ← InterruptStatus&~clrMask
ClearInterruptStatusBroadcast:
PROC [clrMask:
WORD] ~
INLINE {
DragonOpsIO.BIOWrite[BroadcastAddr[itClearReg], clrMask];
};
Remove clrMask from InterruptStatus for the all Caches.
InterruptStatus ← InterruptStatus&~clrMask
ClearInterruptStatusSelf:
PROC [clrMask:
WORD] ~
INLINE {
DragonOpsIO.IOWrite[SelfAddr[itClearReg], clrMask];
};
Remove clrMask from InterruptStatus for the calling processor's EU Cache.
InterruptStatus ← InterruptStatus&~clrMask
ReadInterruptStatus:
PROC [n: DevNum]
RETURNS [itStatus:
WORD] ~
INLINE {
itStatus ← DragonOpsIO.IORead[Addr[n, itStatusReg]];
};
Return the current value of InterruptStatus for the specified Cache.
itStatus ← InterruptStatus
ReadInterruptStatusSelf:
PROC
RETURNS [itStatus:
WORD] ~
INLINE {
itStatus ← DragonOpsIO.IORead[SelfAddr[itStatusReg]];
};
Return the current value of InterruptStatus for the calling processor's EU Cache.
itStatus ← InterruptStatus
Interrupt mask management
WriteInterruptMask:
PROC [n: DevNum, itMask:
WORD] ~
INLINE {
DragonOpsIO.IOWrite[Addr[n, itMaskReg], itMask];
};
Set InterruptMask for the specified Cache. If new interrupts become visible, Reschedule will be pulsed.
pulseReschedule ← (itMask AND ~InterruptMask AND InterruptStatus)#0
InterruptMask ← itMask
WriteInterruptMaskBroadcast:
PROC [itMask:
WORD] ~
INLINE {
DragonOpsIO.BIOWrite[BroadcastAddr[itMaskReg], itMask];
};
Set InterruptMask for all Caches. Each cache pulses Reschedule if new interrupts become visible.
pulseReschedule ← (itMask AND ~InterruptMask AND InterruptStatus)#0
InterruptStatus ← itMask
WriteInterruptMaskSelf:
PROC [itMask:
WORD] ~
INLINE {
DragonOpsIO.IOWrite[SelfAddr[itMaskReg], itMask];
};
Set InterruptMask for the calling processor's EU Cache. If new interrupts become visible, Reschedule will be pulsed.
pulseReschedule ← (itMask AND ~InterruptMask AND InterruptStatus)#0
InterruptStatus ← itMask
ReadInterruptMask:
PROC [n: DevNum]
RETURNS [itMask:
WORD] ~
INLINE {
itMask ← DragonOpsIO.IORead[Addr[n, itMaskReg]];
};
Return the current value of InterruptMask for the specified Cache.
itMask ← InterruptMask
ReadInterruptMaskSelf:
PROC
RETURNS [itMask:
WORD] ~
INLINE {
itMask ← DragonOpsIO.IORead[SelfAddr[itMaskReg]];
};
Return the current value of InterruptMask for the calling processor's EU Cache.
itMask ← InterruptMask