Hi,
Osbios wrote:Brendan wrote:The normal terminology sucks. The "keyboard controller" is mostly a chip that controls 2 serial ports (and keyboards and mouses are just devices that plug into these serial ports), however these serial ports are not RS-232 or 16550/8250 compatible. To avoid confusion I call it a "PS/2 controller" because in modern machines it controls the PS/2 ports, and it may or may not control any keyboards (for example, you could have a bar-code scanner and a mouse).
But that would also be misleading. The KBC controls more then the PS/2 connectors. Like parts of the speaker, A20 Gate, ...
You can't really call it the "miscellaneous crud controller"...
IMHO "PS/2 controller" is a good compromise between least confusing and most accurate, especially when you consider my main intention is to avoid confusing the "PS/2 controller" (e.g. an 8042 microcontroller or it's modern counterpart) with the controller chip that's built into the keyboard (e.g. an 8048 microcontroller or it's modern counterpart - the one that scans the keys/switches and talks to the PS/2 controller, and controls the keyboard).
Osbios wrote:Brendan wrote:There are differences between PS/2 controllers - some don't have a second PS/2 port, and some don't let you turn of the "scancode set 2 -> scancode set 1" translation for the first PS/2 port.
I was assuming the disability of turning of the scancode translation was the fault of the USB-Legacy support. But I can be wrong.
I've heard that the legacy keyboard emulation done by USB keyboards doesn't allow the scancode translation to be disabled. I've also heard that (at least for some motherboards) the legacy emulation doesn't reliably support other things (like resetting the computer). This is one of the reasons that it's important to find USB keyboards and disable the legacy keyboard emulation *before* doing anything with the PS/2 controller.
When I was doing my PS/2 code (about 4 years ago) I found that Bochs didn't allow the scancode translation to be disabled. I'm not sure if newer versions of Bochs allow scancode translation to be disabled or not, and don't know about other emulators. I also don't remember if any real computers had the same problem (I'm unsure about an 80486 computer I've got).
I do remember that my old 80486 computer only supported one PS/2 port, and that attempts to do things with the second PS/2 port actually effected the first PS/2 port (for e.g. an attempt to send an "identify device" command to the second PS/2 port would result in data arriving from the device connected to the first PS/2 port).
Osbios wrote:Brendan wrote:In the past I've written code that auto-detects the PS/2 controller type (while doing full initialization and fault testing), then auto-detects what type/s of devices are connected to the PS/2 port/s (if any). This code also allowed any device in any port (e.g. keyboard in second PS/2 port, mouse in first PS/2 port, a pair of keyboards, a pair of mouses, etc). Except for the "scancode set 2 -> scancode set 1" translation for the first PS/2 port (which can normally be disabled) there is almost no difference between the PS/2 ports.
I also wrote a detecting routine for both ports independent from the combination of keyboard or mouses. But I'm very interested in the PS/2 controller detection! Do you still have it and can share it with us?
I might still have it in some form or another (I've got a directory on one computer that has 21 different versions/prototypes of my OSs, some versions/prototypes have been lost, and some are on other computers). However, if I find it I doubt it'd help much - it's "OS specific" (it relies on a kernel API, etc that I no longer remember) and I threw it away for good reasons. Basically I thought it was good at the time, but that was 4 years ago and I've learnt enough since then to realize that it's well below my current standards.
I did look for this code but what I found was a later version of it; and in this later version I'd gone back to "no mouse allowed in first PS/2 port". IIRC there were a few reasons for this - problems with Bochs, problems with BIOSs that assume a keyboard is in the first PS/2 port and generate a "Keyboard error" and won't boot, and problems with Windows (either Windows 95 or Windows 98, I don't remember which) where Windows would lock up during boot if a mouse was in the first PS/2 port.
This code takes the following steps:
- - get PS/2 controller's configuration byte (command 0x20 sent to PS/2 controller)
- send a new PS/2 controller configuration byte (command 0xA0 sent to PS/2 controller, then the configuration byte previously read with IRQs disabled and scancode translation enabled)
- disable device A (send command 0xF5 to device A and wait for "ACK")
- disable device B (send command 0xF5 to device B and wait for "ACK")
- do device A interface test (command 0xAB sent to PS/2 controller)
- do device B interface test (command 0xA9 sent to PS/2 controller)
- reset device A (send command 0xFF to device A) and get results of BAT from device (if any)
- reset device B (send command 0xFF to device B) and get results of BAT from device (if any)
- allocate IRQs if any (IRQ 1 if "device A" wasn't disabled, and IRQ 12 if "device B" wasn't disabled) or kill the driver if both devices disabled
At every step there's time-outs and error detection, where (if there's a time-out or error) either the entire driver was killed (mostly in earlier steps), support for device A was disabled or support for device B was disabled. PS/2 controllers that didn't support the second PS/2 port failed at some stage in this (not sure which step, probably the "device B interface test") resulting in support for the second PS/2 port being disabled.
The end result was (hopefully) a 32-bit dword for each device containing the (one byte, 2 bytes or 3 bytes of) data it returned from BAT. There's also some code to correct this 32-bit ID for Bochs: apparently the mouse in Bochs only sent "ACK" and didn't send "ACK then 0x00" like a normal 2-button mouse, so I had some "%ifdef BOCHS" followed by "if(ID == 0x000000FA) then ID = 0x0000FA00" and "%endif" as a work-around.
Note: Unfortunately, if the PS/2 controller won't allow scancode translation to be disabled then it's impossible to reliably reconstruct the device's original data from the data you receive from the PS/2 controller.
Osbios wrote:Brendan wrote:Lastly, it'd be good to treat PS/2 devices as "hot-plug" devices....
I do the same in software. But don't forget some board will go nuts if you unplug and plug PS/2 devices.
Good "hot plug PS/2" support would include checking for "device removed" at regular intervals (e.g. every 5 seconds); and when you get a BAT (indicating "device inserted") from a device, checking if the device is the same device that was previously connected and (if it is) resetting prior state (e.g. so that if you unplug a keyboard and plug the same keyboard back in you don't lose the typematic rate, LED states, etc).
I only did part of this (ie. supported re-insertion of the same device, without supporting insertion of a different device or detecting "device removed") because I needed that to work - I was using old style KVM switch (a mechanical rotary switch, that disconnected and reconnected the keyboard, mouse and video when you selected a different computer).
Combuster wrote:We have what everybody needs to get started. If we want to do more, we RTFM, and so should you. I don't have all the answers, do you?
At this level of detail there is no single manual. Instead there's a large number of different datasheets from different manufacturers about different controllers and different chipsets, that all mostly (but not entirely) say the same things. I had limited information (more than most people collect I guess, but much less than "everything") but I doubt anyone could obtain all the information for all PS/2 controllers and still have enough enthusiasm left to read them all and find the differences.
I mostly did the programmer's equivalent of shaking a mysterious cardboard box trying to guess the contents - trial and error using educated guesses (based on the information I did have).
I should also point out that most OS developers don't do any of the things I do - they assume the PS/2 controller works, assume the BIOS's configuration is "good enough", assume a PS/2 keyboard (if any) is connected to the first PS/2 port (and assume it works), and assume a PS/2 mouse (if any) is connected to the second PS/2 port (and assume it works). Basically a lot of people just slap an IRQ handler onto IRQ1 and IRQ12 and do no testing or low level initialization. In this case there's plenty of information...
Cheers,
Brendan