Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!unmvax!ncar!ames!amdcad!sun!pitstop!sundc!seismo!uunet!munnari!otc!metro!basser!natmlab!ditsyda!evans From: evans@ditsyda.oz (Bruce Evans) Newsgroups: comp.os.minix Subject: Re: Help! Minix 1.3 & PS/2 Model 80 Message-ID: <1701@ditsyda.oz> Date: 28 Jan 89 13:01:25 GMT References: <1975@ast.cs.vu.nl> Organization: CSIRO DIT Sydney, Australia Lines: 81 in article <1975@ast.cs.vu.nl>, ast@cs.vu.nl (Andy Tanenbaum) says: > This still leaves us with the question of how to exit from the interrupt > handler and not get another interrupt instantly. Whatever solution is There is an amazingly simple answer. Do nothing. The reason we get another interrupt now is that the EOI done in interrupt() incorrectly tells the 8259 that the interrupt has been handled. Look at the PC BIOS keyboard driver. The first thing it does is an STI which is analogous to the task switch or return done at the end interrupt(). I think most of the BIOS drivers do this. I implemented this for my PC and 386-AT today. Of course an EOI must still be done in the high level task. It must now be a specific EOI: port_out(int_ctl_port, SPECIFIC_EOI | ((1 << irq_number) & 0x07)); where int_ctl_port is the interrupt control port (usually a constant for each driver, e.g., INT_CTL) SPECIFIC_EOI is 0x60 irq_number is the interrupt number (not vector), i.e., 0 to 15, 8 on each controller, e.g., 5 for XT_WINI, 6 for FLOPPY. I put these after all the fdc_results() and win_results() calls (actually in a new function) for the disk drivers. The sense command really belongs in the results function too. I'm using the 1.4a floppy driver.It works well. Perhaps the wini drivers will need a sense command for PS/2's too. One thing I didn't nail down is the PS/2's interrupt controller. There is a define for it as 0x3C in the assembler code only. Is this an 8259 with a mask port at 0x3D? The other drivers needed essentially no changes. The centralized EOI had to be deleted (lest the disks do it) so all the other drivers have to do it explicitly. It doesn't matter if it is done before or after device service, since all non-disk drivers run with interrupts disabled and the 8259 does not latch changes. (I'm fairly sure but don't believe me for level sensitive interrupts without trying it :-).) The clock is a special case in this. I actually use a low level handler, but since the clock has no device registers, the hardware part of the service routine is null and an immediate EOI does the job. There may be one minor problem :-). The 8259 enforces a priority scheme so while the XT_WINI interrupt is being handled at level 5, the FLOPPY interrupt at level 6 is locked out. These 2 priorities are well chosen and cause no trouble. The keyboard and rs232 priorities at 1 and 3-4 are not well chosen but cause no trouble because the devices are serviced with interrupts disabled anyway. I'm worried about the AT_WINI interrupt at level 14. The catch is that it is chained through level 2 on the first controller. So the 8259 is after all fairly well matched to Minix's interrupt handling. The main thing that is missing is a mode with no priorities. > chosen should be efficient. Doing a port_out to the 8259 to change the > mask is as expensive as doing a port_out to the 8259 for EOI. It is far worse than that. I implemented this mask fiddling approach too. It requires a port_in to get the current state, then a lock/restore to protect everything. 5 instructions and 8 bytes in assembler, but about 50 instructions in C. It still has to do an EOI as well. I did it in assembler to set the mask, in between the save() and interrupt() calls, and in C for the task level code to clear the mask. I think that the lock/restore approach is wasteful because the interrupt state is always known at the task level. I'm now investigating the "Special Mask Mode" which offers some hope of improving one or both methods. The documentation (data sheet) is so obscure that I'm using experimental methods. Whatever I end up with will be in the 386 protected mode version to be posted in a week or two (remember it will also run on PC's and provide other improvements). I already had a lot of #define's for the interrupt controller (to reprogram it at the start and to properly distinguish between interrupt numbers and interrupt vectors), and these could be used for the PS/2 code to avoid unnecessary diffs. Bruce Evans evans@ditsyda.oz.au