Assembly
Language
© Copyright Brian Brown, 1988-2000. All rights reserved.
| Notes | Home
Page |
INTERRUPTS
An interrupt is an unexpected hardware initiated subroutine call
or jump that temporarily suspends the running of the current
program.
Interrupts occur when a peripheral device asserts an interrupt input pin of the micro-processor. Provided the interrupt is permitted, it will be acknowledged by the processor at the end of the current memory cycle. The processor then services the interrupt by branching to a special service routine written to handle that particular interrupt. Upon servicing the device, the processor is then instructed to continue with what is was doing previously (by use of a special "return from interrupt" instruction).
Interrupts fall into two major categories, maskable and non-maskable. An interrupt may be either EDGE or LEVEL sensitive.
Edge level interrupts are recognised on the falling or rising edge of the input signal. They are generally used for high priority interrupts and are latched internally inside the processor. If this latching was not done, the processor could easily miss the falling edge (due to its short duration) and thus not respond to the interrupt request.
Level sensitive interrupts overcome the problem of latching, in that the requesting device holds the interrupt line at a specified logic state (normally logic zero) till the processor acknowledges the interrupt. This type of interrupt can be shared by other devices in a wired or configuration, thus is commonly used to support daisy chaining and other techniques.
Maskable Interrupts
The processor can inhibit certain types of interrupts by use of a
special interrupt mask bit. This mask bit is part of the
condition code register, or a special interrupt register. If this
bit is set, and an interrupt request occurs on the Interrupt
Request input, it is ignored.
Non-Maskable Interrupts
There are some interrupts which cannot be masked out or ignored
by the processor. These are associated with high priority tasks
which cannot be ignored (like memory parity or bus faults). In
general, most processors support the Non-Maskable Interrupt
(NMI). This interrupt has absolute priority, and when it occurs,
the processor will finish the current memory cycle, then branch
to a special routine written to handle the interrupt request.
Advantages of Interrupts
Interrupts are used to ensure adequate service response times by
the processing. Sometimes, with software polling routines,
service times by the processor cannot be guaranteed, and data may
be lost. The use of interrupts guarantees that the processor will
service the request within a specified time period, reducing the
likelihood of lost data.
Maskable NonMaskable Acknowledge 68000 IPL0-IPL2 Where IPL0-IPL2 = 7 FC0-FC2 (111) RESET iAPX386 INTR NMI M/IO=0 RESET D/C=0 W/R=0
68000
The 68000 uses three input lines, which are priority encoded. A
level 7 cannot be masked. The interrupt lines must remain stable
until the 68000 signals interrupt acknowledge.
iAPX386
INTR is level sensitive, and must remain asserted until the
iAPX386 generates the interrupt acknowledge signal. NMI is rising
edge sensitive and must be negated for at least eight CLK2
periods, then asserted for at least eight CLK2 periods. Once NMI
is accepted, no further NMI's are processed till an IRET is
executed.
The Use of Interrupts
The use of interrupts generally falls into the following
categories,
I/O data transfers are more efficient when interrupt driven, because the processor is released from software polling. The device requests transfer only when there is data to be moved, so the processor does not need to continually poll the device. This releases the CPU to perform other tasks during this period.
The Basic steps involved in interrupt processing are
68000
A device requests an interrupt by presenting a priority
level between 1 and 7 to the processor. The interrupt is
accepted ONLY if the current processor priority level (in
SR) is less than the interrupt level, OR if the request
level is 7. Level 7 is equivalent to NMI.
iAPX386
INTR interrupt requests are enabled using the STI
instruction (and disabled using CLI). The NMI is always
enabled except where the processor is currently servicing
an NMI request.
68000
An interrupt is asserted by presenting a priority level
of between 1 and 7 to the processor on the IPL0-IPL2
lines.
iAPX386
An INTR is performed by asserting the INTR pin high. An
NMI is performed by asserting the NMI pin high.
68000
The 68000 asserts FC0-FC2 high to indicate an interrupt
acknowledge. The requesting device may either supply an
interrupt vector number, or indicate auto-vectoring, in
which case the vector numbers are 25 to 31, according to
the priority level on IPL0-IPL2. The program counter and
status register is saved on the stack.
The priority level in the status register is set to the level of the interrupt, which prevents further interrupts of the same or lower levels. The supervisor bit is enabled and the trace bit turned off.
iAPX386
When the INTR occurs, if the Interrupt Flag bit (IF) is
enabled, the processor reads an 8-bit vector (using
D0-D7) supplied by the interrupting device, which
identifies the source of the interrupt. The IF bit is
reset when the interrupt is being serviced, effectively
disabling further interrupts. It may be set by the
interrupt handler to allow nesting interrupts. When the
IRET instruction is executed, the original state of the
IF bit is restored.
When the NMI occurs, the processor uses an internal vector address of 2. No interrupt acknowledge signal is generated, and the processor ignores further NMI requests whilst servicing the current NMI. The IF bit is cleared on entry to the NMI service routine, which prevents furthet INTR interrupt requests.
The interrupt vector is supplied from the IDT descriptor entries when running in protected mode. The tables base address and limit is stored in IDTR, and each descriptor is eight bytes long. Which descriptor is referenced depends upon the 8 bit vector supplied by the interrupting device. The program counter and EFLAG is saved on the stack.
68000
The 68000 uses the Return from Exception (RTE)
instruction to restore the machine state to that which
existed prior to the interrupt occurring. The PC and
status register are restored from the supervisor stack.
This is forbidden if the processor is running in user
state, as the instruction sets the status register
directly, which would permit a means of enabling
supervisor mode.
iAPX386
The Interrupt Return (IRET) instruction restores the
machine state, loading the CS, PC and EFLAGS from the
stack. Other exceptions require popping off the error
code before executing the IRET (8, 10-14).
ACCOMPLISHING INPUT/OUTPUT DATA TRANSFER
There are three main methods used to perform/control input/output
data transfers. They are,
Programmed I/O or Polling
In programmed I/O, all transfers to and from devices is performed
by the processor. The processor sends and requests data; all
input and output operations are under the control of the program
being executed. The transfers are co-ordinated by the use of a
special handshake protocol.
To determine if an I/O request is pending, the processor scans each device. If the device is requesting service, it will set a special flag. The flags of the various devices are continuously checked using a scanning loop program. When the processor finds a devices flag set, it branches to the appropriate service routine, and after the service is completed, resumes the polling sequence. Such a software polling loop is shown below.
There are two basic methods used in sensing the device-request flags, the use of a simple input status port, and the use of a priority-encoder input-status port.
A Simple Input-Status Port
The various devices are connected to a decoded location, each
device utilising a single bit line. By reading this location, the
CPU can determine which device is requesting service.
The Priority-Encoded Input-Status Port
The decoded location is connected to the output of a priority
encoder. The input of the priority encoder is connected to each
device. When a device requests service, the priority encoder
presents a special code combination (unique for each device) to
the decoded memory location. The port thus holds the value or
address associated with the highest device requesting service.
The priority encoder arranges all devices in a list, devices given a lower priority are serviced when no other higher priority devices need servicing. This simplifies the software required to determine the device, resulting in an increase in speed.
The disadvantages are
Summary of Software Polled I/O
Polling is the most common and simplest method of I/O control. It
requires no special hardware and all I/O transfers are controlled
by the CPU program. Polling is a synchronous mechanism, by which
devices are serviced in sequential order.
The polling technique, however, has limitations.
Interrupt Controlled I/O Transfers
Interrupts are an asynchronous mechanism. Each device is
connected to an interrupt line. When a device needs service, it
asserts the interrupt line to request the processors attention.
The processor checks for pending interrupts at the end of every memory cycle. Interrupts can be masked, or non-maskable. Once the interrupt has been recognized by the processor and accepted, the device must be serviced. This is done by forcing the processor to a specialized service routine.
The status of the program being executed must first be saved. The processors registers will be saved on the stack, or, at very least, the program counter will be saved. Preserving those registers which are not saved will be the responsibility of the interrupt service routine. Once the program counter has been saved, the processor will branch to the address of the service routine.
If more than one device is connected to the interrupt line, the processor needs to know to which device service routine it should branch to. The identification of the device requesting service can be done in either hardware or software, or a combination of both.
Software Determination of the Requesting Device
A software routine is used to identify the device requesting
service. A simple polling technique is used, each device is
checked to see if it was the one needing service.
Having identified the device, the processor then branches to the appropriate interrupt-handling-routine address for the given device. The order in which the devices appear in the polling sequence determines their priority.
Software/Hardware Driven Identification (Daisy Chain)
This is significantly faster than a pure software approach. A
daisy chain is used to identify the device requesting service.
Daisy chaining is used for level sensitive interrupts, which act like a wired or gate. Any requesting device can take the interrupt line low, and keep it asserted low until it is serviced.
Because more than one device can assert the shared interrupt line simultaneously, some method must be employed to ensure device priority. This is done using the interrupt acknowledge signal generated by the processor is response to an interrupt request.
Each device is connected to the same interrupt request line, but the interrupt acknowledge line is passed through each device, from the highest priority device first, to the lowest priority device last.
After preserving the required registers, the microprocessor generates an interrupt acknowledge signal. This is gated through each device. If device 1 generated the interrupt, it will place its identification signal on the data bus, which is read by the processor, and used to generate the address of the interrupt-service routine. If device 1 did not request the servicing, it will pass the interrupt acknowledge signal on to the next device in the chain. Device 2 follows the same procedure, and so on.
Hardware Identification (Vectored Interrupts)
This is the fastest system. The onus is placed on the requesting
device to request the interrupt, and identify itself. The
identity could be a branching address for the desired
interrupt-handling routine.
If the device just supplies an identification number, this can be used in conjunction with a lookup table to determine the address of the required service routine. Response time is best when the device requesting service also supplies a branching address.
Priority Interrupt Controller Chips (PIC's) are hardware chips designed to make the task of a device presenting its own address to the CPU simple. The PIC also assesses the priority of the devices connected to it. Modern PIC's can also be programmed to prevent the generation of interrupts which are lower than a desired level.
DIRECT MEMORY ACCESS
Interrupts guarantee the fastest possible response time to an I/O
device requesting service. However, the servicing of the device
is still accomplished using software.
This may not be fast enough, for example, to transfer raw data between disks and memory. The solution is to replace the software routines which do the transferring of data with a hardware device(s).
The software routine is replaced with a specialized hardware processor, the Direct Memory Access Controller, or DMAC for short.
Direct memory access (DMA) is a hardware technique used to transfer data between prime memory and peripheral devices. In order to perform the transfer of data, the DMAC requires access to the processors address and data buses.
DMAC options for data transfer
The DMAC has several options available for the transfer of data.
They are,
The simplest approach is to suspend the processor.
Bus Arbitration
Most processors use special control lines for bus arbitration,
ie, controlling the use of the address and data bus,
Because the DMAC must drive the address and data buses of the processor, it is necessary for the processor to be able to tri-state these buses in response to a bus request by the DMAC.
DMAC Controller Operation
The diagram illustrates the various stages in DMA data transfer.
When the DMAC receives an interrupt from the device requesting
service, it generates a special signal for the microprocessor,
the HOLD signal.
The microprocessor then completes its current memory cycle, and tri-states the address and data buses. The CPU then responds with a HOLD ACKNOWLEDGE signal.
This informs the DMAC that the buses are available for use. It then places an address on the address bus which specifies the address at which the data transfer is to take place.
A read or write signal is then generated by the DMAC, and the I/O device either generates or latches the data. The DMAC effectively steals cycles from the processor in order to transfer the byte, so single byte transfer is also known as cycle stealing.
To achieve block transfers, some DMAC's incorporate an automatic sequencing of the value presented on the address bus. A register is used as a byte count, being decremented for each byte transfer, and upon the byte count reaching zero, the DMAC will release the bus.
When the DMAC operates in burst mode, the CPU is halted for the duration of the data transfer.
Memory Considerations
The speed of memory in a micro-processor based system is the
limiting factor on the DMA transfer rate. If the system RAM has a
cycle time of 500ns, this means the memory has a bandwidth of
2Mhz. DMA transfers cannot exceed this rate.
Transfers can occur in single bytes, or in bursts of bytes. The type of transfer mode affects the maximum transfer rate also.
If burst mode is used, the effective transfer rate is nearly the same as that of the memory bandwidth, but for single byte transfers, the effective transfer rate is very much slower. This occurs because time is expended in requesting and granting the DMA transfer for each byte.
Hidden DMA transfers
It is possible to perform hidden DMA, which is transparent to the
normal operation of the CPU. In other words, the bus is grabbed
by the DMAC when the processor is not using it.
The DMAC monitors the execution of the processor, and when it recognises the processor executing an instruction which has sufficient empty clock cycles to perform a byte transfer, it waits till the processor is decoding the op code, then grabs the bus during this time.
The processor is not slowed down, but continues processing normally. Naturally, the data transfer by the DMAC must be completed before the processor starts the execute cycle of the op code.
This technique can only be performed with those processors which provide an indication of the machine cycle status. Processors utilising cache and pipelining prohibit the use of this technique, as the processor is likely to be using the bus (pre-fetching) whilst decoding the current op-code.
DMAC's and Operating Systems
In a multi-user system, where many users compete for limited
resources such as RAM, it is common for the operating system to
use either paging (Virtual memory) or segmentation (swapping)
techniques.
In paging, the users program is split up into small blocks called pages, each about 4Kbytes in size. One or more of those pages resides in prime memory, whilst the rest of the pages which make up the users program are stored on disk.
As the user program executes, it is possible for the program to make reference to a page which currently resides on disk. This is called a page fault. The operating system then takes over, locates the required page on disk, and loads it into RAM (it may also swap some other pages out to make room for the new page!) before the users program is allowed to continue.
This operation is best performed with the help of a DMAC. The operating system can load the DMAC chip with the required information, ie, track/sector(s) information, load address, and then instruct the DMAC to perform the transfer. When the transfer is complete, the DMAC will provide a signal to the processor. The processor can then check the status of the DMAC to ensure the operation was performed correctly.
In mainframes, a special device is used to perform data transfers between devices and memory. It is the IBM I/O Channel. There are two basic types, the selector and the multiplexer channel. The selector type operates in burst mode with one device at a time for maximum speed, whereas the multiplexer can work with many sub-devices simultaneously in byte or burst mode.
Bus Request Bus Grant 68000 BR* BG* iAPX386 HOLD HLDA
Direct Memory Access (DMA) and the IBM-PC
DMA is used to transfer data between I/O devices and memory
without the aid of the CPU. The DMA device takes over the
processor busses and transfers the data a single byte at a time,
or as a block (burst mode). In the PC, DMA is performed by the
8237. It is used primarily for dynamic RAM refresh (psuedo reads)
and the floppy diskette controller.
The 8237 DMA Controller
This chip is reponsible for handling DMA transfers between
various I/O devices and memory. When a device requests service,
it asserts its associated request line (DRQ1 to DRQ3), signalling
the DMA controller. The 8237 then asserts HOLD to the processor
which responds with HLDA (Hold Acknowledge), and floats its
busses. Upon receiving this acknowledge, the 8237 takes over the
system bus and performs the transfer.
All DMA channels have access to 1mb memory space (20 bit registers) and have a 64k block limitation. Memory to memory transfers which use channel 0 and 1 are not supported, as channel 0 is used to refresh the system RAM.
On the PC/XT, the 8237 transfers 8 bit values between I/O and memory, and transfers must occur on evenbyte boundarys.
The PC series uses the 8237 DMA Controller Chip which is used as follows,
Channel Purpose 0 Dynamic RAM Refresh 1 SDLC or User programmed 2 Floppy disk 3 Fixed disk Page registers appear at 0x80 to 0x83 Controller appears at 0x00 to 0x0f
When the base address is written, it is the real address divided by 2 that is written to the base register.
The method of initiating a dma transfer is,
Interrupt Latency and Response Time
In responding to interrupts, designers use several terms to
describe specific phases of the interrupt process.
At times, a processor might ignore requests whilst executing some indivisible instruction stream (read-write-modify cycle). The figure that matters most is the longest possible interrupt latency time. Often the real time executive is executing code which cannot be interrupted, running with interrupts disabled. In these instances, latency will vary considerably depending upon when the interrupt occurs, whether in user code or in the executive.