[comp.os.minix] Proposed solution to PS/2 problems

ast@cs.vu.nl (Andy Tanenbaum) (01/28/89)

Sort of out of the blue, a got a letter from a student in Eindhoven (in Holland)
named Adrie Koolen who has had MINIX running on a PS/2 model 60 for a year.
He is not on any net and knows nothing about all our discussions.  He also has
implemented a large number of 1.3 features on his own, including extended
memory for the AT, bad block handling, softscrolling, RS232, LED control,
foreign keyboard support, bad block handling, and other things.  He also
built a distributed system for diskless MINIX workstations.  Furthermore
he documented all of this in great detail (in Dutch).  When he turned it
in, his teachers said it was dumb and a waste of time.  They felt he ought
to go back to something important (like learning how to solder wires together?).
The kid is clearly a couple of light years ahead of his teachers.  I'll
write him a nice official letter on university stationery saying what a good
job he did, so he can rub it in his teachers' noses.

Anyway, he sent me the code, so the first thing I did was take a look to see
how he handled the level-triggered interrupt problem.  He is clearly aware of
it, and describes it in detail in his report, with diagrams and everything.
Basically what he did is as follows.  In mpx88.s there is a routine disk_int:
that catches floppy disk interrupts.  This routine calls save(), and then calls
interrupt() with some parameters. Right after the call to save() he inserted a
call to floppy_int(), which is a C routine he added to floppy.c:

floppy_int()
{
  /* sense_needed, ifp, and results are global variables */
  if (sense_needed) fdc_out(FDC_SENSE);
  results = fdc_results(ifp);	/* save this for later */
}

In this way, by the time interrupt() is called in proc.c, the floppy disk
controller has negated the interrupt, and everything is ok when interrupt()
sends the EOI.

This scheme seems ok and is simple, but has one drawback:  fdc_out() and
fdc_results() make lots of calls to port_out(), and they are all made with
interrupts disabled.  Bruce Evans recently pointed out that reducing the
interrupt handling time is needed to run RS232 at higher speeds.  Adrie's
scheme increases it.

I have also been thinking about this problem.  I have a slightly different
solution, as follows.  Suppose I modified the disk_int routine in mpx88.s
to read in the 8259A mask, disable the floppy int, and output it again.  In
assembly code this takes 4 instructions.  Then interrupt() is called.

Suppose we modify interrupt() not to send EOI to the 8259A, but have that
done after the receive(HARDWARE) statements in the floppy driver (after
sensing, of course).    Then we re-enable the floppy in the 8259A mask.

My scheme has no C language calls to port_in() or
port_out() in the interrupt handler, and should work on PCs and PS/2s equally
well, so we don't need any mca variable or run time test.

The one thing I am not sure about is what happens if a floppy interrupt
happens while the hard disk task is running?  The floppy interrupt will happen
and the interrupt handler will run and exit.  No more floppy interrupts will
happen because the 8259A mask bit has been set to disable them.  But what
happens if an RS232 interrupt wants to occur.  Does the 8259A inhibit the
interrupt because the floppy EOI has not yet been sent?  If so, the RS232
performance may be worse in my scheme.  I am aware that the 8259A has
various modes for nested/nonnested interrupts etc., but what I don't know
is which mode PCs and PS/2s use, and whether RS232 has a relatively high
or low priority.  I am also not entirely clear how specific and nonspecific
EOIs relate to this.  If you look at the 1.3 proc.c, you will see something
about nonspecific EOI has been added for the PS/2 Model 30.

If you are knowledgeable in this area, please post comments about my
proposal.  Better proposals are also welcome.  The goals are:

 - KISS (Keep It Simple, Stupid)
 - Don't redesign all of MINIX to accommodate the PS/2
 - Not too much assembly code
 - Have pity on the poor RS232 line which has all these characters coming at it
 - Should work on PCs, ATs, PS/2s without too many if (ps && !mca) ...

Andy Tanenbaum (ast@cs.vu.nl)