DIRECTORY
DragOps USING [Word];
DragonStack: CEDAR DEFINITIONS
~ BEGIN
Procedures intended for more or less public use while in Kernel mode.
Intended use: DisableInterrupts ... MarkFrame ... SaveStack
Calling these without first disabling interrupts is a no-no.
Calling SaveStack without first calling MarkFrame is a no-no.
DisableInterrupts: PROC;
Must NOT be INLINE
Disables interrupts in the caller's context when DisableInterrupts returns.
EnableInterrupts: PROC;
Must NOT be INLINE
Enables interrupts in the caller's context when EnableInterrupts returns. Notice that in many cases explicit calls to EnableInterrupts are unnecessary: a subsequent RETURN will implicitly enable interrupts.
MarkFrame: PROC ~ INLINE {
This procedure must be INLINE so it marks the correct frame
status: StackedStatusWord ← GetYoungestStatus[];
status.mark ← TRUE;
SetYoungestStatus[status];
};
MarkSignalHandler: PROC;
Marks a frame for the SignalHandler. Must NOT be INLINE.
SaveStack: PROC ~ INLINE {
... saves the stack (updates the current value of the hook EU register). The stack is saved up to (and including) the eldest marked frame. Also updates the framesLeft EU register -- not yet. For excruciating details, see GenStack.mesa. Making this procedure INLINE saves a frame but is otherwise irrelevant.
status: StackedStatusWord;
Eldest frame is the bogus frame; if it is marked do nothing
IF GetEldestStatus[].mark THEN RETURN;
status ← DragonStack.RemoveBogusFrame[];
DO
mark: BOOL ← status.mark;
status ← DragonStack.NakedSaveFrame[status];
IF mark THEN EXIT;
ENDLOOP;
bogus frame replaces the marked frame
DragonStack.InstallBogusFrame[status];
};
Procedures exported from the machine code generated by GenStack.
It is very important that these be called in the order
RemoveBogusFrame NakedSaveFrame* InstallBogusFrame
passing along the status from returned result to argument at each step.
RemoveBogusFrame: PROC [] RETURNS [status: StackedStatusWord];
Removes the bogus frame (normally the eldest frame) and returns the status of the new eldest frame.
NakedSaveFrame: PROC[oldStatus: StackedStatusWord] RETURNS[newStatus: StackedStatusWord];
Removes the eldest frame, which must be a real frame and not younger than the marked frame, and returns the status of the new eldest frame. oldStatus should be the status returned by RemoveBogusFrame or the previous call to NakedSaveFrame.
InstallBogusFrame: PROC [oldStatus: StackedStatusWord];
Installs a new bogus frame. oldStatus should be the previously returned status from NakedSaveFrame.
Private Stuff
Types
StackedStatusWord must track DragOps.StackedStatusWord which contains the truth about the hardware.
StackedStatusWord: PRIVATE TYPE = MACHINE DEPENDENT RECORD [
version (0: 00..07): [0..255] ← 0,
padBits (0: 08..10): [0..7] ← 0,
the next 3 bits are not interpreted by the hardware
signalHandler (0: 11..11): BOOLFALSE, -- TRUE => this is a signalHander frame
bogus (0: 12..12): BOOLFALSE, -- TRUE => this is the bogus frame
mark (0: 13..13): BOOLFALSE, -- TRUE => last frame saved by SaveStack
the next 2 bits are interpreted by the hardware
userMode (0: 14..14): BOOLFALSE, -- TRUE => user, FALSE => kernel
trapsEnabled (0: 15..15): BOOLFALSE,
padByte (0: 16..23): [0..255] ← 0,
lBase (0: 24..31): [0..255] ← 0 ]; -- EU local frame base
Nacho: TYPE ~ POINTER TO NachoRep;
NachoRep: TYPE ~ RECORD [
link: Nacho, -- link to the next elder frame in the process stack
nextPC: DragOps.Word, -- the continuation PC for the frame
status: StackedStatusWord, -- the saved status register of the procedure
others: Nacho, -- the link to the area for more saved registers
regs: RegArray -- the saved registers (local variables)
];
RegArray: TYPE ~ ARRAY Reg OF DragOps.Word;
Reg: TYPE ~ [0..15];
GetEldestStatus: PRIVATE PROC RETURNS [savedStatus: StackedStatusWord] ~ TRUSTED MACHINE CODE {
090H, 0F2H -- LIP EldestStatus
};
SetEldestStatus: PRIVATE PROC [newStatus: StackedStatusWord] ~ TRUSTED MACHINE CODE {
091H, 0F2H -- SIP EldestStatus
};
GetYoungestStatus: PRIVATE PROC RETURNS [savedStatus: StackedStatusWord] ~ TRUSTED MACHINE CODE {
090H, 0F0H -- LIP YoungestStatus
};
SetYoungestStatus: PRIVATE PROC [newStatus: StackedStatusWord] ~ TRUSTED MACHINE CODE {
091H, 0F0H -- SIP YoungestStatus
};
END.