9 Hardware Interrupts and Traps

In the PDP11 computer, as in many other computers, there is an “interrupt” mechanism, which allows the controllers of peripheral devices (which are devices external to the CPU) to interrupt the CPU at appropriate times, with requests for operating system service.

The same mechanism has been usefully and conveniently applied to “traps” which are events internal to the CPU, which relate to hardware and software errors, and to requests for service from user programs.

9.1 Hardware Interrupts

The effect of an interrupt is to divert the CPU from whatever it was doing and to redirect it to execute another program.

During a hardware interrupt:

  • The CPU saves the current processor status word (PS) and the current program count (PC) in its internal registers;

  • the PC and PS are then reloaded from two consecutive words located in the low area of main memory. The address of the first of these two words is known as the “vector location” of the interrupt;

  • finally the original PC and PS values are stored into the newly current stack. (Whether this is the kernel or user stack depends on the new value of the PS.)

Different peripheral devices may have different vector locations. The actual vector location for a particular device is determined by hard wiring, and can only be changed with difficulty. Moreover there are well entrenched conventions for choosing vector locations for the various devices.

Thus after the interrupt has occurred, because the PC has been reloaded, the source of instructions executed by the CPU has been changed. The new source should be a procedure associated with the peripheral device controller which caused the interrupt.

Also since the PS has also been changed, the processor mode may have changed. In UNIX, the initial mode may be either “user” or “kernel”, but after the interrupt, the mode is always “kernel”. Recall also that a change in mode implies:

(a)

a change in memory mappings. (Note that to avoid any confusion, vector locations are always interpreted as kernel mode addresses.);

(b)

a change in stack pointers. (Recall that the stack pointer, SP or r6, is the only special register which is replicated for each mode. This implies that after a mode change, the stack pointer value will have changed even though it has not been reloaded!)

9.2 The Interrupt Vector

For our sample system, the representative peripheral devices chosen are listed in Table 9.1, along with their conventional hardware defined vector locations and priorities.

vector

peripheral

interrupt

process

location

device

priority

priority

060

teletype input

4

4

064

teletype output

4

4

070

paper tape input

4

4

074

paper tape output

4

4

100

line clock

6

6

104

programmable

6

6

 

clock

   

200

line printer

4

4

220

RK disk drive

5

5

Table 9.1 Interrupt Vector Locations and Priorities

9.3 Interrupt Handlers

Within this selection of UNIX source code, there are seven procedures known as “interrupt handlers”, i.e. which are executed as the result of, and only as the result of, interrupts:

   clock  (3725)  pcrint (8719)
   rkintr (5451)  pcpint (8739)
   klxint (8070)  lpint  (8976)
   klrint (8078)

“clock” will be examined in detail in Chapter 11. The others are discussed with the code for their associated devices.

9.4 Priorities

An interrupt does not necessarily occur immediately the peripheral device controller requests it, but only when the CPU is ready to accept it. It is usually desirable that a request for a low priority service should not be allowed to interrupt an activity with a higher priority.

Bits 7 to 5 of the PS determine the processor priority at one of eight levels (labelled zero to seven). Each interrupt also has an associated priority level determined by hardware wiring. An interrupt will be inhibited as long as the processor priority is greater than or equal to the interrupt priority.

After the interrupt the processor priority will be determined from the PS stored in the vector location and this does not have to be the same as the interrupt priority. Whereas the interrupt priority is determined by hardware, it is possible for the operating system to change the contents of the vector location at any time.

As a matter of curiosity, it may be noted that the PDP11 hardware restricts the possible interrupt priorities to 4, 5, 6 and 7 i.e. levels 1, 2 and 3 are not supported by the Unibus.

9.5 Interrupt Priorities

In UNIX, interrupt handling routines are initiated at the same priority as the interrupt priority.

This means that during the handling of the interrupt, a second interrupt from a device of the same priority class will be delayed until the processor priority is reduced, either by the execution of one of the “spl” procedures, which are intended for just this purpose (see lines 1293 to 1315), or by reloading the processor status word e.g. upon returning from the interrupt.

During interrupt handling, the processor priority may be raised temporarily to protect the integrity of certain operations. For instance, character oriented devices such as the paper tape reader/punch or the line printer interrupt at level four. Their interrupt handlers call “getc” (0930) or “putc” (0967), which raise the processor priority temporarily to level five, while the character buffer queues are manipulated.

