Hi,
Lephe wrote:
I now have a clearer understanding of what PS/2 emulation does, thanks. Originally my PS/2 driver initialization routine (roughly) performs a controller self-test, then checks for dual channels, performs interface tests, looks for devices, resets and finally enables them. Considering your answers, I don't feel very safe using this procedure on a machine with a motherboard-emulated PS/2 controller. Would the following be appropriate for keyboard detection?
- Boot the kernel without doing anything related to PS/2
- Disable PS/2 emulation in the USB controller
- Check for a real PS/2 controller and (possibly) a PS/2 keyboard
- Then check for USB keyboards
For device enumeration in general (not PS/2 alone); my OS is designed to:
- Go through all the PCI devices; disable all "legacy emulation" possible (including "PS/2 emulation" in USB controllers, legacy ISA emulation in hard disk controllers, legacy VGA emulation in video controllers, ...); and then completely disable the devices themselves (so that they don't respond to anything on the PCI bus except PCI configuration space accesses).
- Do any manual detection of ancient ISA and legacy devices (e.g. ISA cards, floppy controller, serial ports, parallel ports, PS/2 controller, etc) after I'm sure that nothing modern can interfere with the manual detection.
- Start any drivers needed for ancient ISA and legacy devices
- Go through all the PCI devices a second time; trying to find device drivers for them and "re-enabling" the devices if a driver is found (as part of the device driver initialisation).
Lephe wrote:
The other thing that bothers me is that according to the wiki, PS/2 controllers must be detected through ACPI before being used. But ACPI (and here I mean ACPICA which seems the most reasonable option to me) requires fairly advanced memory management, multithreading and scheduling (advanced features only?); I'm far from supporting all of this. May my OS crash from trying to use an non-existing PS/2 controller until I support ACPI?
ACPI can be split into 2 parts - reading stuff from tables (FADT, APIC/MADT, SLIT, SRAT, etc) during boot, and the run-time AML (ACPI Machine Language). The tables (during boot) are simple/easy and don't require much work at all. The run-time AML is a hideous nightmare.
Determining if a PS/2 controller exists is the former (just reading a single flag from a table) and doesn't involve anything complicated.
Lephe wrote:
Finally, since Brendan bothered to list some ways in which an OS can fail to properly manipulate devices, I'd like to know if the following solutions are suitable:
- Existence of PS/2 controller → ACPI tables?
- Correct operation of PS/2 controller → Controller self-test?
- Existence and "location" of PS/2 keyboard → Interface tests and Identify commands?
- Correct operation of PS/2 keyboard → Keyboard self-test?
- Hot-plug PS/2 → Wiki explains it, I'll check it out.
- USB driver → That would be for later on
As a generic guideline; about 50% of a driver's code should be to detect and handle things that should never happen. Code to test the correct operation of the PS/2 controller would include the controller's self test feature and the interface tests; but there'd also be time-outs throughout the controller's initialisation code and various other checks. For example; if you're following the
initialisation sequence described here, then you could check if the first PS/2 port is disabled (as expected) during "step 5", you'd have a time-out for "step 6" (in case the controller doesn't respond to the self test at all) and also in "step 7" (in case there's no response from the interface tests), etc. Any kind of abnormality would be treated as a "controller not operating correctly", until you reach "step 10" (which is the end of PS/2 controller initialisation and the beginning of PS/2 device initialisation).
Once the PS/2 controller is tested and initialised; you'd ask each PS/2 device what it is, and start a driver for whatever the device in each port says it is (e.g. if the device plugged into the second PS/2 port says that it's a keyboard, then you'd start a PS/2 keyboard driver for the device plugged into second PS/2 port).
The keyboard self-test (its response to the "reset" command) is the main test; but again there's a lot of time-outs (a time-out for every command sent to keyboard) and additional checks you can do (e.g. after the "set scancode set" command you could use the "get current scancode set" to check if the keyboard did the command properly); and then (during initialisation and at any time after that) the keyboard can send you a "key detection error or internal buffer overrun" status code.
Cheers,
Brendan