Normally, the system executes instructions sequentially, one after the next, unless it hits a BRANCH instruction. The BRANCH instruction is covered in Chapter 2 when we talk about procedure calling conventions. The other time the system will interrupt the normal flow of processing is in the case of an interruption. An example might be an I/O card signaling that a transfer is complete or a page fault due to a page not being present in memory. Interruptions are categorized into four classes: A fault happens when the system cannot execute the current instruction due to a temporary problem, such as a page being unavailable. The instruction will usually be restarted after the condition is corrected. A trap happens when the current instruction causes an error, such as an arithmetic overflow or a violation of protection rights on a page. The instruction normally will not be restarted. An interrupt is generated by an entity outside of the current instruction stream, such as an I/O card requesting attention. A check occurs when the system hardware has detected a hardware malfunction such as a parity error. While these terms are well-defined in the PA-RISC architecture, they are not strictly adhered to within the HP-UX kernel. For example, HP-UX refers to a "Protection Fault" when this is strictly a trap, not a fault. However, all four types of interruptions are handled in the same way, so it's really just a matter of terminology. Also note that the terms interrupt and interruption are sometimes confused. Strictly speaking, an event (other than a BRANCH) that causes the flow of control to change is an interruption. One particular type of interruption is an interrupt, which is a signal from an external device. Each possible type of interruption is given a predetermined priority within the system, and the various types are organized into interruption groups. Table 1-5, from Gerry Kane's PA-RISC 2.0 Architecture, shows the interruption groups, interruption numbers, and the description of the type of interruption. Table 1-5. Interrupts and Interruption Groups, in Priority OrderGroup | Interruption | Description |
---|
Group 1: | 1 | High-priority machine check | Group 2: | 2 | Power failure interrupt | | 3 | Recovery counter trap | | 4 | External interrupt | | 5 | Low-priority machine check | | 29 | Performance monitor interrupt | Group 3: | 6 | Instruction TLB miss fault or instruction page fault | | 7 | Instruction memory protection trap | | 8 | Illegal instruction trap | | 9 | Break instruction trap | | 10 | Privileged operation trap | | 11 | Privileged register trap | | 12 | Overflow trap | | 13 | Conditional trap | | 14 | Assist exception trap | | 15 | Data TLB miss fault or Data page fault | | 16 | Nonaccess instruction TLB miss fault | | 17 | Nonaccess data TLB miss fault or Nonaccess data page fault | | 26 | Data memory access rights trap | | 27 | Data memory protection ID trap | | 28 | Unaligned data reference trap | | 18 | Data memory protection trap or Unaligned data reference trap | | 19 | Data memory break trap | | 20 | TLB dirty bit trap | | 21 | Page reference trap | | 22 | Assist emulation trap | Group 4: | 23 | Higher-privilege transfer trap | | 24 | Lower-privilege transfer trap | | 25 | Taken branch trap |
Interruption Vector Table PA-RISC uses an Interruption Vector Table (IVT) to determine how to handle each type of interruption. The address of the beginning of the IVT is store in control register CR14. Each entry in the table is 32 bytes (8 words) long. Note that these entries are not just pointers to routines they are actual code, up to eight instructions. In many cases that code will just be a BRANCH to the correct handler, but this doesn't have to be the case. Interruption Handling The four different groups of interruptions become significant when we look at how interruptions are handled. Group 1 consists of just the HPMC. This interruption is generated when the hardware detects an unrecoverable error. It can occur at any time asynchronously with the instruction stream and is acted on immediately. Group 2 interruptions are checked immediately at the beginning of an instruction cycle. These interruptions are handled before the next instruction is fetched. The system next checks the N-bit in the PSW, which indicates a nullified instruction. A nullified instruction is an instruction that should be skipped. In Chapter 2, we talk about how and why it is used. For now, it's enough to know that if the N-bit is on, the next instruction isn't even fetched we just increment the program counter and start the next cycle. If the N-bit is not set, the system fetches the next instruction, begins execution of the instruction, and advances the program counter. If the execution of the instruction causes a Group 3 interruption, the program counter is decremented, the PSW is reset to its previous state, and the interruption is handled. This means that when the interruption handler finishes, the instruction will be restarted. If the instruction causes a Group 4 interruption, the handler is branched to directly without backing up the program counter, so the instruction will not be restarted. Interruption Save State When an interruption occurs, the system must save its current state before branching to the interruption vector. Control registers 17 through 22 are used to save the interruption state. For each interruption, the system takes the following actions: The PSW is saved in CR22. For groups 2 and 3, this will be the PSW at the beginning of the instruction. For group 4, it will be the PSW at the end of the instruction. The PSW is cleared except for the W-, E-, and M-bits. This has the effect of disabling all lower priority interruptions. The current instruction space and offset are stored in control registers 17 and 18. The privilege level is set to 0. The instruction that was executing at the time of the interruption is stored in CR19. The address associated with the instruction is stored in control registers 20 (space) and 21 (offset). In this way, a faulting address is passed to the fault handlers. General registers 1, 8, 9, 16, 17, 24, and 25 are saved by copying them to the shadow registers. The system begins executing at the interruption vector address + (32 * interruption number). |