OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 1:40 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 11 posts ] 
Author Message
 Post subject: Trouble reading multi-byte scan codes from 8042 Controller
PostPosted: Sun Mar 28, 2021 8:01 pm 
Offline

Joined: Sun Mar 28, 2021 7:10 pm
Posts: 6
I was recently working on enhancing my keyboard driver, providing support for more than alphanumeric and symbol keys (arrow keys, etc.), and ran into this problem. When reading from port 60h, I could only read the last N - 1 bytes of a scan code that I know should be N bytes, e.g. pressing the left arrow key results in the read code 6Bh 6Bh, as opposed to the expected E0h 6Bh.

Below is the code I put in to my handler instead of my usual code, for debugging purposes.
Code:
void _handle_keyboard() {
    // Send EOI to PIC
    send_eoi(KEYBOARD_IRQ_PIN);

    // Read and print value from 60h
    printf("%#x ", inb(KEYBOARD_IN_PORT));
    printf("%#x\n", inb(KEYBOARD_IN_PORT));
}


In debugging, I have done a couple of things. I have changed the 8042 configuration byte to disable translation (bit 6). This changed the scan code from code set 1 to code set 2, although I was still unable to read all the bytes of the scan code sequence using multiple I/O reads with print statements, as shown above. I have also tried explicitly setting the scan code sent from the keyboard, via command F0h set to the keyboard, but still get the same behavior, just with byte values printed corresponding to different scan code sets.

Here is the code I use to initialize the keyboard. This is where I added commands to disable translation and set the scan code set when debugging (code not shown for those settings).
Code:
// Initialization function
int init_keyboard() {
    // Disable interrupts
    uint32_t flags;
    cli_and_save(flags);

    // Route interrupts to handler
    if(set_int(KEYBOARD_IRQ_PIN, _handle_keyboard)) return -1;

    // Intialize state
    device_state.r_shift   = 0;
    device_state.l_shift   = 0;
    device_state.caps      = 0;
    device_state.alt       = 0;
    device_state.status    = FREE;
    device_state.enable    = ENABLED;

    // Enable interrupts on the proper pin
    enable_irq(KEYBOARD_IRQ_PIN);

    // Restore flags, enable interrupts
    restore_flags(flags);
    sti();

    return 0;
}


Is this the proper way to read in scan codes, via multiple port 60h reads? If so, what could be possible causes of this issue?


Top
 Profile  
 
 Post subject: Re: Trouble reading multi-byte scan codes from 8042 Controll
PostPosted: Sun Mar 28, 2021 9:26 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5100
The keyboard controller sends one byte per IRQ, not one scan code per IRQ. Read only one byte in the IRQ handler.


Top
 Profile  
 
 Post subject: Re: Trouble reading multi-byte scan codes from 8042 Controll
PostPosted: Sun Mar 28, 2021 10:13 pm 
Offline

Joined: Sun Mar 28, 2021 7:10 pm
Posts: 6
Octocontrabass wrote:
The keyboard controller sends one byte per IRQ, not one scan code per IRQ. Read only one byte in the IRQ handler.


Even reading one byte per IRQ, I have the same behavior. On a left arrow key (make code E0 6B), I only get one IRQ on the button press, and that is for 6B. On release (break code E0 F0 6B) I get interrupts only for 6B, F0, in that order. I am never able to read the E0 byte for some reason.


Top
 Profile  
 
 Post subject: Re: Trouble reading multi-byte scan codes from 8042 Controll
PostPosted: Sun Mar 28, 2021 10:33 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5100
The interrupts can't arrive in the wrong order.

Do you have your interrupt handler configured as a trap gate or an interrupt gate?


Top
 Profile  
 
 Post subject: Re: Trouble reading multi-byte scan codes from 8042 Controll
PostPosted: Mon Mar 29, 2021 12:40 am 
Offline

Joined: Sun Mar 28, 2021 7:10 pm
Posts: 6
Octocontrabass wrote:
The interrupts can't arrive in the wrong order.

