Interrupt/Exception handling on the x86
Required reading: Chapter 5 (Interrupt and Exception handling)
Sources of Exceptions/Interrupts
PIC: Programmable Interrupt Controller
- mapping IRQ0-15 => into vector number
- vector is signaled over the INTR line
IDT: Interrupt Descriptor Table (pg 5-11)
- table of entries (8 bytes each)
- lidt instruction - tells CPU where in memory the table resides
and how big it is
- lidt instruction takes a linear address
- first 32 entries for processor exceptions
- any of the remaining 16 for hardware interrupts
- rest are for software interrupts (e.g., int $0x50)
IDT entry (pg 5-13)
- 8 bytes
- CS:EIP -- entry point of handler routine
- P -- 1 bit -- Does entry holds valid info?
- DPL -- 2 bits -- 0 for exception and external interrupts, 3 for software interrupts
- Type -- 4 bits -- task, trap, or interrupt gate
- Crazy format like GDT entries (recall SEG() macro)
- Interrupts gates -- clear IF bit of %eflags when used
- Trap gates -- don't change eflags when used
- Both clear TF, VM, RF, NT flags when used
- Example:
SETGATE (idt[IRQ_OFFSET + 0], /* vector */
0, /* istrap */
&_clock_interrupt, /* offset */
0); /* DPL */
TSS: Task State Segment
- Purpose: hardware supported multi-tasking => we don't use
- Resides in memory, must tell the CPU where:
- TSS descriptor goes in the GDT
- Contains the linear address and size of the TSS
- ltr (GD_TSS) loads the TSS descriptor into the CPU
- Only field relevant to this class:
- SS0:ESP0 -- kernel stack that processor switches to when a
interrupt/exeception happens in user mode.
- All other fields irrelevant to this class:
- Saved segment registers: GS, FS, DS, SS, CS, ES
- Saved general registers:EDI, ESI, EBP, ESP, EBX, EDX, ECX, EAX
- Other saved registers: EFLAGS, CR3
- Stack pointers for receiving calls or handling traps
at intermediate privilege levels:
SS1:ESP1, SS2:ESP2
Exception Entry Mechanism
- pg 5-16
- Like a procedure call (arguments on the stack)
- USER => KERNEL
- KERNEL => KERNEL
- why switch stacks (USER => KERNEL)?
- stack may be the cause of the fault
- triple faults cause CPU reset
- Motivation: save on stack if the registers themselves are changed
- notice: Kernel=>Kernel fault doesn't save SS:ESP.
why? because there is no stack switch (i.e., SS:ESP are not
overwritten)
- mention now or later??
- mode (user => kernel): CS -- bottom 2 bits are CPL
Exception Return Mechanism
iret -- top of stack should be old EIP
closer look at old EIP / Exception Types
- traps - old EIP -- points past instruction causing exception
- ex. int $3 -- software breakpoint trap
- faults - old EIP -- points to instruction causing exception
- ex. page faults, segmentation violations
- aborts - old EIP -- not certain -- serious problems - CPU is confused
Comparison to PDP11/40
- DEVICE INTERRUPTS
- x86: maskable by IF bit of EFLAGS; (and by the PIC)
- pdp: multiple priority levels
- DISPATCHING
- x86: IDT, which resides anywhere in memory
- pdp: dispatch table at fixed physical address
- DISPATCH ENTRY FORMAT
- x86: IDT entry -- contain CS:EIP
- pdp: trap;br7+0. -- entry point and new PSW
- MODE SWITCH
- x86: low two bits of CS hold CPL (11 -- kernel, 00 -- user)
- pdp: kernel vs user specified in PSW
- ADDRESSING SWITCH
- x86: no switch -
paging is not changed because %cr3 is not reloaded.
However, more of the VA space is accessible--notably
the KERNEL only VA regions
(this ignores segmentation since our convention
is to disable segmentation for the lab OS)
- pdp: complete switch:
kernel mode implicitely selects new set of segementation registers
- STACK SWITCH
- x86: new stack is: TSS ss0:esp0
- pdp: kernel mode -- implicitely uses kernel sp register