Troubleshooting to get keyboard driver working

This commit is contained in:
Thomas Oltmann 2025-08-13 23:30:04 +02:00
parent a33a142653
commit 58ad56118c
6 changed files with 59 additions and 18 deletions

View file

@ -25,9 +25,10 @@ boot: disk
panic: action=ask panic: action=ask
error: action=report error: action=report
info: action=report info: action=report
debug: action=ignore, pci=report # report BX_DEBUG from module 'pci' #debug: action=ignore, apic0=report, pic=report, ioapic=report
debug: action=ignore, keyboard=report
debugger_log: - debugger_log: bochs-log.txt
#com1: enabled=1, mode=socket-server, dev=localhost:1111 #com1: enabled=1, mode=socket-server, dev=localhost:1111
port_e9_hack: enabled=1 port_e9_hack: enabled=1

View file

@ -24,7 +24,7 @@
* already in progress. * already in progress.
*/ */
#define RTC_IRQ_NUMBER 8 #define RTC_IRQ_NUMBER 0
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>

View file

@ -5,6 +5,8 @@
#include "console.h" #include "console.h"
#include "unicode.h" #include "unicode.h"
#include "x86_64/interrupt.h"
#define BUFFER_SIZE 1024 #define BUFFER_SIZE 1024
/* --- Memory Functions --- */ /* --- Memory Functions --- */
@ -75,19 +77,23 @@ static unicode_char linebuf[BUFFER_SIZE];
static unsigned int current_buffer_position = 0; static unsigned int current_buffer_position = 0;
static void linebuf_flush(void) { static void linebuf_flush(void) {
int int_state = int_disable();
for (unsigned int i = 0; i < current_buffer_position; i++) { for (unsigned int i = 0; i < current_buffer_position; i++) {
// TODO // TODO
// serial_write_char(linebuf[i]); // serial_write_char(linebuf[i]);
cout_putc(linebuf[i]); cout_putc(linebuf[i]);
} }
current_buffer_position = 0; current_buffer_position = 0;
int_restore(int_state);
} }
static void linebuf_putc(unicode_char c) { static void linebuf_putc(unicode_char c) {
int int_state = int_disable();
if (current_buffer_position == BUFFER_SIZE) { if (current_buffer_position == BUFFER_SIZE) {
linebuf_flush(); linebuf_flush();
} }
linebuf[current_buffer_position++] = c; linebuf[current_buffer_position++] = c;
int_restore(int_state);
} }
/* --- Low-level output functions --- */ /* --- Low-level output functions --- */

View file

