-
Notifications
You must be signed in to change notification settings - Fork 1
A lot of fixes #48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A lot of fixes #48
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,110 +1,98 @@ | ||
#include "Interrupts.h" | ||
#include "Console.h" | ||
#include "Io.h" | ||
#include "Kernel.h" | ||
#include "Keyboard.h" | ||
#include "Panic.h" | ||
#include "Process.h" | ||
#include "VMem.h" | ||
#include "stdint.h" | ||
|
||
#define likely(x) __builtin_expect(!!(x), 1) | ||
#define unlikely(x) __builtin_expect(!!(x), 0) | ||
|
||
static uint64_t tick_count = 0; | ||
|
||
// Fast tick display using direct memory write | ||
static void FastDisplayTicks(uint64_t ticks) { | ||
uint16_t *vidptr = (uint16_t*)(0xb8000 + KERNEL_VIRTUAL_OFFSET); | ||
int pos = 20 * 80; // Line 20 | ||
|
||
// Write "Ticks: " | ||
vidptr[pos++] = (0x03 << 8) | 'T'; | ||
vidptr[pos++] = (0x03 << 8) | 'i'; | ||
vidptr[pos++] = (0x03 << 8) | 'c'; | ||
vidptr[pos++] = (0x03 << 8) | 'k'; | ||
vidptr[pos++] = (0x03 << 8) | 's'; | ||
vidptr[pos++] = (0x03 << 8) | ':'; | ||
vidptr[pos++] = (0x03 << 8) | ' '; | ||
|
||
// Fast number display | ||
if (ticks == 0) { | ||
vidptr[pos] = (0x03 << 8) | '0'; | ||
return; | ||
} | ||
|
||
char buf[20]; | ||
int i = 0; | ||
uint64_t temp = ticks; | ||
|
||
while (temp > 0) { | ||
buf[i++] = '0' + (temp % 10); | ||
temp /= 10; | ||
} | ||
|
||
while (i > 0) { | ||
vidptr[pos++] = (0x03 << 8) | buf[--i]; | ||
} | ||
} | ||
|
||
|
||
static void FatalExceptionHandler(const char* message, uint64_t interrupt_number) { | ||
PrintKernelWarning(message); | ||
PrintKernelWarning(" at interrupt: "); | ||
PrintKernelInt(interrupt_number); | ||
PrintKernelWarning("\n"); | ||
PANIC(message); | ||
} | ||
|
||
|
||
// The C-level interrupt handler | ||
void InterruptHandler(struct Registers* regs) { | ||
// The C-level interrupt handler, called from the assembly stub | ||
void InterruptHandler(Registers* regs) { | ||
ASSERT(regs != NULL); | ||
if (regs->interrupt_number == 32 || regs->interrupt_number == 33) { // Force ignore keyboard interrupt | ||
tick_count++; | ||
// FastDisplayTicks(tick_count); | ||
FastSchedule(regs); | ||
outb(0x20, 0x20); // EOI to master PIC | ||
return; | ||
} | ||
|
||
uint64_t cr2; | ||
asm volatile("mov %%cr2, %0" : "=r"(cr2)); | ||
|
||
PrintKernelError("PAGE FAULT\n"); | ||
PrintKernelError(" Address: "); | ||
PrintKernelHex(cr2); | ||
PrintKernelError("\n Error Code: "); | ||
PrintKernelHex(regs->error_code); | ||
PrintKernelError("\n"); | ||
|
||
|
||
if (!(regs->error_code & 0x1)) { | ||
PrintKernelError(" Reason: Page Not Present\n"); | ||
} else { | ||
PrintKernelError(" Reason: Protection Violation\n"); | ||
} | ||
|
||
if (regs->error_code & 0x2) { | ||
PrintKernelError(" Operation: Write\n"); | ||
} else { | ||
PrintKernelError(" Operation: Read\n"); | ||
// Handle hardware interrupts first | ||
switch (regs->interrupt_number) { | ||
case 32: // Timer interrupt | ||
FastSchedule(regs); | ||
outb(0x20, 0x20); // EOI to master PIC | ||
return; | ||
|
||
case 33: // Keyboard interrupt | ||
KeyboardHandler(); | ||
outb(0x20, 0x20); // EOI to master PIC | ||
return; | ||
|
||
// Handle other hardware interrupts (34-47) | ||
case 34 ... 47: | ||
PrintKernelWarning("[IRQ] Unhandled hardware interrupt: "); | ||
PrintKernelInt(regs->interrupt_number - 32); | ||
PrintKernelWarning("\n"); | ||
|
||
// Send EOI to the appropriate PIC | ||
if (regs->interrupt_number >= 40) { | ||
outb(0xA0, 0x20); // EOI to slave PIC | ||
} | ||
outb(0x20, 0x20); // EOI to master PIC | ||
return; | ||
} | ||
|
||
if (regs->error_code & 0x4) { | ||
PrintKernelError(" Mode: User\n"); | ||
} | ||
else { | ||
PrintKernelError(" Mode: Supervisor\n"); | ||
// Handle CPU exceptions (0-31) | ||
PrintKernelError("\n!! CPU EXCEPTION !!\n"); | ||
|
||
switch (regs->interrupt_number) { | ||
case 6: // Invalid Opcode | ||
PrintKernelError(" TYPE: Invalid Opcode (UD)\n"); | ||
PrintKernelError(" RIP: "); | ||
PrintKernelHex(regs->rip); | ||
PrintKernelError("\n"); | ||
PANIC("Invalid Opcode"); | ||
break; | ||
|
||
case 13: // General Protection Fault | ||
PrintKernelError(" TYPE: General Protection Fault (GPF)\n"); | ||
PrintKernelError(" RIP: "); | ||
PrintKernelHex(regs->rip); | ||
PrintKernelError("\n Error Code: "); | ||
PrintKernelHex(regs->error_code); | ||
PrintKernelError(" (often segment related)\n"); | ||
PANIC_CODE("General Protection Fault", regs->error_code); | ||
break; | ||
|
||
case 14: // Page Fault | ||
uint64_t cr2; | ||
asm volatile("mov %%cr2, %0" : "=r"(cr2)); | ||
|
||
PrintKernelError(" TYPE: Page Fault (PF)\n"); | ||
PrintKernelError(" Faulting Address: "); | ||
PrintKernelHex(cr2); | ||
PrintKernelError("\n Error Code: "); | ||
PrintKernelHex(regs->error_code); | ||
PrintKernelError("\n Details:\n"); | ||
|
||
if (!(regs->error_code & 0x1)) PrintKernelError(" - Reason: Page Not Present\n"); | ||
else PrintKernelError(" - Reason: Protection Violation\n"); | ||
|
||
if (regs->error_code & 0x2) PrintKernelError(" - Operation: Write\n"); | ||
else PrintKernelError(" - Operation: Read\n"); | ||
|
||
if (regs->error_code & 0x4) PrintKernelError(" - Mode: User\n"); | ||
else PrintKernelError(" - Mode: Supervisor\n"); | ||
|
||
if (regs->error_code & 0x8) PrintKernelError(" - Cause: Reserved bit set\n"); | ||
if (regs->error_code & 0x10) PrintKernelError(" - Cause: Instruction Fetch\n"); | ||
|
||
PANIC_CODE("Page Fault", regs->error_code); | ||
break; | ||
|
||
default: // All other exceptions | ||
PrintKernelError(" TYPE: Unhandled Exception\n"); | ||
PrintKernelError(" Interrupt Number: "); | ||
PrintKernelInt(regs->interrupt_number); | ||
PrintKernelError("\n RIP: "); | ||
PrintKernelHex(regs->rip); | ||
PrintKernelError("\n Error Code: "); | ||
PrintKernelHex(regs->error_code); | ||
PrintKernelError("\n"); | ||
PANIC("Unhandled CPU Exception"); | ||
break; | ||
} | ||
|
||
if (regs->error_code & 0x8) { | ||
PrintKernelError(" Cause: Reserved bit set\n"); | ||
} | ||
|
||
if (regs->error_code & 0x10) { | ||
PrintKernelError(" Cause: Instruction fetch\n"); | ||
} | ||
|
||
PANIC_CODE("Page Fault", regs->error_code); | ||
} | ||
|
||
// The C-level interrupt handler | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#ifndef INTERRUPTS_H | ||
#define INTERRUPTS_H | ||
|
||
#endif // INTERRUPTS_H | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#include "Keyboard.h" | ||
#include "Io.h" | ||
#include "Console.h" | ||
|
||
#define KEYBOARD_DATA_PORT 0x60 | ||
#define KEYBOARD_STATUS_PORT 0x64 | ||
|
||
static volatile char input_buffer[256]; | ||
static volatile int buffer_head = 0; | ||
static volatile int buffer_tail = 0; | ||
static volatile int buffer_count = 0; | ||
|
||
static char scancode_to_ascii[] = { | ||
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', | ||
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', | ||
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', | ||
0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, | ||
'*', 0, ' ' | ||
}; | ||
Comment on lines
+13
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Incomplete keyboard mapping The scancode mapping table only covers a subset of keys and doesn't handle modifier keys (Shift, Ctrl, Alt) or different keyboard states (Caps Lock, Num Lock). This limits the keyboard functionality significantly. Consider implementing a more complete keyboard driver with state tracking:
🤖 Prompt for AI Agents
|
||
|
||
void KeyboardInit(void) { | ||
buffer_head = buffer_tail = buffer_count = 0; | ||
} | ||
|
||
void KeyboardHandler(void) { | ||
// Check if data is available | ||
uint8_t status = inb(KEYBOARD_STATUS_PORT); | ||
if (!(status & 0x01)) return; // No data available | ||
|
||
uint8_t scancode = inb(KEYBOARD_DATA_PORT); | ||
|
||
if (scancode & 0x80) return; // Key release | ||
if (scancode >= sizeof(scancode_to_ascii)) return; // Invalid scancode | ||
|
||
char c = scancode_to_ascii[scancode]; | ||
if (c && buffer_count < 256) { | ||
input_buffer[buffer_tail] = c; | ||
buffer_tail = (buffer_tail + 1) % 256; | ||
buffer_count++; | ||
} | ||
} | ||
|
||
char GetChar(void) { | ||
if (buffer_count == 0) return 0; | ||
|
||
char c = input_buffer[buffer_head]; | ||
buffer_head = (buffer_head + 1) % 256; | ||
buffer_count--; | ||
return c; | ||
} | ||
|
||
int HasInput(void) { | ||
return buffer_count > 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#ifndef KEYBOARD_H | ||
#define KEYBOARD_H | ||
|
||
#include "stdint.h" | ||
|
||
void KeyboardInit(void); | ||
void KeyboardHandler(void); | ||
char GetChar(void); | ||
int HasInput(void); | ||
|
||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider adding interrupt-related declarations.
This header appears to be a placeholder with only include guards. Given the significant interrupt handling refactoring mentioned in the AI summary, consider adding appropriate function declarations, constants, or type definitions that should be exposed from the interrupt subsystem.
For example, if
KeyboardHandler
or other interrupt handlers are called from external code, their declarations should be present here:📝 Committable suggestion
🤖 Prompt for AI Agents