13. Interrupts and Traps
Part of
the Hawk Manual
|
13.1. The Trap Vector
13.2. The Trap Registers
13.3. A Prototype Handler
The following assembly language definitions are used here in the discussion of the trap vector:
RESTRAP = #00 BUSTRAP = #10 INSTRAP = #20 PRIVTRAP= #30 MMUTRAP = #40 COPTRAP = #50 ; -- #60 ; -- #70 IRQ0 = #80 IRQ1 = #90 IRQ2 = #A0 IRQ3 = #B0 IRQ4 = #C0 IRQ5 = #D0 IRQ6 = #E0 IRQ7 = #F0
The lowest memory addresses are known as the trap and interrupt vector. When the CPU detects an abnormal condition, either internally or signalled by external hardware, control is transferred to a location in the trap trap and interrupt vector.
Traps occur because something prevents an instruction from being completed. As a result, the instruction is aborted before it can have any side effects, and control is transferred to a trap handler. Programming errors commonly cause a variety of traps, but some have other uses. The following conditions lead to traps:
The memory management unit and coprocessors are not strictly part of the CPU, but they will force traps when instructions that use them cannot be completed:
Two additional locations 6016 and 7016 are included in the trap vector and reserved for future traps.
Interrupts occur because something outside the processor needs service. If an interrupt is requested while an instruction is being executed, that instruction is allowed to execute to completion before control is transferred to an interrupt handler. Examples events that may cause interrupts are timer expiration and key presses.
The final 8 locations in the interrupt-and-trap vector from are conventionally reserved for device interrupts. IRQ0 or 8016 is the highest priority interrupt, a non-maskable interrupt that cannot be disabled by software. Devices asserting IRQ0 must retract their interrupt request immediately when the CPU acts on it or the CPU will hang.
IRQ1 or 9016 through IRQ7 or F016 are controlled by the PSW level field:
There are two distinct ways that multiple devices may be assigned interrupt levels. One uses each level bit as an interrupt-enable bit for one device. In this case, only IRQ1, IRQ3 and IRQ7 should be used for high, medium and low priority devices, and PSW.level = 00002 should never be set to values other than x0002, x0012, x0112 and x1112.
The other approach requires an 8-way priority interrupt encoder, allowing seven distinct interrupt levels in numerical order. This is upward compatible from the simpler model.
Each of these registers can be manipulated with CPUGET and CPUSET (see Section 11.5).
When an interrupt or trap occurs, the CPU first stores the program counter in the trap program counter and the level field of the processor-status word is copied into the prior field, before setting the level field to zero (see Section 1.3.4.1). More formally:
This makes the trap handler uninterruptable and privileged, and it turns off the memory management unit.
In addition, If the trap occurred because of a memory addressing fault, the memory address and a notice of the cause is stored in the trap-memory-address register (see Section 1.3.4.3). The trap save register TSV is available for use by trap service routines.
A typical trap or interrupt handler begins by saving the entire CPU state in memory, then doing something about the trap, and then restoring the (possibly altered) CPU state. Trap handlers that alter the CPU state are common. For example, an unimplemented-instruction-trap handler that implements a virtual machine instruction will change the CPU state the way that machine instruction should.
To speed trap or interrupt service, parts of the state that are not needed by the handler need not be saved. This example saves all of the general purpose registers, but some handlers may only need a few registers. Many handlers make no use of coprocessors, so no coprocessor state is saved by the hanlder given in this example.
The data structure in which the system state is saved can be thought of as a record with one field for each saved register, or it can be thought of as the activation record of the trap handler. The following assembly language definitions describe the record structure for the prototype handler given here:
; bus trap save area record structure ; (all fields are 1 word, so displacements are shown in words) svPC = 0 <<2 ; save area for PC svR1 = 1 <<2 ; save area for registers svR2 = 2 <<2 svR3 = 3 <<2 ... save areas for R4-RC svRD = 13 <<2 svRE = 14 <<2 svRF = 15 <<2 svPSW = 16 <<2 ; save area for PSW svMA = 17 <<2 ; save area for trap MA svSIZE = 18 <<2 ; size of register-save area
The following prototype handler code assumes that a separate save area with the above structure is statically allocated, in RAM, for each trap or interrupt or trap handler.
Given the above save area structure, the following code for one trap vector entry will begin the process of saving the CPU state and then transfer control to the remainder of the handler which begins by saving the remainder of the CPU state.
; code to handle illegal memory references . = BUSTRAP CPUSET R2,TSV ; 2 partially save R2 LOAD R2,BUSSVP ; 6 get the save area pointer LOADS PC,PC ; 8 join common code for all traps W BUSHANDLE ; 12 code pointer BUSSVP: W BUSSVAREA ; 16 save area pointer
The comments above include accounting for memory used because the trap and interrupt vector entries must occupy no more than 16 bytes each, and the two one word pointers must be word aligned. This code sets up r[2] as a pointer to the save area after using the trap-save register to temporarily cache the old value of r[2]. At the point that control enters the code to save registers, key parts of the CPU state are in TPC and TSV; these must be recovered and saved before the straightforward code to save the other parts of the CPU state.
Note that the BUSHANDLE code given below is just a wrapper around the code that does the actual work. For a bus trap, the actual work could be as simple as outputting an error message and then hanging the CPU awaiting a hardware reset. For an instruction-trap handler, the actual work might involve inspecting the PC in order to inspect the instruction that caused the trap, and then, if the opcode is one that the handler virtualizes, emulating that instruction before returning from trap. For an interrupt handler, the actual work would typicaly involve initiating the next input or output data transfer.
BUSHANDLE: ; enter with: R2 pointing to save area and stack ; TPC holds user's PC ; TSV holds user's R2 STORE R1,R2,svR1 ; save R1 STORE R3,R2,svR3 ; save R3 CPUGET R1,TSV CPUGET R3,TPC STORE R1,R2,svR2 ; R2 now fully saved STORE R3,R2,svPC ; PC now fully saved CPUGET R1,TMA CPUGET R3,PSW STORE R1,R2,svMA ; TMA saved STORE R3,R2,svPSW ; PSW saved STORE R4,R2,svR4 ; R4 saved . . straightforward code to save R5-R14 . STORE R15,R2,svRF ; R15 saved . . body of trap handler . LOAD R15,R2,svRF ; R15 restored . . code to restore R14-5 . LOAD R4,R2,svR4 ; R4 restored LOAD R3,R2,svPSW LOAD R1,R2,svPC CPUSET R3,PSW ; PSW restored (interrupts disabled) CPUSET R1,TPC LOAD R3,R2,svR3 ; R3 restored LOAD R1,R2,svR1 ; R1 restored LOAD R2,R2,svR2 ; R2 restored RTT ; PC restored (return to user!)
The above code is written using R1 and R3 as alternate temporaries in order to improve pipeilined execution.
The code given above all runs with the memory management unit turned off and interrupts disabled. The code for the body of the handler may safely enable interrupts by changing the level field of the processor status word, but note that interrupt handlers should never enable their own or lower priority interrupts.
It is possible to construct variants on the above code that use a common block of code to save and restore registers, avoiding code duplication. It is also possible to have a single register save area shared by multiple traps and interrupts so long as the handlers that share a save area do not themselves cause traps or allow interrupts that require use of the same save area.
This approach to trap service is at the extreme RISC end of the spectrum! Many machines include complex trap entry hardware that automatically saves and restores blocks of registers.