Initialising PS2 controller results in #GP and jump to random code on real hardware

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.
Post Reply
atomtables
Posts: 14
Joined: Fri Nov 08, 2024 5:08 pm
Libera.chat IRC: atomtables

Initialising PS2 controller results in #GP and jump to random code on real hardware

Post by atomtables »

Hi, when I initialise the PS/2 controller on a HP Elitebook 8540w, the code seems to go to a random location in memory then #GP fault (which my interrupts catch). This error does not happen on an emulator. Below is the code for the PS/2 controller, the function where the init function is called, and the screen which the interrupts threw.

Code: Select all

//
// Created by  on 19/12/2024.
//

#include "controller.h"

#include <display/simple/display.h>
#include <exception/exception.h>
#include <modules/modules.h>

#include "keyboard.h"

static const bool DEBUG = false;

#define wait_for(_cond) while (!(_cond)) { NOP(); }

bool verify_controller_ready_write() {
    u8 status = inportb(CONTROLLER_MAIN);
    return BIT_GET(status, 1) == 0;
}

bool verify_controller_ready_read() {
    u8 status = inportb(CONTROLLER_MAIN);
    return BIT_GET(status, 0) == 1;
}

bool verify_controller_response(u8 response) {
    if (response == 0x00 || response == 0xFF) {
        return false;
    }
    return true;
}

void sendcommandb(u8 cmd) {
    wait_for(verify_controller_ready_write());
    outportb(CONTROLLER_MAIN, cmd);
}

void sendcommandw(u8 cmd, u8 subcmd) {
    wait_for(verify_controller_ready_write());
    outportb(CONTROLLER_MAIN, cmd);

    wait_for(verify_controller_ready_write());
    outportb(CONTROLLER_AUX, subcmd);
}

u8 readdatab() {
    wait_for(verify_controller_ready_read());
    return inportb(CONTROLLER_AUX);
}

u8 read_configuration_byte() {
    sendcommandb(0x20);
    u8 config = readdatab();
    return config;
}

void write_configuration_byte(u8 config) {
    sendcommandw(0x60, config);
    // Don't read response - there isn't one for this command
    if (DEBUG) display.printf("current controller byte: 0x%x\n", read_configuration_byte());
}

// MAIN LOADER
void ps2_controller_init() {
    sendcommandb(CONTROLCMD_DISABLE_P1);

    u8 config = read_configuration_byte();
    config |= 0x01; // Enable first PS/2 port
    config |= 0x40; // Enable first PS/2 translation
    write_configuration_byte(config);

    keyboard_irq_enabled = true;
    keyboard_translation_enabled = true;

    sendcommandb(CONTROLCMD_ENABLE_P1);
}
This is the kernel init code:

Code: Select all

idt_init();
    isr_init();
    PIC_init();
    display.printf("Target complete: interrupts\n");

    timer_init();
    display.printf("Target complete: timer\n");
    sleep(1000);
    init_mem();
    display.printf("Target complete: memory\n");
    sleep(1000);
    fpu_init();
    display.printf("Target complete: fpu\n");

    sleep(1000);
    pcs_init();
    display.printf("Target complete: pcspeaker\n");

    sleep(1000);
    ps2_controller_init();
    display.printf("Target complete: ps2 controller\n");

    sleep(1000);
    keyboard_init();
    display.printf("Target complete: keyboard\n");
// misc
and this is the screen i got from the interrupts
Image

if anyone could help it would be greatly appreciated!
Octocontrabass
Member
Member
Posts: 6247
Joined: Mon Mar 25, 2013 7:01 pm

Re: Initialising PS2 controller results in #GP and jump to random code on real hardware

Post by Octocontrabass »

Do you know which part of your code causes the jump to a nonsense address?

Have you checked to see if it's an IRQ arriving and corrupting its own return address?
atomtables wrote: Sat Oct 25, 2025 5:17 pm

Code: Select all

    config |= 0x01; // Enable first PS/2 port
    sendcommandb(CONTROLCMD_ENABLE_P1);
Don't these two lines of code do the same thing?
atomtables
Posts: 14
Joined: Fri Nov 08, 2024 5:08 pm
Libera.chat IRC: atomtables

Re: Initialising PS2 controller results in #GP and jump to random code on real hardware

Post by atomtables »

It's a little hard to debug since this only happens on my HP, on a ThinkPad T440p it works perfectly fine. It definitely seems like an IRQ corrupting its own return address, I have heard things about HPs having all sorts of weird behaviour.

As for the repeat, yea oops.

Since for the time being I'm trying to write my own filesystem driver using (P)ATA, I won't be able to test on real hardware since I don't have a replacement hard disk. Thanks for the help
Post Reply