sys: Implement LAPIC and IOAPIC support, add PS/2 keyboard driver

- Added LAPIC implementation in `apic.c` and `apic.h`, including initialization and basic operations.
- Introduced IOAPIC (I/O Advanced Programmable Interrupt Controller) support in `ioapic.c` and `ioapic.h`, parsing the ACPI MADT to locate IOAPICs and manage redirection entries.
- Implemented PS/2 keyboard driver in `ps2.c` and `ps2.h`, handling keyboard interrupts and translating scancodes to ASCII.
- Attempted to make usermode work again (it failed, coming soon)
- Cleaned up comments in `time.c` and `render.c` for clarity.

Signed-off-by: kaguya <vpshinomiya@protonmail.com>
This commit is contained in:
kaguya
2026-04-24 01:59:33 -04:00
parent 551eb00708
commit 3b6e68bc16
27 changed files with 1009 additions and 504 deletions
+15 -70
View File
@@ -27,8 +27,10 @@
#include "arch/x86_64/pci.h"
#include "sound/hda.h"
#include "sound/pcm.h"
#include "arch/x86_64/ps2.h"
#include "input/input.h"
#include "arch/x86_64/apic.h"
#include "arch/x86_64/ioapic.h"
#include "input/ps2.h"
uintptr_t g_hhdm_offset;
@@ -85,11 +87,6 @@ static volatile uint64_t limine_requests_start_marker[] = LIMINE_REQUESTS_START_
__attribute__((used, section(".limine_requests_end")))
static volatile uint64_t limine_requests_end_marker[] = LIMINE_REQUESTS_END_MARKER;
// GCC and Clang reserve the right to generate calls to the following
// 4 functions even if they are not directly called.
// Implement them as the C specification mandates.
// DO NOT remove or rename these functions, or stuff will eventually break!
// They CAN be moved to a different .c file.
@@ -203,7 +200,6 @@ void kmain(void) {
x86_64_ISR_Initialize();
x86_64_IRQ_Initialize();
x86_64_PIT_Initialize(1000);
ps2_init();
asm volatile("sti");
calibrate_tsc();
@@ -429,6 +425,7 @@ void kmain(void) {
}
/*pci_init();
pci_device_t hda;
@@ -445,72 +442,20 @@ void kmain(void) {
}*/
//syscall_init();
//start_userspace();
lapic_init();
ioapic_init();
irq_redirect_to_apic(0, 0x20, lapic_id(), false);
printf("tst");
printf("\n=== Input Subsystem Test ===\n");
printf("Opening /dev/input/event0...\n");
input_init();
ps2_kbd_init();
fd_t input_fd = VFS_Open("/dev/input/event0");
if (input_fd < 0) {
printf("Failed to open /dev/input/event0!\n");
} else {
printf("Successfully opened /dev/input/event0 (fd=%d)\n", input_fd);
printf("Press keys or move mouse... (press ESC to exit test)\n\n");
input_event_t ev;
bool running = true;
while (running) {
// Non-blocking read from the input device
int bytes = VFS_Read(input_fd, (uint8_t*)&ev, sizeof(input_event_t));
if (bytes == sizeof(input_event_t)) {
switch (ev.type) {
case INPUT_EV_KEY:
printf("KEY: scancode=0x%02X ascii='%c' (%d) pressed=%s\n",
ev.key.scancode,
ev.key.ascii ? ev.key.ascii : '?',
ev.key.ascii,
ev.key.pressed ? "YES" : "NO");
// Exit test on ESC key release
if (ev.key.scancode == 0x01 && !ev.key.pressed) {
printf("ESC pressed - exiting input test.\n");
running = false;
}
break;
case INPUT_EV_MOUSE_REL:
if (ev.rel.dx || ev.rel.dy) {
printf("MOUSE MOVE: dx=%d dy=%d\n", ev.rel.dx, ev.rel.dy);
}
break;
case INPUT_EV_MOUSE_BTN:
printf("MOUSE BTN: button=%d pressed=%s\n",
ev.btn.button,
ev.btn.pressed ? "YES" : "NO");
break;
case INPUT_EV_MOUSE_WHEEL:
printf("MOUSE WHEEL: delta=%d\n", ev.wheel.delta);
break;
default:
printf("Unknown event type %d\n", ev.type);
break;
}
}
// Small yield so we don't spin the CPU too hard
// (you can replace with a proper sleep later)
asm volatile("pause");
}
VFS_Close(input_fd);
printf("Input test finished.\n");
}
//syscall_init();
//start_userspace();
// We're done, just hang...
hcf();