The interrupt handler for the console teletype makes use of a “timeout” facility. This involves a queue which is also manipulated by the clock interrupt handler, which runs at level six. To prevent possible interference, the “timeout” procedure (3835) runs at level seven (the highest possible level).

Usually it does not make sense to run an interrupt handler at a processor priority lower than the interrupt priority, for this would then risk a second interrupt of the same type, even from the same device, before completion of the processing of the first interrupt. This likely to be at best inconvenient and at worst disastrous. However the clock interrupt handler, which once per second has a lot of extra work to do, does exactly this.

9.6 Rules for Interrupt Handlers

As discussed above, interrupt handlers need to be careful about the manipulation of the processor priority to avoid allowing other interrupts to happen “too soon”. Likewise care needs to be taken that the other interrupts are not delayed excessively, lest the performance of the whole system be degraded. It is important to note that when an interrupt occurs, the process which is currently active will very likely not be the process which is interested in the occurrence. Consider the following scenario:

User process #m is active and initiates an i/o operation. It executes a trap instruction and transfers to kernel mode. Kernel process #m initiates the required operation and then calls “sleep” to suspend itself to await completion of the operation ...

Some time later, when some other process, user process #n say, is active, the operation is completed and an interrupt occurs. Process #n reverts to kernel mode, and kernel process #n deals with the interrupt, even though it may have no interest in or prior knowledge of the operation.

Usually kernel process #n will include waking process #m as part of its activity. This will not always be the case though, e.g. where an error has occurred and the operation is retried.

Clearly, the interrupt handler for a peripheral device should not made references to the current “u” structure for this is not likely to be the appropriate “u” structure. (The appropriate “u” structure could quite possibly be inaccessible, if it has been temporarily swapped out to the disk.)

Likewise the interrupt handler should not call “sleep” because the process thus suspended will most likely be some innocent process.

9.7 Traps

“Traps” are like “interrupts” in that they are events which are handled by the same hardware mechanism, and hence by similar software mechanisms.

“Traps” are unlike “interrupts” in that they occur as the result of events internal to the CPU, rather than externally. (In other systems the terminology “internal interrupt” and “external interrupt” is used to draw this distinction more forcefully.) Traps may occur unexpectedly as the result of hardware or power failures, or predictably and reproducibly, e.g. as the result of executing an illegal instruction or a “trap” instruction.

“Traps” are always recognised by the CPU immediately. They cannot be delayed in the way low priority interrupts may be. If you like, “traps” have an “interrupt priority” of eight.

“Trap” instructions may be deliberately inserted in user mode programs to catch the attention of the operating system with a request to perform a specified service. This mechanism is used as part of the facility known as “system calls”.

Like interrupts, traps result in the reloading of the PC and PS from a vector location, and the saving of the old values of the PC and PS in the current stack. Table 9.2 lists the vector locations for the various “trap” types.

vector

trap type

process

location

 

priority

004

bus timeout

7

010

illegal instruction

7

014

bpt-trace

7

020

iot

7

024

power failure

7

030

emulator trap instruction

7

034

trap instruction

7

114

11/10 parity

7

240

programmed interrupt

7

244

floating point error

7

250

segmentation violation

7

Table 9.2 Trap Vector Locations and Priorities

The contents of Tables 9.1 and 9.2 should be compared with the file “low.s” on Sheet 05. As noted earlier, this file is generated at each installation (along with the file “conf.c” (sheet 46)), as the product of the utility program “mkconf”, so as to reflect the actual set of peripherals installed.

9.8 Assembly Language ‘trap’

From “low.s” it appears that traps and interrupts are handled separately by the software. However closer examination reveals that “call” and “trap” are different entry points to a single code sequence in the file “m40.s” (see lines 0755, 0776). This sequence is examined in detail in the next chapter.

During the execution of this sequence, a call is made on a “C” language procedure to carry out further specific processing. In the case of an interrupt, the “C” procedure is the interrupt handler specific to the particular device controller.

In the case of a trap, the “C” procedure is another procedure called “trap” (yes, the word “trap” is definitely overworked!), which in the case process of a system error will most likely call priority “panic” and in the case of a “system call”, will invoke (indirectly via “trapl”(2841)) the appropriate system call procedure.

9.9 Return

Upon completion of the handling of an interrupt or trap the code follows a common path ending in an “rtt” instruction (0805). This reloads both the PC and PS from the current stack, i.e. the kernel stack, in order to restore the processor environment that existed before the interrupt or trap.