ast@cs.vu.nl (Andy Tanenbaum) (01/23/89)
Steve Ackerman has reported getting MINIX to boot on the PS/2 Model 80. Good work! However, we are not really done yet. I have to figure out how to deal with level-triggered interrupts in a reasonable way. This message solicits suggestions. Please post them, since 10K heads are better than 1. MINIX, like all other message passing operating systems, does not do much in its interrupt routines. It just sends a message and returns from the interrupt. This means that after a floppy disk interrupt, the interrupt line would normally still be asserted. However, to shut off the 8259A interrupt controller, on line 1888, we order it to shut up. On the PS/2 this doesn't work. We have to actually talk to the device. It is probably unwise to do this inside the interupt() function. This means we have to move line 1888 to each device driver and do it there. Unpleasant but possible. However, things are worse than this. If we delete line 1888 and move it to the device drivers, when the interrupt routine is finished, we will get another interrupt. To prevent this, Steve diddled the 8259A's interrupt mask around line 1888. Double ugly. My question is: does anybody see a better and cleaner way to do this? I don't especially want the code around line 1888 having to figure out which of the 8259A's to diddle, and which bit, etc. For the floppy it may not be too bad, but for serial I/O, networking, etc, it will make things more complicated and error prone in a sensitive area. On the other hand, I don't want a major redesign of things. I think the original design is fairly simple and don't want to muck it up because of the way the PS/2 does things.) I'd also like to minimize the amount of code of the sort if (ps) /* Models 25 - 80 */ if (mca) ... /* microchannel architectures only */ if (ps && mca == FALSE) ... /* Models 25 and 30 */ etc. Hardware types, get out your thinking caps. Another point, I am still trying to figure out exactly how to tell if a machine is (1) PS/2 and (2) Microchannel. Several people have pointed out that INT 15 is supposed to tell you, but I can't find that in my (PC) BIOS manual. Maybe it is something new. Could some kind soul please write a little piece of code that can be added to klib88.s making the call to int15, and then write the C code for using this call to set the variables ps and mca in such a way that it works on PC, XT, AT, and PS/2 (preferably without including a complete expert system in there). Thanks. Andy Tanenbaum (ast@cs.vu.nl)
steve@basser.oz (Stephen Russell) (01/25/89)
In article <1944@ast.cs.vu.nl> ast@cs.vu.nl (Andy Tanenbaum) writes: > >[ ... ] I think the original >design is fairly simple and don't want to muck it up because of the way >the PS/2 does things.) This won't be the first time that a simple system had to be abandoned because of badly-designed hardware :-) >Another point, I am still trying to figure out exactly how to tell if >a machine is (1) PS/2 and (2) Microchannel. Several people have pointed >out that INT 15 is supposed to tell you, Only ref I have is in Thom Hogan's "The Programmer's PC Sourcebook", pp234. INT 0x15, function AH=0xC0 returns a pointer in ES:BX to a "System Descriptor Table". The layout is as follows: Offset Length Description Value 0 Word Size of table in bytes >= 8 2 Byte Model byte See below 3 Byte Submodel byte " 4 Byte BIOS Revision level 00 = first release 5 Byte Features bit 7 HD BIOS uses DMA 3 bit 6 2nd interrupt chip present bit 5 RTC present bit 4 keyboard intercept called bit 3 wait for ext event called bit 2 extended BIOS area alloc'd bit 1 PS/2-type I/O channel bit 0 (Reserved) The rest is reserved. The interesting things are the model bytes and bit 1 of byte 5. Note: According to Hogan, this stuff applies to AT's after 1985 Nov 15, XTs after 1986 Jan 10, all XT286s, Convertibles and PS/2s. His ref is IBM PS/2 and PC BIOS Interface Tech Ref, pp 2-94 to 2-96. On page 197 of Hogan, the model number bytes are described as follows: Model Byte Submodel Revision BIOS Version Machine FF -- -- All IBM PC FE -- -- 8 Nov 82 PC/XT and Portable PC FD -- -- All PCjr FC -- -- 10 Jan 84 AT 00 01 10 Jun 85 AT 01 00 15 Nov 85 AT 04 00 Initial PS/2 Model 50 05 00 Initial PS/2 Model 60 02 00 All PC/XT286 FB 00 01 10 Jan 86 XT 00 02 9 May 86 XT FA 00 00 2 Aug 86 PS/2 Model 30 F9 00 00 13 Aug 85 PC Convertible F8 00 00 Initial PS/2 Model 80 01 00 Initial PS/2 Model 80 FE NA NA Compaq DeskPro 2D NA NA Compaq Portable 9A NA NA Compaq Portable Plus 4B NA NA MegaBIOS ROM B6 NA NA HP110 Portable The machine model byte can also be found at address F000:FFFE. Ref: PS/2 and PC BIOS Tech Ref, page 4-18. So, the strategy to find the machine might be something like this: - Check the model byte at F000:FFFE. - If it's F[BDEF], then it's a PC, XT or Jr. - If it's F8 or FA, it's a PS/2. - If it's FC, could be an AT, XT286 or PS/2 Model 30/50. Early model AT's will not support INT 0x15:0xC0 (carry set on return?). The rest can be differentiated by the submodel/revision bytes. - If it's none of the above, assume a PC clone, and hope for the best! - For PS/2 machines, check bit 1 in byte +5 in configuration block for PS/2 style I/O channels. Now I don't have enough machines around here to test this out, but others on the net may be able to check the details for their machine. Of course, who knows what the clone makers have done. Fortunately, there aren't a lot of PS/2 MCA clones (yet), but let's hope they get the above details right. One worry: why are there 2 model 80's for F8? Mistake in Hogan's table?
gaz@apollo.COM (Gary Zaidenweber) (01/25/89)
From article <1944@ast.cs.vu.nl>, by ast@cs.vu.nl (Andy Tanenbaum): > Steve Ackerman has reported getting MINIX to boot on the PS/2 Model 80. > Good work! However, we are not really done yet. I have to figure out > how to deal with level-triggered interrupts in a reasonable way. This > message solicits suggestions. Please post them, since 10K heads are > better than 1. > > MINIX, like all other message passing operating systems, does not do much > in its interrupt routines. It just sends a message and returns from the > interrupt. This means that after a floppy disk interrupt, the interrupt > line would normally still be asserted. However, to shut off the 8259A > interrupt controller, on line 1888, we order it to shut up. On the PS/2 > this doesn't work. We have to actually talk to the device. It is > probably unwise to do this inside the interupt() function. This means > we have to move line 1888 to each device driver and do it there. Unpleasant > but possible. In my opinion, level-triggered interrupts are far preferable to edge-triggered ones. One approach might be to rethink the definition of "does not do much in its interrupt routines" and the explicit and implicit content of messages. I'm sorry that I haven't looked at the code, but I have both designed and coded drivers for many types of network devices in a multitasking OS. > > However, things are worse than this. If we delete line 1888 and move it > to the device drivers, when the interrupt routine is finished, we will get > another interrupt. To prevent this, Steve diddled the 8259A's interrupt > mask around line 1888. Double ugly. Again, my opinion, the interrupt dispatcher should be returned to by the interrupt routine after its execution and the dispatcher will diddle such machine-dependent hardware as the 8259A. It knows which routine was dispatched. Well-designed controllers should be able to queue level-triggered interrupts. > > My question is: does anybody see a better and cleaner way to do this? > I don't especially want the code around line 1888 having to figure out > which of the 8259A's to diddle, and which bit, etc. For the floppy it > may not be too bad, but for serial I/O, networking, etc, it will make > things more complicated and error prone in a sensitive area. On the other > hand, I don't want a major redesign of things. I think the original > design is fairly simple and don't want to muck it up because of the way > the PS/2 does things.) I'd also like to minimize the amount of code of the sort My above suggestions, unfortunately, do add a bit of complexity with the payoff of "nearly infinite :-)" flexibility. > > if (ps) /* Models 25 - 80 */ > if (mca) ... /* microchannel architectures only */ > if (ps && mca == FALSE) ... /* Models 25 and 30 */ > etc. > > Hardware types, get out your thinking caps. > > Another point, I am still trying to figure out exactly how to tell if > a machine is (1) PS/2 and (2) Microchannel. Several people have pointed > out that INT 15 is supposed to tell you, but I can't find that in my > (PC) BIOS manual. Maybe it is something new. Could some kind soul please > write a little piece of code that can be added to klib88.s making the > call to int15, and then write the C code for using this call to set the > variables ps and mca in such a way that it works on PC, XT, AT, and PS/2 > (preferably without including a complete expert system in there). Thanks. > > Andy Tanenbaum (ast@cs.vu.nl) -- Gary Zaidenweber | It's nice to know that if someone gets UUCP: umix!apollo!gaz | caught shredding the constitution, that ARPA: gaz@apollo.COM | you can at least charge him with littering. AT&T: +1 508 256 6600 | -- Jay Leno