Page 1 of 1

keyboard works in emulator, but not physical machine

Posted: Wed Feb 13, 2013 7:37 pm
by Caleb1994
Hey guys,

I can't figure out what I'm doing wrong with this. I've written a PS2 keyboard driver, and it works great in Qemu, Bochs, and VirtualBox, but it doesn't work on a physical machine. It's a really simple driver here is the initialization code:

Code: Select all

register_irq(PS2_KEYBOARD_IRQ, keyboard_irq);
unmask_irq(PS2_KEYBOARD_IRQ);
ps2_enable(0); // enable ps2 port 0
flush_keyboard(); // flush the current buffer
ps2_enable_translation(0); // enable translation on port 0
ps2_enable_interrupt(0); // enable interrupts on port 0
and here is the general ps2 initialization code:

Code: Select all

ps2_disable(0);
ps2_disable(1);
ps2_flush_buffer();
ps2_disable_interrupt(0);
ps2_disable_interrupt(1);
ps2_disable_translation(0);
ps2_disable_translation(1);

if( !ps2_clock_enabled(1) )
     ps2_dual_channel = 0;

u8 test = ps2_test();
if( test != 0x55 ){
     PANIC("PS/2 Controller Self Test Failed!");
}

if( ps2_dual_channel )
{
     ps2_enable(1);
     if( ps2_clock_enabled(1) )
          ps2_dual_channel = 0;
     ps2_disable(1);
}

test = ps2_test_port(0);
if( test != 0x00 ) PANIC("First PS/2 Port Test Failed!");
if( ps2_dual_channel )
{
     test = ps2_test_port(1);
     if( test != 0x00 )
          PANIC("Second PS/2 Port Test Failed!");
}

ps2_enable(0);
if( ps2_dual_channel ) ps2_enable(1);
all the ps2_* functions do exactly what they seem to, and most simply take an integer value for either port 0 or port 1.

I am getting no input from the keyboard when I run it on my desktop from a flash drive. Any ideas?

Re: keyboard works in emulator, but not physical machine

Posted: Wed Feb 13, 2013 8:14 pm
by Brendan
Hi,
Caleb1994 wrote:I am getting no input from the keyboard when I run it on my desktop from a flash drive. Any ideas?
Does a real PS/2 keyboard exist? I'm guessing it doesn't and it's actually a USB keyboard, and you're relying on the "dodgy beyond belief" PS/2 emulation the firmware tries to do.

I'm also a little curious about "ps2_disable_translation(1);". There can't be any translation for port 1 to disable.

Finally, are you sure it's not just "PIC jam". Some boot loaders (e.g. GRUB) disable IRQs in a bad way, that tends to cause IRQs to become stuck in the PIC chips (where an old IRQ will prevent the same IRQ and lower priority IRQs from being delivered to the CPU, but the old IRQ won't be delivered either). The normal fix for this is sending a few dummy EOIs to the PIC chips after you've initialised them.


Cheers,

Brendan

Re: keyboard works in emulator, but not physical machine

Posted: Wed Feb 13, 2013 8:29 pm
by Caleb1994
Brendan wrote:Does a real PS/2 keyboard exist? I'm guessing it doesn't and it's actually a USB keyboard, and you're relying on the "dodgy beyond belief" PS/2 emulation the firmware tries to do.
Yes, I am using a PS/2 keyboard.
Brendan wrote:I'm also a little curious about "ps2_disable_translation(1);". There can't be any translation for port 1 to disable.
Ah, yes. I mistyped. My development machine is current not connected to the internet, so I was typing the code into the post while reading it from my other screen. My hands just decided they were going to type a second translation line... #-o
Brendan wrote:Finally, are you sure it's not just "PIC jam". Some boot loaders (e.g. GRUB) disable IRQs in a bad way, that tends to cause IRQs to become stuck in the PIC chips (where an old IRQ will prevent the same IRQ and lower priority IRQs from being delivered to the CPU, but the old IRQ won't be delivered either). The normal fix for this is sending a few dummy EOIs to the PIC chips after you've initialised them.
Interesting, I had never heard of that. I will test that later when I get back to my computer. Thanks for the help!

UPDATE:

