TIP: Click on subject to list as thread! ANSI
echo: 80xxx
to: ALL
from: ED BEROSET
date: 1997-09-01 06:51:00
subject: protected mode interrupts

cc80001
From: Ed Beroset 
Subject: protected mode interrupts
To supplement the bit of code Paul posted, this is a description of how
protected mode interrupts work in protected mode.  It assumes that you
already know something about real mode interrupts.
Just as in real mode, all interrupts in protected mode are vectored
through a table.  In real mode, that table is at at a fixed location
(0:0), but in protected mode the table, called the Interrupt Descriptor
Table (IDT) can be anywhere in memory.  Unlike real mode interrupt vector
table entries, which consist of just only the segment:offset address of
the interrupt handler, the IDT is a table of descriptors.  The descriptors
may be any of three types:
	- task gates
	- interrupt gates
	- trap gates
Their structures are as follows:
                            TASK GATE
 15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|                            reserved                           |  +6
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| P |  DPL  | 0 | 0 | 1 | 0 | 1 |           reserved            |  +4
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|                     TSS segment selector                      |  +2
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|                            reserved                           |  +0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
                         INTERRUPT GATE
 15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|                          offset 31..16                        |  +6
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| P |  DPL  | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |     reserved      |  +4
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|                        segment descriptor                     |  +2
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|                          offset 15..0                         |  +0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
                            TRAP GATE
 15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|                          offset 31..16                        |  +6
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| P |  DPL  | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |     reserved      |  +4
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|                        segment descriptor                     |  +2
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|                          offset 15..0                         |  +0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
As you can see, each descriptor is 8 bytes long (instead of the four bytes
each for real mode vectors).  The other significant differences are that
they contain P (Present) and DPL (Descriptor Privilege Level) information,
in addition to pointing to the handler routine.  The P bit is set if the
page is present in memory, or cleared if the segment has been paged out to
disk.  For systems which do not implement paging, this bit is always set
to 1.  The DPL is part of the protection mechanism built into the
processor (hence "protected mode").  I won't describe the gory details of
the protection mechanism here except as it applies uniquely to interrupts.
Suffice it to say, then, that as with call gates,  the CPU prevents an
interrupt from ttransferring execution to a *less* priveleged segment.
(Read that carefully -- some folks find it counterintuitive!)  
Since interrupts are typically asynchronous (i.e. they can occur at any
time), the handler routines are usually either put in a conforming code
segment (remember that conforming segments "conform" to the Current
Privilege Level (CPL)) or are written as PL 0 (most privileged.)
Naturally, which method you decide to use has mostly to do with how secure
your system is supposed to be.  If you're handling, say, a hard drive
hardware interrupt, you would probably not want to use a conforming code
segment, since all I/O and data the handler needs would have to be allowed
at the least privileged level (3) for the thing to work.  Bad idea!
Finally, a word about how to set up the PIC (Programmable Interrupt
Controller).  Due to the original design decisions made in the early
Cenozoic era (back when IBM engineers were designing their first PC), they
decided to use the Intel 8259A PIC.  It has a couple of different modes,
but the one used in PCs works like this:  when a hardware interrupt occurs
(this whole PIC thing is ONLY about hardware interrupts), it causes one of
the input lines on the PIC to go high.  The 8259 checks to see if the
interrupt has been masked (i.e. disallowed), and if it's OK to alert the
CPU, the 8259 does so by asserting its output INT line.  The CPU gets this
signal and acknowleges via its #INTA line.  The PIC then waits for a
second #INTA pulse, and when it's received, the PIC puts an eight-bit
pointer onto the data bus where it's read by the CPU.  The CPU ends the
second #INTA pulse and the interrupt is complete, at least as far as the
PIC is concerned.
What, you may ask, is this eight-bit pointer?  Good question.  It's an
index into the IDT -- in other words, it's the interrupt number.  Now if
you've ever gotten confused because IRQ 0 is not the same as INT 0, here's
why.  Each PIC is capable of handling up to eight hardware inputs.  Each
set of eight hardware interrupts (commonly referred to as IRQ 0-7 and IRQ
8-15) can be mapped to any eight contiguous interrupts.  The standard
mapping on PCs is to have IRQ 0 mapped to INT 8 and IRQ 8 mapped to INT
70h but this is not a very good idea.  INT 8 happens also to be reserved
by the processor for its double fault handler.  In fact, the first 32
interrupts are reserved for the processor but the boys at IBM decided to
ignore that to make their hardware simpler.    Fortunately, if we're
writing our own interrupts, we can "set things right" and simplify the
design of the interrupt handlers as a result.  While programming the PIC
from scratch is kind of difficult to describe, but if we ignore some 
of those details, simply remapping the base interrupt for each PIC is
quite simple.
The base address for the master PIC -- the one that controls IRQ 0-7 -- is
20h, and the base address for the slave (or "cascaded") PIC is A0h.  To
program a PIC for a particular base interrupt, here's the sequence:
send 11h to the PIC base address (e.g. 20h or A0h)
send the base interrupt to the PIC base address + 1 (e.g. 21h or A1h)
send either 4 to PIC + 1 (e.g. 21h) if it's the master PIC
	or  2 to PIC + 1 (e.g. A1h) if it's the slave PIC
send 1 to PIC + 1 (e.g. 21h or A1h)
Between each write, insert a short delay so the hardware (like
the original AT) will be able to keep up.  Note that in most designs these
days there isn't really a separate 8259A controller on board -- it's all
integrated into a chipset -- but the programming remains the same.  If
you're curious about what all those magic numbers mean, refer to Intel's
8259A data sheet.  This post is long enough without getting into all that!
One last thing for those who are going to rush right out and try this
under DOS -- it would be nice to save the current state of the PIC before
going into protected mode and then restore it when you come back out to
DOS.  Unfortunately, the PICs weren't originally intended to be
reprogrammed on the fly like that so there is NO PROVISION for reading out
the currently programmed values.  Alas!  The next best thing is to program
'em as I've outlined above, setting the base addresses to 8 and 70h
respectively when you come back out of DOS.  (Actually, some chipset
manufacturers have implemented a "back door" set of shadow registers by
which one can read the state of the PIC, but naturally, they're all
implemented somewhat differently...)
In related news, I'm currently putting together a web site which
specializes in just this sort of information about programming directly
to the hardware in assembly language.  It's not out there yet, but
drop me an email if you've got a particular topic that you'd like to see
covered -- particularly if you've been unable to find the information
elsewhere.  One caveat -- I don't intend to cover anything but the
most generic video. It's just too complex and other people have already
done it much better than I could anyway.
Ed
beroset@mindspring.com
-!-
---
---------------
* Origin: The Circuit! Board * Spokane * (1:346/100)

SOURCE: echomail via exec-pc

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.