kbd controller ; wiki question
kbd controller ; wiki question
I'm going through the ps/2 controller setup routine __init_kbd_module() and checking the wiki's section on " Initialising the PS/2 Controller".
Article says in step #3 to disable devices, in step #5 to toggle bits of interest (such as disable translation). It mentions here we can check bit5 for possible 2nd port of ps/2 controller. But in step #3 we disabled both ports, it's expected both bits4,5 will be set to 1(disabled) as we did so in step 3.
Did I miss something here?
If I can sneak another question in. There seems to be more ways how one can disable a port. On ctrl side I can send direct command 0xAD to ctrl, I can send confbyte with proper bit mask set. I can even do so by sending encoder (0x60) command 0xf5. It does confuse me a bit. Are those first two approaches the same?
With the last one I did a test on real HW with AT connector (din5) with ps/2 keyboard. I disabled it with 0xf5 command (port 0x60). I then unplugged the keyboard (I know AT/ps2 keyboards are not meant for it) and later plugged in. I thought encoder would be in its "cold" state and it gets enabled again. It doesn't. Does this mean that even doing the 0xf5 command does the same as those two above?
Article says in step #3 to disable devices, in step #5 to toggle bits of interest (such as disable translation). It mentions here we can check bit5 for possible 2nd port of ps/2 controller. But in step #3 we disabled both ports, it's expected both bits4,5 will be set to 1(disabled) as we did so in step 3.
Did I miss something here?
If I can sneak another question in. There seems to be more ways how one can disable a port. On ctrl side I can send direct command 0xAD to ctrl, I can send confbyte with proper bit mask set. I can even do so by sending encoder (0x60) command 0xf5. It does confuse me a bit. Are those first two approaches the same?
With the last one I did a test on real HW with AT connector (din5) with ps/2 keyboard. I disabled it with 0xf5 command (port 0x60). I then unplugged the keyboard (I know AT/ps2 keyboards are not meant for it) and later plugged in. I thought encoder would be in its "cold" state and it gets enabled again. It doesn't. Does this mean that even doing the 0xf5 command does the same as those two above?
Re: kbd controller ; wiki question
If the controller has no second port, it will not implement the disable bit, and therefore you read back a 0 bit even if you wrote it to 1 before.mtbro wrote:Article says in step #3 to disable devices, in step #5 to toggle bits of interest (such as disable translation). It mentions here we can check bit5 for possible 2nd port of ps/2 controller. But in step #3 we disabled both ports, it's expected both bits4,5 will be set to 1(disabled) as we did so in step 3.
Did I miss something here?
Carpe diem!
Re: kbd controller ; wiki question
These bits (bits4,5) have inverted logic - 1 is disabled, 0 is enabled. But according to wiki the first step should be to disable both of them. Fine with the 2nd one if it doesn't exist, it won't do anything. If it does exist it will get disabled. But step 5 says to read the control byte and use that to decide if the bit is or isn't set. But due to the actions in step 3 both will be disabled.
I tried to boot my code also on a system with ps/2 controller with two ps/2 ports and it works as I'm describing. Unless I'm missing something..
I tried to boot my code also on a system with ps/2 controller with two ps/2 ports and it works as I'm describing. Unless I'm missing something..
-
- Member
- Posts: 5562
- Joined: Mon Mar 25, 2013 7:01 pm
Re: kbd controller ; wiki question
Despite the article's name, it actually covers two types of keyboard controllers: PS/2 keyboard controllers and AT keyboard controllers. A PS/2 keyboard controller uses bit 5 to enable or disable the mouse port, and commands 0xA7 and 0xA8 will change bit 5. An AT keyboard controller uses bit 5 to switch between XT and AT keyboard compatibility, and commands 0xA7 and 0xA8 will not change bit 5.mtbro wrote:But in step #3 we disabled both ports, it's expected both bits4,5 will be set to 1(disabled) as we did so in step 3.
Did I miss something here?
On an AT keyboard controller with an AT (or PS/2) keyboard plugged in, bit 5 will be 0, so this is the step where you'll usually be able to tell whether the keyboard controller is AT or PS/2.
Yes, the first two approaches both set bit 4 of the keyboard controller's configuration byte. Sending 0xF5 to the keyboard tells the keyboard to stop sending scan codes, but does not affect the keyboard controller.mtbro wrote:There seems to be more ways how one can disable a port. On ctrl side I can send direct command 0xAD to ctrl, I can send confbyte with proper bit mask set. I can even do so by sending encoder (0x60) command 0xf5. It does confuse me a bit. Are those first two approaches the same?
The keyboard may have detected an error while you were plugging it in, which will stop scanning. Also, if the keyboard is old enough, it may automatically switch between XT and AT mode, and hotplug may have caused it to incorrectly switch to XT mode while the keyboard controller is still expecting an AT keyboard.mtbro wrote:I thought encoder would be in its "cold" state and it gets enabled again. It doesn't. Does this mean that even doing the 0xf5 command does the same as those two above?
Re: kbd controller ; wiki question
Oh, ok. This does make it more clear to me.Octocontrabass wrote:On an AT keyboard controller with an AT (or PS/2) keyboard plugged in, bit 5 will be 0, so this is the step where you'll usually be able to tell whether the keyboard controller is AT or PS/2.
What I'm surprised though is that my old HW with din5 connector on board is then PS/2 controller as it does react to a7 command. I thought all PS/2 controllers used mini-din connectors.
Re: kbd controller ; wiki question
While I was testing my /fragile/ init code I decided to stress test it: on purpose I was pressing random keys during init function to see what it does. Following the wiki's advice I wanted to send the reset (0xff) command to a keyboard (write port 0x60) and check the results. And that's where I hit a problem: How can I distinguish between a scancode and the answer from the keyboard ? I know there's no scancode 0xfa so I know it's an ack. But if I'm using scancode 1 0xaa could be shift being released.
Do I need to disable the keyboard if I want to send and recv proper answers from the controller and keyboard? So when during normal operation(irq1 enabled) user presses numlock to toggle the LED I need to temporarily disable interrupts on this line, disable keyboard in controller and then send command? Or am I overcomplicating this now ..
Do I need to disable the keyboard if I want to send and recv proper answers from the controller and keyboard? So when during normal operation(irq1 enabled) user presses numlock to toggle the LED I need to temporarily disable interrupts on this line, disable keyboard in controller and then send command? Or am I overcomplicating this now ..
It turns out my board PC100 BXcel really has ps/2 controller and 5-din connector.mtbro wrote:I thought all PS/2 controllers used mini-din connectors.
-
- Member
- Posts: 5562
- Joined: Mon Mar 25, 2013 7:01 pm
Re: kbd controller ; wiki question
The keyboard will always answer before it sends any more scan codes.mtbro wrote:How can I distinguish between a scancode and the answer from the keyboard ?
No, you don't need to do that. Just send the command.mtbro wrote:Do I need to disable the keyboard if I want to send and recv proper answers from the controller and keyboard? So when during normal operation(irq1 enabled) user presses numlock to toggle the LED I need to temporarily disable interrupts on this line, disable keyboard in controller and then send command?
That's from the very end of the Baby AT form factor when all motherboards were designed with ATX in mind and the Baby AT version was an afterthought. I'm not surprised it has a PS/2 controller.mtbro wrote:PC100 BXcel
Re: kbd controller ; wiki question
Ok, thank you. I need to do more testing, especially those when I keep pressing keys during init as I think it messes up my expectation on what should keyboard return on a successful BAT test.
Unfortunately I threw away any older boards I had so this is the oldest I can use for tests.
My confusion stems from the fact it has DIN5 connector. Till now I thought if it had din5 connector on the outside it had AT controller inside.Octocontrabass wrote:That's from the very end of the Baby AT form factor when all motherboards were designed with ATX in mind and the Baby AT version was an afterthought. I'm not surprised it has a PS/2 controller.
Unfortunately I threw away any older boards I had so this is the oldest I can use for tests.
Re: kbd controller ; wiki question
I tried to stress my init code more; it works as (I) expected. I wanted to see if I can mess up the init by pressing random keys on keyboard during its run.Octocontrabass wrote:No, you don't need to do that. Just send the command.
On real HW it takes some time for keyboard encoder to send the result of the reset. I thought I have only two options: poll and wait till I get response or read the response later when IRQ is triggered. I actually poll for a while and give up after that. I've seen ISR is later triggered with the 0xaa in the buffer. During the test though the answer to the command (0xaa) was always the first in the read buffer.
Is my assumption correct that once keyboard ACKs (0xfa) the command it internally ignores user inputs on keys while command is being executed ?
-
- Member
- Posts: 5562
- Joined: Mon Mar 25, 2013 7:01 pm
Re: kbd controller ; wiki question
As far as I know, that's correct. But even if the keyboard doesn't ignore inputs, it still won't send any scan codes between receiving the first byte of a command and sending the last byte of its response.mtbro wrote:Is my assumption correct that once keyboard ACKs (0xfa) the command it internally ignores user inputs on keys while command is being executed ?
Re: kbd controller ; wiki question
Thanks for confirmation.
Re: kbd controller ; wiki question
This is what I'm fighting with for few days. While all ok on qemu real HW is giving me hard time. I messed up my code so much I'm a bit ashamed to share it; probably need to do a full rewrite on it.Octocontrabass wrote:it still won't send any scan codes between receiving the first byte of a command and sending the last byte of its response.
I thought I'd keep state of the command (such as "in queue", "waiting for ack", "waiting for data"..) and have keyboard's ISR deal with it. There's problem though, it takes time for encoder to register the command. So even when I use kbde_poll_write() there's the delay after out instruction for encoder to register it. So while my code thinks I'm already executing command it's not true. If I keep pressing keys on keyboard I can mess up the command execution. I don't want to poll in ISR, that seems bad.
Small delays (out to port 0x80) is not enough.
-
- Member
- Posts: 5562
- Joined: Mon Mar 25, 2013 7:01 pm
Re: kbd controller ; wiki question
You don't need to worry about delays. The keyboard sends a response for every byte you send. You can tell the command has started when you receive the 0xFA response for the first byte of the command.
Re: kbd controller ; wiki question
I did upload my commit though I know it's bad. In my kbd_isr_handler() I was trying to split scancodes into two buffer: one for commands only and one that will be for kbd driver to deal with. I don't need to store encoder's answers per se but I wanted to have them stored for debug purposes on real HW. I'm getting familiar with some commands this way.
My goal was to avoid checking if scancode read in ISR is 0xfa (or others such as 0xfe). I thought I could sort it and let the proper function deal with it. kbdc_handle_command() was my idea of handling command. It does work but it has that problem I mentioned. I can't assume command is being executed before I receive ack on it. So back to drawing board..
My goal was to avoid checking if scancode read in ISR is 0xfa (or others such as 0xfe). I thought I could sort it and let the proper function deal with it. kbdc_handle_command() was my idea of handling command. It does work but it has that problem I mentioned. I can't assume command is being executed before I receive ack on it. So back to drawing board..
-
- Member
- Posts: 5562
- Joined: Mon Mar 25, 2013 7:01 pm
Re: kbd controller ; wiki question
But commands are also handled by the keyboard driver, aren't they?mtbro wrote:I was trying to split scancodes into two buffer: one for commands only and one that will be for kbd driver to deal with.