4.0 Traps and Faults
Abnormal conditions which happen during instructions are often called traps, faults, or checks, and other events which disturb normal instruction flow are called interrupts. These events will be collectively referred to as traps here because of the uniform way they are handled. In addition, the KFC (Kernel Function Call) instruction shares some properties of traps. (See Chapter 4.4 below.) A trap causes control to be sent to a location which is 4,002,000B + 20B * Trap No., where the trap no. is chosen according to the table below; KFC sends control to the location determined as though it were an XOP.
Trap Name Priority Trap No
Reset 1 07B location for control when RESET is asserted
IFU stack ovf 2 10B IFU stack has 12 frames
IFU page fault 3 01B IFU page fault
Mode fault 3 37B kernel instruction attempted in user mode
KFC 4 xxx Kernel Function Call (uses Xop trap location)
AU fault 4 43B DPbus indicates an AU fault
Address check 4 24B store into address < 100000000B from user mode or
use of such an address in a user mode IO instruction
that specifies address checking.
Integer overflow 4 30B integer result out-of-range
Bounds check 4 31B RBC, QBC, or BC opcode trap
Lisp ovf or NaN 4 32B Lisp arithmetic argument or result out-of-range
EU page fault 5 41B DPbus indicates EU Cache page fault
EU write fault 6 42B DPbus indicates EU Cache write protect fault
Reschedule 7 12B called when RESCHEDULE is acknowledged
EU stack ovf 8 11B called when, after an opcode, traps are enabled
and S is in the range [SLimit..SLimit+16).
The Disableable Traps: IFU Stack Overflow, EU Stack Overflow, and Reschedule
All traps and KFC enter kernal mode, disable traps, and push the old IFU Status onto the EU stack. Instructions which result in traps have no other effect on the machine state; it is as though the instruction causing the trap were erased and replaced by the trap event.
Enabling or disabling traps affects only Reschedule, EU stack overflow, and IFU stack overflow; other traps are always enabled. The EU and IFU stack overflow traps occur when critical resources are on the verge of exhaustion, and both traps normally push the oldest frame in the registers out into storage to make more room; automatically disabling traps prevents these two traps from nesting, which would cause logical problems and require more reserved registers. Reschedule is also disabled because the possibility of Reschedule happening during EU or IFU stack overflow service would require more reserved registers. All other traps with the exception of EU or IFU memory faults, can easily be avoided by the EU and IFU stack overflow trap handlers, so it is not necessary to disable them.
When traps are enabled, the IFU call stack has 11 entries for normal calls and converts the following call (which uses the 12th call stack entry) into an IFU stack overflow trap. When traps are disabled, all 15 call stack entries are available. Similarly, it is expected that SLimit will be set equal to L - 17, where L is the base of the earliest frame in the registers. Then any instruction will cause an EU stack overflow trap if, at the end of the instruction, traps are enabled and S is in the range [SLimit..SLimit+16). Then EU stack overflow trap will be requested with at least 17 unused registers in reserve for the trap handler, so 111 registers are available for use by normal frames.
There are no IFU stack underflow or EU stack underflow traps. It is expected that in normal operation the earliest frame in the registers will point to a special unmapped address, so that returning to this frame will cause an IFU page fault. The IFU page fault handler will identify the special unmapped address and treat this event as IFU stack underflow, which requires software to move an earlier frame from storage into the registers.
Unlike IFU stack underflow, which is a normal event, EU stack underflow represents a programming error which the hardware doesn't detect. However, decrementing S too much can result in an EU stack overflow error if S is counted into the range [SLimit .. SLimit + 16).
A Reschedule interrupt is asynchronous to normal instruction execution, and it is appropriate to think of this trap as being inserted between instructions; in other words, it is impossible to have any other traps requesting concurrently. However, the Reschedule trap will push one more entry onto the IFU call stack and one more word (the IFU status) onto the EU stack, and these pushes may result in IFU stack overflow or EU stack overflow; the priorities in the table above show that IFU stack overflow will prevail over Reschedule, and Reschedule will prevail over EU stack overflow.
EU Stack Overflow trap ordinarily occurs as the result of an instruction which advances S into the restricted region, IFU stack overflow trap as the result of a call, and Reschedule trap as the result of an external event, but these events can also occur as a result of reenabling traps with S already inside the restricted region, with 12 or more IFU call stack entries, or with reschedule-pending true in the IFU's status.
It is illegal to reenable traps with 12 or more IFU call stack entries because, in this situation, it is not defined exactly when the IFU stack overflow trap will occur; the consequence of this illegality is that any trap handler which reenables traps must do so before making any procedure calls. If this illegality is obeyed, the IFU stack overflow trap handler will always have 3 call stack entries in reserve for its own activities and for EU page faults that result from its activities.
However, it is permissible to reenable traps with an EU stack overflow condition existing and/or reschedule-pending true. If this happens, the EU stack overflow trap will always occur immediately, and the Reschedule trap will occur immediately unless the EU stack overflow condition is true at the same time. This is a violation of the priorities given above, and it is appropriate to think of these events as happening between the instruction (RETK or SIP) which reenables interrupts and the following instruction. In all other situations, the EU stack overflow event occurs during the instruction and is of lower priority than anything else.
A practical situation in which traps are reenabled with S inside the restricted range is when the handler for a Lisp NaN trap decides to reenable traps preparatory to carrying out major work. It is possible that the NaN trap itself makes S = SLimit by pushing the IFU's status, and several more pushes may occur before the trap handler reenables traps. Hence, the EU stack overflow trap handler may be entered with only 17 - 1 - TBD words available. For this reason, it is necessary that the trap handler for any trap which is going to reenable interrupts obey a limit of TBD pushes to ensure that enough registers are available for the IFU stack overflow handler.
It is illegal to execute RETN, RET, RETK, LIP[ifuEldestPC], LIP[ifuYoungestPC], LIP[ifuEldestL], or LIP[ifuYoungestL] with 0 call stack entries.
It is illegal for the Kernel to execute a RETK with traps already enabled when the adjustment to S by RETK causes EU stack overflow to become true, but it is legal to execute a RETK that reenables traps with EU stack overflow already true.
Traps Associated With Memory Faults
The trap handler for a memory fault will save away the state of the current process and run the scheduler because it is impossible to continue execution of the current process in the event of such a fault.
The priority table above shows that memory faults have a lower priority than all other traps except Reschedule and EU stack overflow. However, an IFU page fault, for example, preempts the execution of the instruction; the only possible competitors for an IFU page fault are IFU and/or EU stack overflow that result from the page fault trap itself; in this situation the relative priorities are IFU stack overflow > IFU page fault > EU stack overflow.
Similarly, the only competitors of an EU memory fault are mode fault, address check, and EU stack overflow; and it is possible for the memory fault trap itself to cause IFU stack overflow. No other trap can request service simultaneously. The table above shows that IFU stack overflow > mode fault > address check > EU page fault > EU write protect fault > EU stack overflow. (More specifically, in the event of a mode fault or address check, the memory reference will never be initiated, so no disturbance of the cache occurs.)
A key issue with an EU memory fault trap is that it may nest with IFU or EU stack overflow, if the next free frame for process state is not resident in storage. The deepest nested requirements of IFU or EU stack overflow with an EU memory fault must not exceed the limit of 4 call stack entries and 17 - 1 - TBD local registers.
Traps Associated With Particular Instructions
Except for the IFU and EU stack overflow and memory fault traps and the Reschedule trap, all traps in the table above are the predictable result of executing some instruction. All traps with priority equal to 4 are mutually exclusive, and the Mode fault trap is higher priority than any of these.
4.1 User Mode
User mode can be turned on by using SIP[IFUStatus] or RETK to change IFUStatus. Once in user mode, kernel mode can be reentered by executing a KFC instruction, or by trapping. In user mode the following actions are illegal:
IO instructions: IOL, ION, IOS
The second byte after the opcode contains a user-mode-illegal bit and an address-check bit. If the user-mode-illegal bit is set, the instruction will cause a mode fault trap in user mode; if the address-check bit is set, then it will cause an address check in user mode if the address is < 100000000B.
SIP instruction
The SIP instruction causes a mode fault trap when executed in user mode.
LIP[IFUEldestPC]
This instruction modifies the IFU state as well as reading the PC. It causes a mode fault trap when executed in user mode.
Writes into the 12 constants or the first 8 auxiliary registers
These writes (accomplished using instructions in the RRR format) will cause a mode fault trap when executed in user mode.
Writes to an address <100000000B
Such writes will cause an address check trap when executed in user mode.
.
4.2 Undefined Instructions (Xops)
The instruction length for every instruction is determined from a computation on the high-order three bits of its opcode. Those opcodes not specifically defined as machine instructions are called Xops. Executing an Xop is semantically equivalent to a function call (DFC or LFC) to its trap location. Each instruction has its own trap location at 4,000,000B + 20B * opcode no. In addition, Xops of length two, three or five bytes push the literal following their opcodes, so that two-byte Xops push a one-byte literal value, three-byte Xops push a two-byte literal value, and five-byte Xops push a four-byte literal value.
Execution of an Xop does not change the status of the machine to Kernel mode.
It is expected that future revisions of the Dragon processor will deploy many Xops for new instructions.
4.3 Undefined User Operations
There is a second category of undefined opcodes which must not be executed. These opcodes, six in all, are intentionally not described. The execution of these six opcodes has been forbidden in order to simplify the amount of logic required to implement the instructionset. Actually, these opcodes are defined and possibly even perform useful work, but they may be redefined in future versions of the machine. These six opcodes are indicated the instruction map by three asterisks, (***).
4.4 The KFC (Kernel Function Call) Instruction
The KFC instruction is like an Xop in that it traps to a location which is 4,000,000B + 20B * opcode, and it advances the PC like an Xop, so that a procedure return will send control to the location after the KFC; however, KFC pushes the old IFU status and disables traps like a Trap.