You are on page 1of 9

Interrupt Driven I/O

Text: Tanenbaum ch.1.4.3, ch.5.1.5
Slides on interrupts:

Receiver Interrupt Program Example:


How an interrupt happens

Com Port


x86 Interrupts
Interrupt signals go from device to the PIC
and to CPU
All 3 signals are on the bus
Program the PIC and device using IN or
OUT instructions on certain I/O port
address, e.g.
PIC : 0x20 and 0x21
COM2: 0x2f8, 0x2f9

x86 Interrupts (contd)

UART receives a character and signals an interrupt on

a bus line.
Interrupt Controller detects the signal. If no pending
interrupts are pending, it services the interrupt
If another one is in progress or a higher priority one is
pending, the device is ignored. It continues to assert
the interrupt signal until it is serviced.
To handle the interrupt, the controller puts an interrupt
vector number (e.g 0x23 for COM2) on the address
lines and asserts a signal (INTR)to interrupt the CPU.

x86 Interrupts (contd)

CPU stops what it is doing and starts doing
something else.
CPU uses the interrupt vector number to
index the IDT (interrupt descriptor table) and
find the interrupt vector (i.e. address of the
interrupt service routine)
CPU runs the service routine which includes
writing a certain value(EOI) to the interrupt
controllers I/O port to ack the interrupt

Saving the Context

The hardware saves certain info before the
service procedure.
Info saved depends on the CPU. Saving the
Program counter is the minimum. Some
saves internal registers.
Most of the CPUs save info on the stack.

Programming the interrupts

Refer to the slides 5-19 on interrupts

Example Program for COM2

receiver interrupts
Look at $pcex/typewr.c

Steps 1-5:
Step 6:
Steps 10-13:
Steps 7-9:

initialization steps
wait forever loop
shut down interrupts
interrupt handler, need the envelope

Routines pic_end_int(), pic_enable_irq(), pic_disable_irq() are functions

implemented in the SAPC library in directory $pclibsrc
Look at $pcinc for include files

Interrupt Envelope Routine

From $pclibsrc/irq3.s: The bold lines are the essential ones you should understand. The others date
from Linux and are only needed to guard against bad user-level code.
# like linux SAVE_MOST and RESTORE_MOST macros in irq.h
.globl _irq3inthand
KERNEL_DS = 0x18
_irq3inthand: cld
# D bit gets restored by iret (this can be dropped)
push %es # in case user code changes data segs (this can be dropped)
push %ds # (this can be dropped)
pushl %eax
# save C scratch regs
<---(1) register saves
pushl %edx
pushl %ecx
movl $KERNEL_DS, %edx
# (this can be dropped)
mov %dx, %ds
# (this can be dropped)
mov %dx, %es
# (this can be dropped)
call _irq3inthandc # call C interrupt handler
<---(2) call into C
popl %ecx
<---(3) register
popl %edx
popl %eax
pop %ds #(this can be dropped)
pop %es #(this can be dropped)
<---(4) iret instruction