kbd controller ; wiki question

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
mtbro
Member
Member
Posts: 54
Joined: Fri Apr 08, 2022 3:12 pm

kbd controller ; wiki question

Post by mtbro »

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?
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: kbd controller ; wiki question

Post by nullplan »

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?
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.
Carpe diem!
mtbro
Member
Member
Posts: 54
Joined: Fri Apr 08, 2022 3:12 pm

Re: kbd controller ; wiki question

Post by mtbro »

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..
Octocontrabass
Member
Member
Posts: 5562
Joined: Mon Mar 25, 2013 7:01 pm

Re: kbd controller ; wiki question

Post by Octocontrabass »

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?
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.

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.
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?
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: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?
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
Member
Member
Posts: 54
Joined: Fri Apr 08, 2022 3:12 pm

Re: kbd controller ; wiki question

Post by mtbro »

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.
Oh, ok. This does make it more clear to me.
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.
mtbro
Member
Member
Posts: 54
Joined: Fri Apr 08, 2022 3:12 pm

Re: kbd controller ; wiki question

Post by mtbro »

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 ..
mtbro wrote:I thought all PS/2 controllers used mini-din connectors.
It turns out my board PC100 BXcel really has ps/2 controller and 5-din connector.
Octocontrabass
Member
Member
Posts: 5562
Joined: Mon Mar 25, 2013 7:01 pm

Re: kbd controller ; wiki question

Post by Octocontrabass »

mtbro wrote:How can I distinguish between a scancode and the answer from the keyboard ?
The keyboard will always answer before it sends any more scan codes.
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?
No, you don't need to do that. Just send the command.
mtbro wrote:PC100 BXcel
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
Member
Member
Posts: 54
Joined: Fri Apr 08, 2022 3:12 pm

Re: kbd controller ; wiki question

Post by mtbro »

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.
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.
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.
Unfortunately I threw away any older boards I had so this is the oldest I can use for tests.
mtbro
Member
Member
Posts: 54
Joined: Fri Apr 08, 2022 3:12 pm

Re: kbd controller ; wiki question

Post by mtbro »

Octocontrabass wrote:No, you don't need to do that. Just send the command.
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.
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 ?
Octocontrabass
Member
Member
Posts: 5562
Joined: Mon Mar 25, 2013 7:01 pm

Re: kbd controller ; wiki question

Post by Octocontrabass »

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 ?
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
Member
Member
Posts: 54
Joined: Fri Apr 08, 2022 3:12 pm

Re: kbd controller ; wiki question

Post by mtbro »

Thanks for confirmation.
mtbro
Member
Member
Posts: 54
Joined: Fri Apr 08, 2022 3:12 pm

Re: kbd controller ; wiki question

Post by mtbro »

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.
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.

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.
Octocontrabass
Member
Member
Posts: 5562
Joined: Mon Mar 25, 2013 7:01 pm

Re: kbd controller ; wiki question

Post by Octocontrabass »

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.
mtbro
Member
Member
Posts: 54
Joined: Fri Apr 08, 2022 3:12 pm

Re: kbd controller ; wiki question

Post by mtbro »

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..
Octocontrabass
Member
Member
Posts: 5562
Joined: Mon Mar 25, 2013 7:01 pm

Re: kbd controller ; wiki question

Post by Octocontrabass »

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.
But commands are also handled by the keyboard driver, aren't they?
Post Reply