<> <> <> <<>> <> <<>> DIRECTORY DragonOpsIO; CacheOps: CEDAR DEFINITIONS IMPORTS DragonOpsIO ~ BEGIN <> <> <<- Directed access: any cache may be accessed by specifying its DevNum (equal to it's DynaBus ID)>> <<- Self access: a processor may access the registers of it's own EU cache directly>> <<- Broadcast access: a processor may write a given register in all caches simultaneously>> <> <> DevID: TYPE ~ DragonOpsIO.DevID; IOAddress: TYPE ~ DragonOpsIO.IOAddress; WORD: TYPE ~ DragonOpsIO.WORD; DevNum: TYPE ~ [0 .. 1024); -- Identifies uniquely a cache - equal to its DevID <> <> <> <<- 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]; }; <> <> <> <<>> SetInterruptStatusBroadcast: PROC [itStatus: WORD] ~ INLINE { DragonOpsIO.BIOWrite[BroadcastAddr[itStatusReg], itStatus]; }; <> <> <> <<>> SetInterruptStatusSelf: PROC [itStatus: WORD] ~ INLINE { DragonOpsIO.IOWrite[SelfAddr[itStatusReg], itStatus]; }; <> <> <> <<>> ClearInterruptStatus: PROC [n: DevNum, clrMask: WORD] ~ INLINE { DragonOpsIO.IOWrite[Addr[n, itClearReg], clrMask]; }; <> <> <<>> <<>> ClearInterruptStatusBroadcast: PROC [clrMask: WORD] ~ INLINE { DragonOpsIO.BIOWrite[BroadcastAddr[itClearReg], clrMask]; }; <> <> <<>> <<>> ClearInterruptStatusSelf: PROC [clrMask: WORD] ~ INLINE { DragonOpsIO.IOWrite[SelfAddr[itClearReg], clrMask]; }; <> <> <<>> <<>> ReadInterruptStatus: PROC [n: DevNum] RETURNS [itStatus: WORD] ~ INLINE { itStatus _ DragonOpsIO.IORead[Addr[n, itStatusReg]]; }; <> <> <<>> <<>> ReadInterruptStatusSelf: PROC RETURNS [itStatus: WORD] ~ INLINE { itStatus _ DragonOpsIO.IORead[SelfAddr[itStatusReg]]; }; <> <> <> WriteInterruptMask: PROC [n: DevNum, itMask: WORD] ~ INLINE { DragonOpsIO.IOWrite[Addr[n, itMaskReg], itMask]; }; <> <> <> <<>> <<>> WriteInterruptMaskBroadcast: PROC [itMask: WORD] ~ INLINE { DragonOpsIO.BIOWrite[BroadcastAddr[itMaskReg], itMask]; }; <> <> <> <<>> <<>> WriteInterruptMaskSelf: PROC [itMask: WORD] ~ INLINE { DragonOpsIO.IOWrite[SelfAddr[itMaskReg], itMask]; }; <> <> <> <<>> <<>> ReadInterruptMask: PROC [n: DevNum] RETURNS [itMask: WORD] ~ INLINE { itMask _ DragonOpsIO.IORead[Addr[n, itMaskReg]]; }; <> <> <<>> <<>> ReadInterruptMaskSelf: PROC RETURNS [itMask: WORD] ~ INLINE { itMask _ DragonOpsIO.IORead[SelfAddr[itMaskReg]]; }; <> <> <> <> <<>> ReadID: PROC [n: DevNum] RETURNS [devID: DevID] ~ INLINE { devID _ DragonOpsIO.IORead[Addr[n, devIDReg]]; }; <> <> <<>> ReadIDSelf: PROC RETURNS [devID: DevID] ~ INLINE { devID _ DragonOpsIO.IORead[SelfAddr[devIDReg]]; }; <> <> <<>> <
> <> <> <> <> <<>> Offset: TYPE ~ [0 .. 256); -- Offset of a register inside the cache itStatusReg: Offset = 0; -- offset to InterruptStatus - May still change itClearReg: Offset = 1; -- offset to InterruptStatus - May still change itMaskReg: Offset = 2; -- offset to InterruptMask - May still change devIDReg: Offset = 3; -- offset to InterruptMask - May still change CacheBase: WORD = 0; -- Some value to be defined later Addr: PROC [n: DevNum, offset: Offset] RETURNS [addr: IOAddress] ~ INLINE { dev: WORD _ n; addr.v _ CacheBase+1024*dev+offset; }; BroadcastAddr: PROC [offset: Offset] RETURNS [addr: IOAddress] ~ INLINE { broadcastDevNum: WORD = LAST [DevNum]; -- required by cache decoding mechanism addr.v _ CacheBase+1024*broadcastDevNum+offset; }; SelfAddr: PROC [offset: Offset] RETURNS [addr: IOAddress] ~ INLINE { addr.v _ offset; }; END.