I've tried sending some EOIs to the PICs just after initialization, but it did not help. I did learn something, though. On my laptop (Dell Latitude E6420), the keyboard works fine, so it is something funny with that particular machine. I've looked through the BIOS settings and nothing jumps out at me (I actually couldn't find anything relating to PS/2 at all).

Re: keyboard works in emulator, but not physical machine

Posted: Sun Feb 17, 2013 7:23 pm
by chaoscode
Well, sometimes the options in the bios are called "USB keyboard emulation" or something similar.
Are you using a PS2keyboard or a USB?
Maybe PS/2 Port 0 is real PS2 Keyboard and
port 1(2/3?) is PS2 Emulated USBKeyboard.
Or Mouse and Keyboard are changed?

Re: keyboard works in emulator, but not physical machine

Posted: Sat Feb 23, 2013 4:46 pm
by Caleb1994
chaoscode wrote:Well, sometimes the options in the bios are called "USB keyboard emulation" or something similar.
Are you using a PS2keyboard or a USB?
Maybe PS/2 Port 0 is real PS2 Keyboard and
port 1(2/3?) is PS2 Emulated USBKeyboard.
Or Mouse and Keyboard are changed?
Yes I am using a PS/2 Keyboard. There are only 2 PS/2 Ports: one for mouse and one for keyboard. I have tried plugging the keyboard into the PS/2 port designated as the mouse port, and there was no change. There is no option in the BIOS related to PS/2 emulation.

Re: keyboard works in emulator, but not physical machine

Posted: Sun Feb 24, 2013 12:38 am
by Brendan
Hi,
Caleb1994 wrote:Yes I am using a PS/2 Keyboard. There are only 2 PS/2 Ports: one for mouse and one for keyboard. I have tried plugging the keyboard into the PS/2 port designated as the mouse port, and there was no change. There is no option in the BIOS related to PS/2 emulation.
There can only be about 7 problems:
  • USB emulation not turned off USB controller/s (combined with a crappy BIOS that doesn't give you an option, and does this emulation even when no USB keyboard is present). Maybe try physically removing the USB controllers (if it's an old computer and they're on a PCI card) or disabling the USB controller/s in the BIOS (if there's an option).
  • PS/2 controller configuration problems - e.g. the clock for the PS/2 port left disabled, or the input buffer full
  • PS/2 controller hardware failure. Does the PS/2 controller "self test" command work? Do the "interface test" commands work? Does it work in other OSs?
  • PS/2 device configuration problems - e.g. is scanning disabled?
  • PS/2 device hardware failure. Does the PS/2 device respond to the reset command? How about the "identify" command, or maybe the "echo" command? Do they work in other OSs?
  • IRQ delivery problems (e.g. IRQs disabled in the CPU or messed up PIC chip). Do other IRQs (e.g. PIT) work correctly? Does polling (e.g. "in al,0x60") work?
  • Is the PS/2 controller "PC compatible" compatible? It should be, but maybe the chipset is silly (and some laptops are silly - e.g. extra non-standard stuff to handle port switching between built-in devices and external devices). It might be worthwhile getting the chipset's datasheet and checking that everything is sane (and that there's no errata).
Note: The code you posted earlier doesn't really help me a lot - it's just lines of code that call functions, where I don't know where the "lines of code" come from or what any of the functions being called actually do. I'd suggest comparing it to the "Initialisation" section of the PS/2 controller wiki page and making sure that *everything* has time-outs, etc.


Cheers,

Brendan

Re: keyboard works in emulator, but not physical machine

Posted: Sun Feb 24, 2013 3:39 am
by rdos
Another possibility:
http://forum.osdev.org/viewtopic.php?p=203069#p203069
The reason why two different Intel processors (a core duo and 4 core) have not worked in RDOS is because I changed from "Fixed delivery" to "Lowest priority delivery" for ISA interrupts (among them, the PS/2 keyboard IRQ).
Other than that, I know that the timing in the IRQ can cause problems, but I don't know exactly what this problem is related to. I only know I had issues with this in the beginning, that have been solved by "trial-and-error".

Re: keyboard works in emulator, but not physical machine

Posted: Mon Feb 25, 2013 3:36 am
by gerryg400
Something to be aware of is that real PS/2 devices can take quite some time to reset. And they don't all reply with the 0xfa that you might expect. Try something like this ...

Code: Select all

        ps2_data_write(0, 0xff);
        /* Get the reset result */
        syslog(0, "Kbd: Waiting for reset...\n");
        do {
            status = ps2_data_read();
        } while (status != 0xaa);
Obviously you don't want to stay in the loop forever so have a means of breaking the loop.

Also don't forget to read the mouse ID from the 2nd port.