OSDev.org
https://forum.osdev.org/

Setting the Scan Code set
https://forum.osdev.org/viewtopic.php?f=1&t=32615
Page 1 of 1

Author:  zvoncika [ Sun Dec 03, 2017 10:16 am ]
Post subject:  Setting the Scan Code set

I'm using the following code to try and set the Scan Code set ( 2 ).
Code:
outb(0x60,0xF0);
   outb(0x64,0x02);

However,when I try to boot my OS in QEMU or VirtualBox they both reset.
Bochs doesn't.
What am I doing wrong here?
Here is my init function:
Code:
void ps2_keyboard_install()
{
   while(inb(PS2_KB_CMD) & 0x1)
      inb(PS2_KB_DATA);
   // Test the PS/2 controller
   outb(PS2_KB_CMD,0xAA);
   if(inb(PS2_KB_DATA) != 0x55)
   {
      // PS/2 Controller test failed
      // Kernel Panic
      asm volatile("int $19");
   }
   // Test the first port
   outb(PS2_KB_CMD,0xAB);
   if(inb(PS2_KB_DATA) != 0x00)
   {
      // First port didn't pass the test
      // Kernel Panic
      asm volatile("int $19");
   }
   // Enable the first port
   outb(PS2_KB_CMD,0xAE);
   // Set SCS
   outb(PS2_KB_CMD,0xF0);
   outb(PS2_KB_DATA,0x02);
   // Get config
   outb(PS2_KB_CMD,0x20);
   uint8_t cfg = (inb(PS2_KB_DATA) | 1) & ~0x10;
   // Set config
   outb(PS2_KB_CMD,0x60);
   outb(PS2_KB_DATA,cfg);
   // Set scan code set
   // Install our handler
   irq_install_handler(1, ps2_keyboard_handler);
}

Author:  Octocontrabass [ Sun Dec 03, 2017 1:16 pm ]
Post subject:  Re: Setting the Scan Code set

Code:
outb(0x60,0xF0);
   outb(0x64,0x02);

This code sends the first byte to the keyboard, and then (without waiting for the keyboard controller to send that byte to the keyboard or receive the keyboard's response) sends an undocumented command to the keyboard controller. This code does not appear to match your ps2_keyboard_install function.

For the rest of your code, I'll assume PS2_KB_CMD is 0x64 and PS2_KB_DATA is 0x60.

Code:
   while(inb(PS2_KB_CMD) & 0x1)
      inb(PS2_KB_DATA);

If there is a fault with the keyboard controller, this may become an infinite loop.

Code:
   outb(PS2_KB_CMD,0xAA);
   if(inb(PS2_KB_DATA) != 0x55)
   {

Keyboard controller command 0xAA may take a long time to execute, and it may completely reset the keyboard controller to its power-on defaults. You must wait for the keyboard controller to respond, and you may also need to reconfigure it (e.g. to disable translation and set the "system flag").

Code:
   outb(PS2_KB_CMD,0xAB);
   if(inb(PS2_KB_DATA) != 0x00)
   {

Again, you need to wait for the keyboard controller to respond.

Code:
   outb(PS2_KB_CMD,0xAE);

Seriously. Old keyboard controllers are slow. You have to wait.

Code:
   outb(PS2_KB_CMD,0xF0);

This reboots the computer, assuming the keyboard controller is ready to accept this command.

Code:
   outb(PS2_KB_DATA,0x02);

This is not a documented keyboard command. The keyboard may misbehave after you send this.

Code:
   outb(PS2_KB_CMD,0x20);
   uint8_t cfg = (inb(PS2_KB_DATA) | 1) & ~0x10;
   // Set config
   outb(PS2_KB_CMD,0x60);
   outb(PS2_KB_DATA,cfg);

You can probably guess what I'm going to say here: not enough waiting. Also, it's a race condition, since you're enabling IRQ1 before you install an IRQ1 handler.

It looks like you might be confusing the keyboard controller with the keyboard. Both can accept and respond to commands, but sending commands to the keyboard is different from sending commands to the keyboard controller. You should finish initializing your keyboard controller, installing the IRQ handler(s), and enabling the IRQ(s) before you enable the keyboard port and start initializing the keyboard.

Author:  zvoncika [ Sun Dec 03, 2017 2:23 pm ]
Post subject:  Re: Setting the Scan Code set

How long should I wait?

Author:  zvoncika [ Sun Dec 03, 2017 2:28 pm ]
Post subject:  Re: Setting the Scan Code set

Should I have a temporary IRQ handler that I'll use while I, configure my PS/2 controller?

Author:  isaacwoods [ Sun Dec 03, 2017 2:34 pm ]
Post subject:  Re: Setting the Scan Code set

The PS/2 controller tells you when it's ready to be issued commands and whatnot. This is what I use:
Code:
  /*
   * Bit 0 of the status register must be SET before attempting to read data from port 0x60
   * Bit 1 of the status register must be CLEAR before attempting to write data to port 0x60
   */
  #define WAIT_FOR_READ()   while ((inb(PS2_COMMAND) & 1u) == 0u) asm volatile("rep nop");
  #define WAIT_FOR_WRITE()  while ((inb(PS2_COMMAND) & 2u) != 0u) asm volatile("rep nop");

Author:  zvoncika [ Sun Dec 03, 2017 2:40 pm ]
Post subject:  Re: Setting the Scan Code set

Huh, thanks!
Really appreciate all the help you guys give me [-o<

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/