Do you have your interrupt handler configured as a trap gate or an interrupt gate?


I have it configured as an interrupt gate. Your comment gave me food for thought however, and I found that I was turning on interrupts in a set_cursor function, as I was calling sti() as opposed to restore_flags(). I fixed that issue, and made sure interrupts were off for the duration of the handler execution.

Since addressing that, bytes come in the right order, but I am still unable to read off the first byte, the E0 byte for left arrow.

What is even more puzzling is that this only seems to happen for scan codes with E0 included as a byte. Here are a few byte sequences as an example:

Code:
                   Expected (M/B)                          Received (M/B)
Left Arrow:        E0 6B/E0 F0 6B                          6B/F0 6B
Print Screen:      E0 12 E0 7C/E0 F0 7C E0 F0 12           7C/F0 7C
Delete:            E0 71/E0 F0 71                          71/F0 71


All scan codes w/o E0 seem to be behaving as expected.


Top
 Profile  
 
 Post subject: Re: Trouble reading multi-byte scan codes from 8042 Controll
PostPosted: Mon Mar 29, 2021 12:47 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5100
What hardware or virtual machine are you using? Perhaps it doesn't support the extended scan codes, for whatever reason.


Top
 Profile  
 
 Post subject: Re: Trouble reading multi-byte scan codes from 8042 Controll
PostPosted: Tue Mar 30, 2021 1:13 am 
Offline

Joined: Sun Mar 28, 2021 7:10 pm
Posts: 6
Octocontrabass wrote:
What hardware or virtual machine are you using? Perhaps it doesn't support the extended scan codes, for whatever reason.


I am using QEMU. Was unable to find any documentation/people with the same issue in searching.


Top
 Profile  
 
 Post subject: Re: Trouble reading multi-byte scan codes from 8042 Controll
PostPosted: Tue Mar 30, 2021 1:44 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5100
Are you connecting to QEMU using VNC? QEMU may not be able to determine the appropriate scan codes to give to your OS when using VNC.


Top
 Profile  
 
 Post subject: Re: Trouble reading multi-byte scan codes from 8042 Controll
PostPosted: Tue Mar 30, 2021 3:23 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
I don't know if that's the source of your problem, but you are supposed to send EOI after reading data from the controller. Otherwise, you may get spurious interrupts and other weird behaviour.


Top
 Profile  
 
 Post subject: Re: Trouble reading multi-byte scan codes from 8042 Controll
PostPosted: Wed Mar 31, 2021 9:06 pm 
Offline

Joined: Sun Mar 28, 2021 7:10 pm
Posts: 6
pvc wrote:
I don't know if that's the source of your problem, but you are supposed to send EOI after reading data from the controller. Otherwise, you may get spurious interrupts and other weird behaviour.


Ah yes, this is something I forgot about as well. Thank you. Changing this did not resolve my issue with incorrect byte sequences.


Top
 Profile  
 
 Post subject: Re: Trouble reading multi-byte scan codes from 8042 Controll
PostPosted: Wed Mar 31, 2021 9:20 pm 
Offline

Joined: Sun Mar 28, 2021 7:10 pm
Posts: 6
Octocontrabass wrote:
Are you connecting to QEMU using VNC? QEMU may not be able to determine the appropriate scan codes to give to your OS when using VNC.


I am not connecting to QEMU using VNC. Your comment, however, prompted me to look into my QEMU settings, and I found the following in their documentation (https://qemu-project.gitlab.io/qemu/system/invocation.html):

QEMU Documentation wrote:
-k language
Use keyboard layout language (for example fr for French). This option is only needed where it is not easy to get raw PC keycodes (e.g. on Macs, with some X11 servers or with a VNC or curses display). You don’t normally need to use it on PC/Linux or PC/Windows hosts.


I found that explicitly setting the flag "-k en-us" resolved the issue, and I am now able to received all bytes for all scan codes. I am using neither curses, VNC, or a Mac OS, so something else must have caused this issue. Thank you for all the help and tips!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 57 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group