@ -152,11 +152,16 @@ static void ioapic_write(volatile uint32_t *ioapic, unsigned offset, uint32_t va
static unsigned irq_to_gsi_number(unsigned irq, uint16_t *flags) static unsigned irq_to_gsi_number(unsigned irq, uint16_t *flags)
{ {
struct MADT *madt = acpi_find_table("APIC"); struct MADT *madt = acpi_find_table("APIC");
if (!madt) {
printf("No MADT table!\n");
return irq;
}
uint32_t offset = 0; uint32_t offset = 0;
while (offset < madt->Header.Length) { while (offset < madt->Header.Length - sizeof *madt) {
struct EntryHeader *entry = (struct EntryHeader *)((char *)(madt + 1) + offset); struct EntryHeader *entry = (struct EntryHeader *)((char *)(madt + 1) + offset);
if (entry->Type == MADT_ENTRY_INT_OVERRIDE) { if (entry->Type == MADT_ENTRY_INT_OVERRIDE) {
struct EntryIntOverride *override = (void *)entry; struct EntryIntOverride *override = (void *)entry;
printf("ACPI Int Override: %u -> %u (%x)\n", override->Source, override->Gsi, override->Flags);
if (override->Source == irq) { if (override->Source == irq) {
if (flags) { if (flags) {
*flags = override->Flags; *flags = override->Flags;
@ -175,11 +180,16 @@ static unsigned irq_to_gsi_number(unsigned irq, uint16_t *flags)
static struct EntryIoapic *ioapic_for_gsi(unsigned gsi) static struct EntryIoapic *ioapic_for_gsi(unsigned gsi)
{ {
struct MADT *madt = acpi_find_table("APIC"); struct MADT *madt = acpi_find_table("APIC");
if (!madt) {
printf("No MADT table!\n");
return NULL;
}
uint32_t offset = 0; uint32_t offset = 0;
while (offset < madt->Header.Length) { while (offset < madt->Header.Length - sizeof *madt) {
struct EntryHeader *entry = (struct EntryHeader *)((char *)(madt + 1) + offset); struct EntryHeader *entry = (struct EntryHeader *)((char *)(madt + 1) + offset);
if (entry->Type == MADT_ENTRY_IOAPIC) { if (entry->Type == MADT_ENTRY_IOAPIC) {
struct EntryIoapic *ioapic = (void *)entry; struct EntryIoapic *ioapic = (void *)entry;
printf("ACPI IOAPIC Entry: id=%u, address=%u, gsi-base=%u\n", ioapic->IoapicId, ioapic->IoapicAddress, ioapic->GsiBase);
if (gsi >= ioapic->GsiBase) { if (gsi >= ioapic->GsiBase) {
void *ioapic_ptr = pa_to_pointer(pa_from_value(ioapic->IoapicAddress)); void *ioapic_ptr = pa_to_pointer(pa_from_value(ioapic->IoapicAddress));
unsigned num_entries = (ioapic_read(ioapic_ptr, IOAPICVER) >> 16) & 0xFF; unsigned num_entries = (ioapic_read(ioapic_ptr, IOAPICVER) >> 16) & 0xFF;

View file

@ -178,9 +178,15 @@ rtc_init(void) {
dt.year, dt.month, dt.day, dt.year, dt.month, dt.day,
dt.hours, dt.minutes, dt.seconds); dt.hours, dt.minutes, dt.seconds);
rtc_set_periodic(false);
/*
interrupt_handler_register(0x40, clock_handler); interrupt_handler_register(0x40, clock_handler);
rtc_set_rate(15); rtc_set_rate(15);
rtc_set_periodic(true); rtc_set_periodic(true);
*/
#if 0
bool success = ioapic_configure_irq(RTC_IRQ_NUMBER, 0x40 | IORED_DELIVERY_NORMAL | ((uint64_t)lapic_get_id() << IORED_DESTINATION_SHIFT)); bool success = ioapic_configure_irq(RTC_IRQ_NUMBER, 0x40 | IORED_DELIVERY_NORMAL | ((uint64_t)lapic_get_id() << IORED_DESTINATION_SHIFT));
ASSERT(success); ASSERT(success);
#endif
} }

View file

@ -12,7 +12,7 @@
#define PORT_DATA 0x60 #define PORT_DATA 0x60
#define CMD_CONFIGBYTE_READ 0x20 #define CMD_CONFIGBYTE_READ 0x20
#define CMD_CONFIGBYTE_WRITE 0x20 #define CMD_CONFIGBYTE_WRITE 0x60
#define CMD_PORT2_DISABLE 0xA7 #define CMD_PORT2_DISABLE 0xA7
#define CMD_PORT2_ENABLE 0xA8 #define CMD_PORT2_ENABLE 0xA8
#define CMD_PORT2_TEST 0xA9 #define CMD_PORT2_TEST 0xA9
@ -245,9 +245,9 @@ void ps2_init() {
/* Set Configbyte */ /* Set Configbyte */
config_byte = ps2_cmd_response(CMD_CONFIGBYTE_READ); config_byte = ps2_cmd_response(CMD_CONFIGBYTE_READ);
config_byte &= ~CONFIG_BIT_PORT1_INT_ENABLED; config_byte &= ~(1 << CONFIG_BIT_PORT1_INT_ENABLED);
config_byte &= ~CONFIG_BIT_PORT1_CLOCK_DISABLED; config_byte &= ~(1 << CONFIG_BIT_PORT1_CLOCK_DISABLED);
config_byte &= ~CONFIG_BIT_PORT1_TRANSLATION; config_byte &= ~(1 << CONFIG_BIT_PORT1_TRANSLATION);
ps2_cmd_with_data(CMD_CONFIGBYTE_WRITE, config_byte); ps2_cmd_with_data(CMD_CONFIGBYTE_WRITE, config_byte);
/* Selftest */ /* Selftest */
@ -261,8 +261,8 @@ void ps2_init() {
if (port_2_enabled) { if (port_2_enabled) {
ps2_write_cmd(CMD_PORT2_DISABLE); ps2_write_cmd(CMD_PORT2_DISABLE);
config_byte = ps2_cmd_response(CMD_CONFIGBYTE_READ); config_byte = ps2_cmd_response(CMD_CONFIGBYTE_READ);
config_byte &= ~CONFIG_BIT_PORT2_INT_ENABLED; config_byte &= ~(1 << CONFIG_BIT_PORT2_INT_ENABLED);
config_byte &= ~CONFIG_BIT_PORT2_CLOCK_DISABLED; config_byte &= ~(1 << CONFIG_BIT_PORT2_CLOCK_DISABLED);
ps2_cmd_with_data(CMD_CONFIGBYTE_WRITE, config_byte); ps2_cmd_with_data(CMD_CONFIGBYTE_WRITE, config_byte);
} }
@ -280,13 +280,18 @@ void ps2_init() {
ps2_write_cmd(CMD_PORT2_ENABLE); ps2_write_cmd(CMD_PORT2_ENABLE);
} }
/* Enable interrupts */ #if 0
config_byte = ps2_cmd_response(CMD_CONFIGBYTE_READ); for (int i = 0; i < 16; i++) {
config_byte |= CONFIG_BIT_PORT1_INT_ENABLED; /* register interrupt handlers */
if (port_2_enabled) { interrupt_handler_register(100 + i, port1_handler);
config_byte |= CONFIG_BIT_PORT2_INT_ENABLED;
bool success;
success = ioapic_configure_irq(i, (100 + i) | IORED_DELIVERY_NORMAL | IORED_TRIGGER_LEVEL | ((uint64_t)lapic_get_id() << IORED_DESTINATION_SHIFT));
ASSERT(success);
} }
ps2_cmd_with_data(CMD_CONFIGBYTE_WRITE, config_byte); #endif
#if 1
/* register interrupt handlers */ /* register interrupt handlers */
interrupt_handler_register(101, port1_handler); interrupt_handler_register(101, port1_handler);
interrupt_handler_register(102, port2_handler); interrupt_handler_register(102, port2_handler);
@ -294,11 +299,24 @@ void ps2_init() {
bool success; bool success;
success = ioapic_configure_irq(1, 101 | IORED_DELIVERY_NORMAL | ((uint64_t)lapic_get_id() << IORED_DESTINATION_SHIFT)); success = ioapic_configure_irq(1, 101 | IORED_DELIVERY_NORMAL | ((uint64_t)lapic_get_id() << IORED_DESTINATION_SHIFT));
ASSERT(success); ASSERT(success);
success = ioapic_configure_irq(0, 101 | IORED_DELIVERY_NORMAL | ((uint64_t)lapic_get_id() << IORED_DESTINATION_SHIFT));
ASSERT(success);
success = ioapic_configure_irq(2, 101 | IORED_DELIVERY_NORMAL | ((uint64_t)lapic_get_id() << IORED_DESTINATION_SHIFT));
ASSERT(success);
success = ioapic_configure_irq(12, 102 | IORED_DELIVERY_NORMAL | ((uint64_t)lapic_get_id() << IORED_DESTINATION_SHIFT)); success = ioapic_configure_irq(12, 102 | IORED_DELIVERY_NORMAL | ((uint64_t)lapic_get_id() << IORED_DESTINATION_SHIFT));
ASSERT(success); ASSERT(success);
#endif
/* Enable interrupts */
config_byte = ps2_cmd_response(CMD_CONFIGBYTE_READ);
config_byte |= (1 << CONFIG_BIT_PORT1_INT_ENABLED);
if (port_2_enabled) {
config_byte |= (1 << CONFIG_BIT_PORT2_INT_ENABLED);
}
ps2_cmd_with_data(CMD_CONFIGBYTE_WRITE, config_byte);
/* Flush Outputbuffer again because it doesn't work otherwise */ /* Flush Outputbuffer again because it doesn't work otherwise */
ps2_empty_output_buffer(); //ps2_empty_output_buffer();
/* Reset devices */ /* Reset devices */
// TODO // TODO