Resolving interrupt conflicts An introduction to reprogramming of the 8259A Interrupt Controllers

advertisement
Resolving interrupt conflicts
An introduction to reprogramming
of the 8259A Interrupt Controllers
Intel’s “reserved” interrupts
• Intel had reserved interrupt-numbers 0-31
for the processor’s various exceptions
• But only interrupts 0-4 were used by 8086
• Designers of the early IBM-PC ROM-BIOS
disregarded the “Intel reserved” warning
• So interrupts 5-31 got used by ROM-BIOS
code for its own various purposes
• This created interrupt-conflicts for 80286+
Exceptions in Protected-Mode
• The interrupt-conflicts seldom arise while
the processor is executing in Real-Mode
• PC BIOS uses interrupts 8-15 for devices
(such as timer, keyboard, printers, serial
communication ports, and diskette drives)
• CPU uses this range of interrupt-numbers
for various processor exceptions (such as
page-faults, stack-faults, protection-faults)
Handling these conflicts
• There are two ways we can ‘resolve’ these
interrupt-conflicts when we write ‘handlers’
for device-interrupts in the ‘overlap’ range
– We can design each ISR to query the system
in some way, to determine the ‘cause’ for the
interrupt-condition (i.e., a device or the CPU?)
– We can ‘reprogram’ the Interrupt Controllers
to use non-conflicting interrupt-numbers when
the peripheral devices trigger their interrupts
Learning to program the 8259A
• Either solution will require us to study how
the system’s two Programmable Interrupt
Controllers are programmed
• Of the two potential solutions, it is evident
that greater system efficiency will result if
we avoid complicating our interrupt service
routines with any “extra overhead” (i.e., to
see which component wished to interrupt)
Three internal registers
input-signals
8259A
IRR
IMR
ISR
IRR = Interrupt Request Register
IMR = Interrupt Mask Register
ISR = In-Service Register
output-signal
PC System Design
8259A
PIC
(slave)
Programming is via
I/O-ports 0xA0-0xA1
8259A
PIC
(master)
Programming is via
I/O-ports 0x20-0x21
INTR
CPU
How to program the 8259A
• The 8259A has two modes:
– Initialization Mode
– Operational Mode
• Operational Mode Programming:
– Write a (9-bit) command to the PIC
– Maybe read a return-byte from the PIC
• Initialization Mode Programming:
– Write a complete initialization sequence
Sending 9-bits to PIC
The ninth bit of the data
7
6
5
4
3
2
1
0
A7 A6 A5 A4 A3 A2 A1 A0
D7 D6 D5 D4 D3 D2 D1 D0
$PORT_ID
%al
out
%al, $PORT_ID
How to access the IMR
• If in operational mode, the Interrupt Mask
Register (IMR) can be read or written at
any time (by doing in/out with A0-line=1)
– Read the master IMR:
– Write the master IMR:
– Read the slave IMR:
– Write the slave IMR:
in
out
in
out
$0x21, %al
%al, $0x21
$0xA1, %al
%al, $0xA1
How to read the master IRR
• Issue the “read register” command-byte,
with RR=1 and RIS=0; read return-byte:
mov $0x0B, %al
out %al, $0x20
in $0x20, %al
How to read the master ISR
• Issue the “read register” command-byte,
with RR=1 and RIS=1; read return-byte:
mov $0x0A, %al
out %al, $0x20
in $0x20, %al
End-of-Interrupt
• In operational mode (unless AEOI was
programmed), the interrupt service routine
must issue an EOI-command to the PIC
• This ‘clears’ an appropriate bit in the ISR
and allows other unmasked interrupts of
equal or lower priority to be issued
• The non-specific EOI-command clears the
In-Service Register’s highest-priority bit
Some EOI examples
• Send non-specific EOI to the master PIC:
mov $0x20, %al
out %al, $0x20
• Send non-specific EOI to both the PICs:
mov $0x20, %al
out
$%al, 0xA0
out
%al, $0x20
Initializing the 8259A
• A series of 9-bit values is sent to the PIC
• Once it’s begun, it must be completed
• Each 9-bit values is called an Initialization
Command Word (abbreviated ICW)
• The least significant 8 bits are sent on the
PC’s data-bus, while the 9th bit is sent as
bit 0 on the PC’s address-bus
Official Reference
• The official Intel programming reference
manual for the 8259A is available online
(see ‘Resources’ on our course website)
• This document is 24 pages in .pdf format
• Many pages are irrelevant to programmers
(e.g., they are concerned with electrical
specifications, physical dimensions, pin
configurations, and heating restrictions)
ICW1 and ICW2
0
A7
1
A15 A14 A13 A12 A11
A10
/ T7 / T6 / T5 / T4 / T3
A6
A5
1
LTIM ADI SNGL IC4
A9
A8
ICW1
ICW2
LTIM (1 = Level-Triggered Interrupt Mode, 0 = Edge-Triggered Interupt Mode)
ADI is length of Address-Interval for call-instruction (1 = 4-bytes, 0 = 8-bytes)
SNGL (1 = single controller system, 0 = multiple controllers in cascade mode)
IC4 means Initialization Command-Word 4 is needed (1 = yes, 0 = no)
ICW3
1
S7
S6
S5
S4
S3
S2
S1
S0
(master)
S Interrupt-Request Input is from a slave controller (1=yes, 0=no)
1
0
0
0
0
0
ID2
ID1
ID0
(slave)
ID number of slave controller’s input-pin to master controller (0-7)
ICW4
1
0
0
0 SFNM BUF M / S AEOI µPM
Special Fully-Nested Mode
(1 = yes, 0 = no)
NON-BUFFERED mode (00 or 01)
BUFFERED-MODE (10 = slave, 11 = master)
microprocessor
mode
1=8086/8088
0=8080
Automatic EOI mode
1 = yes, 0 = no
Initializing the master PIC
• Write a sequence of four command-bytes
• (Each command is comprised of 9-bits)
A0
D7
D6
D5
D4
D3
D2 D1
0
0
0
0
1
0
0
0
D0
1
1
ICW1=0x11
ICW2=baseID
1
0
0
0
0
0
1
0
0
ICW3=0x04
1
0
0
0
0
0
0
0
1
ICW4=0x01
Initializing the slave PIC
• Write a sequence of four command-bytes
• (Each command is comprised of 9-bits)
A0
D7
D6
D5
D4
D3
D2 D1
0
0
0
0
1
0
0
0
D0
1
1
ICW1=0x11
ICW2=baseID
1
0
0
0
0
0
0
1
0
ICW3=0x02
1
0
0
0
0
0
0
0
1
ICW4=0x01
Unused real-mode ID-range
• We can use our ‘showivt.s’ demo to see
the “unused” real-mode interrupt-vectors
• One range of sixteen consecutive unused
interrupt-vectors is 0x90-0x9F
• We created a demo-program (‘reporter.s’)
to ‘reprogram’ the 8259s to use this range
• This could be done in protected-mode, too
• It would resolve the interrupt-conflict issue
Other ideas in the demo
• It uses an assembly language ‘macro’ to create
sixteen different ISR entry-points:
.macro
isr
id
pushf
pushw
$\id
call
action
.endm
• All the instances of this macro call to a common
interrupt-handling procedure (named ‘action’)
The Macro’s expansion
• If the macro-definition is invoked, with an
argument equal to, say, 0x08, like this:
isr 0x08
then the ‘as’ assembler will ‘expand’ that
macro-invocation, replacing it with:
pushf
pushw
$0x08
call
action
How ‘action’ works
• Upon entering the ‘action’ procedure, the system stack
has six words:
FLAGS
CS
IP
FLAGS
Interrupt-ID
return-from-action
SS:SP
• The two “topmost” words (at bottom of picture) will get
replaced by the interrupt-vector corresponding to ‘int-ID’
= pushed onto stack by CPU
= pushed onto stack by ‘isr’ macro
The stack states
Stage 1
Stage 2
Stage 3
FLAGS
FLAGS
FLAGS
FLAGS
CS
CS
CS
CS
IP
IP
IP
IP
Upon entering
‘isr’
FLAGS
FLAGS
Int-ID
vector-HI
action-return
vector-LO
Upon entering
‘action’
Before exiting
‘action’
After exiting
‘action’
(and entering
ROM-BIOS
interrupthandler)
Stage 4
The on-screen status-lines
• We call ROM-BIOS service to setup the
video display-mode for 25-rows of text
• We use rows 0 through 21 for standard
80-column text-output (i.e., keys pressed)
• Line 22 is kept blank (as visual separator)
• Lines 23 and 24 are used to show sixteen
labeled interrupt-counters (IRQ0-IRQ15)
• Any device-interrupt increments a counter
In-class exercise
• The main new idea was reprogramming of
the 8259A Interrupt Controllers, in order to
avoid “overloading” of any Intel “reserved”
interrupt-numbers (namely, 0x00 - 0x1F)
• Modify our ‘reporter.s’ program so that any
‘mouse-event’ interrupts will get counted in
the IRQ-12 counter (it’s labeled ‘PS2’)
• See ‘trymouse.s’ demo for an example
BIOS PS/2 mouse services
Interrupt 0x15, function 0xC2 (8 sub-functions)
–
–
–
–
–
–
–
–
0: Enable/disable the pointing-device
1: Reset the pointing-device
2: Set pointing-device’s sample-rate
3: Set pointing-device’s resolution
4: Read pointing-device’s type
5: Initialize pointing-device interface
6: Get device status/Set scaling-factor
7: Set pointing-device’s handler-address
Steps to activate PS/2 device
#--------------------------------------------------------------------------------------------------------------------------------auxISR: lret
# long return to BIOS
#--------------------------------------------------------------------------------------------------------------------------------enable_aux_device:
# reset the pointing device
mov
$0xC201, %ax
int
$0x15
# reset pointing device
# invoke BIOS service
# install our mouse-event handler
mov
%cs, %ax
mov
%ax, %es
lea
auxISR, %bx
mov
$0xC207, %ax
int
$0x15
# address code-segment
# with the ES register
# point ES:BX to handler
# set handler adddress
# invoke BIOS service
# enable the pointing device
mov
$0xC200, %ax
mov
$1, %bh
int
$0x15
# enable/disable device
# select ‘enable’
# invoke BIOS service
ret
#-------------------------------------------------------------------------------------------------------------------------------
Download