Page 1 of 1

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

Posted: Sat Oct 25, 2025 5:17 pm
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!

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

Posted: Sat Oct 25, 2025 8:19 pm
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?

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

Posted: Sat Nov 08, 2025 12:41 pm
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