[comp.sys.ibm.pc.hardware] sharing hardware interrupts

phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) (05/29/91)

I have read that two devices cannot share and concurrent use the same
interrupt (IRQ).  I'd like to know if this is really so true and if it
is more a case of just dumb software (which abounds in this world).

Suppose you have two or more different serial ports in a PC.  Surely
there is a register somewhere on there that indicates its status as to
whether or not it has changed state, or has a state that needs to be
dealt with.  When any one of the serial ports causes an interrupt (for
the sake of discussion let's say it is #4 and nothing else uses #4)
the software driver will get into control, scan all the known serial
port addresses for states to deal with, and performs the appropriate
action for all of them that need it.

Given the above software, why could it not be possible to have two or
more devices share the same interrupt.

I plan to write my own terminal program soon, and I want to make sure
that it is going to be able to handle all reasonable and useful cases.
-- 
 /***************************************************************************\
/ Phil Howard -- KA9WGN -- phil@ux1.cso.uiuc.edu   |  Guns don't aim guns at  \
\ Lietuva laisva -- Brivu Latviju -- Eesti vabaks  |  people; CRIMINALS do!!  /
 \***************************************************************************/

campbell@dev8j.mdcbbs.com (Tim Campbell) (05/29/91)

In article <1991May29.014824.16278@ux1.cso.uiuc.edu>, phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
> I have read that two devices cannot share and concurrent use the same
> interrupt (IRQ).  I'd like to know if this is really so true and if it
> is more a case of just dumb software (which abounds in this world).
> 
> Suppose you have two or more different serial ports in a PC.  Surely
> there is a register somewhere on there that indicates its status as to
> whether or not it has changed state, or has a state that needs to be
> dealt with.  When any one of the serial ports causes an interrupt (for
> the sake of discussion let's say it is #4 and nothing else uses #4)
> the software driver will get into control, scan all the known serial
> port addresses for states to deal with, and performs the appropriate
> action for all of them that need it.
> 
> Given the above software, why could it not be possible to have two or
> more devices share the same interrupt.
> 
> I plan to write my own terminal program soon, and I want to make sure
> that it is going to be able to handle all reasonable and useful cases.

Ok - here's the skinny.  When an interrupt occurs in a PC (say #4) the
state of the CPU is pushed onto the stack and the machine jumps to the
address pointed to by the ISR (interrupt service request) table.  This
table is the first thing in memory.  It's basically a bunch of address
(far pointers).  IRQ0 would be at address 0000:0000, IRQ1 would be at
address 0000:0004, etc. (4 bytes to an interrupt to hold the far pointer).
IRQ4 would then be at address 0000:0010 (hex) OR 0001:0000 (however you
care to look at it) - this address would then contain the far pointer
to the invocation point of the interrupt handler.

The machine executes the code found at that address until it encounters
an IRET (interrupt return) instruction.  It then pops the state of the
CPU back off the stack and continues to run as though nothing ever 
happened.

What the machine does while executing the interrupt service is your
business.  So it is possible to share interrupts.  But you mentioned
sharing them "concurrently" - which implies to me that you want to use
(for example) COM1 and COM3 at the same time.  Ok, this is fine if YOU
write the low level driver that is to control both of those devices.  But
say you want to plug a mouse into COM1 and modem into COM3 and the 
mouse is handled by the traditional MS-Mouse driver MOUSE.COM which is
completely oblivious to your interupt sharing scheme.  You now have a 
problem.  Yes, I suppose it's *possible* to patch the mouse driver, but
probably not especially pleasant -- so the easy way out is to just say
it can't be done.

So there you have it.  Your answer is definitely a qualified "maybe".

	-Tim

P.S.  I did set up a fully interrupt driven communications program in 
Turbo C which supplied the rather convenient option of being able to
define a function of type interrupt.  This makes the job a LOT easier
because the compiler supplies the required IRET as opposed to the plain
old RET instruction.  I seem to recall hearing that MS C and MS Quick C 
can now do this as well.  Can anyone confirm this?

  ---------------------------------------------------------------------------
	  In real life:  Tim Campbell - Electronic Data Systems Corp.
     Usenet:  campbell@dev8.mdcbbs.com   @ McDonnell Douglas M&E - Cypress, CA
       also:  tcampbel@einstein.eds.com  @ EDS - Troy, MI
 CompuServe:  71631,654	 	 (alias  71631.654@compuserve.com)
 P.S.  If anyone asks, just remember, you never saw any of this.

jamaass@bluemoon.uucp (Jeffrey A. Maass) (05/29/91)

phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:

> I have read that two devices cannot share and concurrent use the same
> interrupt (IRQ).  I'd like to know if this is really so true and if it
> is more a case of just dumb software (which abounds in this world).
> 
> Given the above software, why could it not be possible to have two or
> more devices share the same interrupt.
> 

Phil: You _CANNOT_ share interrupts on a PC/XT/AT, and the reason
is in hardware, not dumb software. Having spent a couple of months
trying to do same before being told the reason, I'd hate to see 
anyone else have the same fate!

Having said that, I can't find the magazine article that "set
me straight", and I don't recall the details as to why (has to do 
with the leading-edge-triggered" nature of the interrupt hardware,
I think).

Anyway, don't do it!

Jeff Maass                   Amateur Radio: K8ND (@ W8CQK)
Powell OH (NW of Columbus)         Netmail: jamaass@bluemoon.uucp
                                   Ma Bell: (614) 873-3234

stidolph@leland.Stanford.EDU (Wayne Stidolph) (05/30/91)

In article <08VP31w164w@bluemoon.uucp> jamaass@bluemoon.uucp (Jeffrey A. Maass) writes:
>phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
>
>> I have read that two devices cannot share and concurrent use the same
>> interrupt (IRQ).  I'd like to know if this is really so true and if it
>> is more a case of just dumb software (which abounds in this world).
>> 
>> Given the above software, why could it not be possible to have two or
>> more devices share the same interrupt.
>> 
>
>Phil: You _CANNOT_ share interrupts on a PC/XT/AT, and the reason
>is in hardware, not dumb software. 
> [deleted] ... (has to do with the leading-edge-triggered" nature of
> the interrupt hardware....

Don't have manual with me, but IBM Tech Ref for PC/AT explains interrupt
sharing around page 2-13 or so... should work as described by Phil.
Interrupts at 8259A can be either level or edge triggered (depends on
Initialization Command Word number 1, bit D3 (LTIM). Up to software
which way to go. In a level-detect mode, if two devices are holding IRQ
and you service one, then when you do the EOI the 8259 will generate
another INT to the CPU, so you'll do the second. I don't remember which
way the AT sets LTIM by default. 

Hope there's some good in this. I'll have time to check my notes on how
to do this middle of next week. Good luck!




-- 
  Wayne stidolph@leland.stanford.edu

bich@hpsciz.sc.hp.com (Bich Tran) (05/30/91)

Unfortunately, you cannot have more than one device tied to the interrupt line,
because in the AT system, interrupts are active hi ( really dumb indeed, and
that is corrected in the EISA bus). Only active low AND open collector gates
can be tied together. SO don't try to connect more than one driver to any one particular
interrupt. Any violation can result into burnt-up outpit drivers.

Hope it helps,
sincerely,
bic

johnl@iecc.cambridge.ma.us (John R. Levine) (05/30/91)

In article <08VP31w164w@bluemoon.uucp> jamaass@bluemoon.uucp (Jeffrey A. Maass) writes:
>phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
>> I have read that two devices cannot share and concurrent use the same
>> interrupt (IRQ).  ...
>
>Phil: You _CANNOT_ share interrupts on a PC/XT/AT, and the reason
>is in hardware, not dumb software. ...

The real answer, like the answer to most questions about crufty old PC
harware, is "it depends."  Most hardware cards are built on the assumption
that the interrupt line is unshared.  When the card doesn't want to
interrupt, it firmly turns the IRQ line off, when it does want to interrupt,
it turns the line on.  The problem with putting two cards on the same
interrupt line is that in the typical case that one wants to interrupt and
the other doesn't, the IRQ line is pulled both ways and the result is usually
no interrupt at all.  I once had all sorts of bizzaro printer problems until
I removed an unused Ethernet card that happened to be jumpered to the same
IRQ line.

The major exception to this is serial ports.  Most serial port cards I have
come across, even the $12.99 Taiwanese specials, connect to the IRQ line in a
way that allows any of several cards to turn on the IRQ line and have it
work.  For example, my internal Telebit modem and the $12.99 serial port for
my fax modem share the same interrupt.  Works fine.

Dumb software remains a problem, since any time you get an interrupt on a
shared line, the software has to poll all of the devices sharing the line to
find out which ones have something to say.  Too many device drivers,
particularly in DOS land (I run Unix) weren't written to support shared
interrupts even when the hardware allows it.

Regards,
John Levine, johnl@iecc.cambridge.ma.us, {spdcc|ima|world}!iecc!johnl
-- 
John R. Levine, IECC, POB 349, Cambridge MA 02238, +1 617 492 3869
johnl@iecc.cambridge.ma.us, {ima|spdcc|world}!iecc!johnl
Cheap oil is an oxymoron.

evans@syd.dit.CSIRO.AU (Bruce.Evans) (05/30/91)

In article <1991May29.014824.16278@ux1.cso.uiuc.edu> phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
>Suppose you have two or more different serial ports in a PC.  Surely
>there is a register somewhere on there that indicates its status as to
>whether or not it has changed state, or has a state that needs to be
>dealt with.  When any one of the serial ports causes an interrupt (for
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it won't
>the sake of discussion let's say it is #4 and nothing else uses #4)
>the software driver will get into control, scan all the known serial
>port addresses for states to deal with, and performs the appropriate
>action for all of them that need it.
>
>Given the above software, why could it not be possible to have two or
>more devices share the same interrupt.

Because if 2 devices are driving the same interrupt line, the one driving
it low wins. For some reason the PC interrupt h/w is designed so that
low == no interrupt. This is the reverse of what is needed for easy
interrupt sharing.

It is easy to have 2 ports sharing the same interrupt line if you don't
want them both to generate interrupts in the same application. The OUT2
port is wired as an interrupt-line enable. Turning it off allows another
serial device to drive the shared line. It is important for applications
that use it to restore it when they finish. I often have to clean up
after Windows has left it hot for COM1 in order to use an old version of
Mirror on COM3. Outputting 3 to port 3FC hex turns off the OUT2 bit (8)
for COM1.
-- 
Bruce Evans		evans@syd.dit.csiro.au

jcmorris@mwunix.mitre.org (Joe Morris) (05/30/91)

campbell@dev8j.mdcbbs.com (Tim Campbell) writes:

>In article <1991May29.014824.16278@ux1.cso.uiuc.edu>, phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
  [question about sharing interrupts between two devices]

>Ok - here's the skinny.  When an interrupt occurs in a PC (say #4) the
>state of the CPU is pushed onto the stack and the machine jumps to the
>address pointed to by the ISR (interrupt service request) table.  This
>table is the first thing in memory.  It's basically a bunch of address
>(far pointers).  IRQ0 would be at address 0000:0000, IRQ1 would be at
>address 0000:0004, etc. (4 bytes to an interrupt to hold the far pointer).
>IRQ4 would then be at address 0000:0010 (hex) OR 0001:0000 (however you
>care to look at it) - this address would then contain the far pointer
>to the invocation point of the interrupt handler.

Something of a nitpick not directly related to the original question, but
I think you meant to refer to "INTERRUPT 0 would be at 0000:0000, INTERRUPT
1 at 0000:0004" etc.  The IRQ (Interrupt ReQuest) lines are signals on
the I/O channel (and some other specialized items like the system clock)
and don't map one-to-one with the hardware interrupt vectors.  The offset
is controlled by the initialization of the interrupt controller chip.

IRQ0 (system timer) is produces the same effect as an INT 8 opcode; the
two standard comm port interrupt request lines are IRQ4 (COM1; equivalent
to INT 0Ch) and IRQ3 (COM2; equivalent to INT 0Bh).  Don't ask me why
COM1 is IRQ4 but COM2 is IRQ3.

Take a look at the documentation for the SYSTEM.INI file in Windows and
you'll see that the default layout for comm ports shares IRQ4 between
COM1 and COM3, and shares IRQ3 between COM2 and COM4.  No, I haven't tried
it.

Joe

roe@unibase.uucp (Roe Peterson) (05/31/91)

evans@syd.dit.CSIRO.AU (Bruce.Evans) writes:

>In article <1991May29.014824.16278@ux1.cso.uiuc.edu> phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
>>Suppose you have two or more different serial ports in a PC.
>>When any one of the serial ports causes an interrupt (for
>>the sake of discussion let's say it is #4 and nothing else uses #4)
[...]
>>Given the above software, why could it not be possible to have two or
>>more devices share the same interrupt.

>Because if 2 devices are driving the same interrupt line, the one driving
>it low wins. For some reason the PC interrupt h/w is designed so that
>low == no interrupt. This is the reverse of what is needed for easy
>interrupt sharing.

True - however, I have successfully shared an interrupt with two
(and only two) serial ports.  It seems that _some_ hardware can drive
an interrupt line high even when one other port is holding it low.
Attempts to share three ports on one interrupt fail.

The hardware I've used is the MCTAMS 4-port serial card (we get them from
JDR Microsystems), with the FAS 2.08.0 device drivers under ESIX 5.3.2.D.
However, since sharing interrupts is more of a hardware question, you should
be able to get away with the same sort of setup under DOS (given a serial
device driver capable of the right magic.)

-- 

						  Roe Peterson
						  uunet!sobeco!unibase!roe
						  roe@unibase.UUCP