diff --git a/arch/x86_64/interrupts/Interrupts.c b/arch/x86_64/interrupts/Interrupts.c index 624c7fd..d58a16e 100644 --- a/arch/x86_64/interrupts/Interrupts.c +++ b/arch/x86_64/interrupts/Interrupts.c @@ -1,11 +1,11 @@ #include "Interrupts.h" #include "Console.h" #include "Ide.h" -#include "Io.h" +#include "MemOps.h" #include "PS2.h" #include "Panic.h" +#include "Pic.h" #include "Process.h" -#include "MemOps.h" // The C-level interrupt handler, called from the assembly stub void InterruptHandler(Registers* regs) { @@ -15,50 +15,43 @@ void InterruptHandler(Registers* regs) { switch (regs->interrupt_number) { case 32: // Timer interrupt (IRQ 0) FastSchedule(regs); - outb(0x20, 0x20); // EOI to master PIC + PICSendEOI(regs->interrupt_number); return; case 33: // Keyboard interrupt (IRQ 1) KeyboardHandler(); - outb(0x20, 0x20); // EOI to master PIC + PICSendEOI(regs->interrupt_number); + return; + + case 34: + PICSendEOI(regs->interrupt_number); return; case 44: // mouse (IRQ 12) MouseHandler(); - outb(0xA0, 0x20); // EOI to slave PIC - outb(0x20, 0x20); // EOI to master PIC + PICSendEOI(regs->interrupt_number); return; case 46: // IDE Primary (IRQ 14) IDEPrimaryIRQH(); - outb(0xA0, 0x20); // EOI to slave PIC - outb(0x20, 0x20); // EOI to master PIC + PICSendEOI(regs->interrupt_number); return; case 47: // IDE Secondary (IRQ 15) IDESecondaryIRQH(); - outb(0xA0, 0x20); // EOI to slave PIC - outb(0x20, 0x20); // EOI to master PIC + PICSendEOI(regs->interrupt_number); return; // Handle other hardware interrupts (34-45) - case 34 ... 43: case 45: // passthrough + case 35 ... 43: case 45: // passthrough 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 + PICSendEOI(regs->interrupt_number); return; } // Handle CPU exceptions (0-31) - - // Buffer for creating descriptive panic messages. - // Made static to reside in .bss rather than on a potentially corrupt stack. static char panic_message[256]; switch (regs->interrupt_number) { @@ -72,6 +65,15 @@ void InterruptHandler(Registers* regs) { break; } + case 8: + { + char rip_str[20]; + htoa(regs->rip, rip_str); + strcpy(panic_message, "Double Fault at "); + strcat(panic_message, rip_str); + PanicFromInterrupt(panic_message, regs); + } + case 13: // General Protection Fault { char ec_str[20]; diff --git a/drivers/APIC.c b/drivers/APIC.c index 7d9c3f1..fe8d40f 100644 --- a/drivers/APIC.c +++ b/drivers/APIC.c @@ -1,6 +1,6 @@ #include "APIC.h" #include "Console.h" - +#include "Io.h" // APIC base address (will be detected from MSR) static volatile uint32_t* apic_base = NULL; static volatile uint32_t* ioapic_base = NULL; @@ -10,26 +10,6 @@ static uint32_t ioapic_max_redirections = 0; // IRQ masking state (same as PIC for compatibility) static uint32_t irq_mask = 0xFFFFFFFF; // All masked initially -// CPUID detection -static inline void cpuid(uint32_t leaf, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) { - __asm__ volatile("cpuid" - : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) - : "a"(leaf)); -} - -// MSR access -static inline uint64_t rdmsr(uint32_t msr) { - uint32_t low, high; - __asm__ volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(msr)); - return ((uint64_t)high << 32) | low; -} - -static inline void wrmsr(uint32_t msr, uint64_t value) { - uint32_t low = value & 0xFFFFFFFF; - uint32_t high = value >> 32; - __asm__ volatile("wrmsr" :: "a"(low), "d"(high), "c"(msr)); -} - int ApicDetect(void) { uint32_t eax, ebx, ecx, edx; diff --git a/drivers/InterruptController.c b/drivers/InterruptController.c index 791374f..ef1cd71 100644 --- a/drivers/InterruptController.c +++ b/drivers/InterruptController.c @@ -1,7 +1,8 @@ #include "InterruptController.h" #include "APIC.h" -#include "Pic.h" #include "Console.h" +#include "Io.h" +#include "Pic.h" static interrupt_controller_t current_controller = INTC_PIC; static int apic_available = 0; @@ -13,6 +14,7 @@ void InterruptControllerInstall(void) { if (ApicDetect()) { apic_available = 1; ApicInstall(); + PICMaskAll(); current_controller = INTC_APIC; PrintKernelSuccess("IC: Using APIC interrupt controller\n"); } else { @@ -47,15 +49,16 @@ void IC_disable_irq(uint8_t irq_line) { } } -void InterruptControllerSendEOI(void) { +void InterruptControllerSendEOI(uint64_t interrupt_number) { switch (current_controller) { case INTC_APIC: ApicSendEOI(); break; case INTC_PIC: - default: - // PIC EOI is handled directly in interrupt handler - // via outb(0x20, 0x20) / outb(0xA0, 0x20) + if (interrupt_number >= 40) { + outb(0xA0, 0x20); // EOI to slave PIC + } + outb(0x20, 0x20); // EOI to master PIC break; } } diff --git a/drivers/InterruptController.h b/drivers/InterruptController.h index bf1377c..2d7add7 100644 --- a/drivers/InterruptController.h +++ b/drivers/InterruptController.h @@ -15,7 +15,7 @@ void InterruptControllerEnable(void); void InterruptControllerDisable(void); void IC_enable_irq(uint8_t irq_line); void IC_disable_irq(uint8_t irq_line); -void InterruptControllerSendEOI(void); +void InterruptControllerSendEOI(uint64_t interrupt_number); void InterruptControllerSetTimer(uint32_t frequency_hz); // Query functions diff --git a/drivers/Pic.c b/drivers/Pic.c index 3c17f8e..84aaae9 100644 --- a/drivers/Pic.c +++ b/drivers/Pic.c @@ -59,6 +59,16 @@ void PIC_disable_irq(uint8_t irq_line) { pic_write_mask(); } +void PICMaskAll() { + s_irq_mask = 0xFFFF; + pic_write_mask(); +} + +void PICSendEOI(uint64_t interrupt_number) { + if (interrupt_number >= 40) outb(PIC2_COMMAND, 0x20); + outb(PIC1_COMMAND, 0x20); +} + void PicInstall() { // Standard initialization sequence outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); diff --git a/drivers/Pic.h b/drivers/Pic.h index e1e2f54..6bfeb4e 100644 --- a/drivers/Pic.h +++ b/drivers/Pic.h @@ -7,5 +7,7 @@ void PitInstall(); void PitSetFrequency(uint16_t hz); void PIC_enable_irq(uint8_t irq_line); void PIC_disable_irq(uint8_t irq_line); +void PICMaskAll(); +void PICSendEOI(uint64_t interrupt_number); #endif \ No newline at end of file diff --git a/include/Io.h b/include/Io.h index fe0e0a4..4435f10 100644 --- a/include/Io.h +++ b/include/Io.h @@ -53,5 +53,25 @@ static inline void sti(void) { asm volatile("sti"); } +// CPUID detection +static inline void __attribute__((always_inline)) cpuid(uint32_t leaf, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) { + __asm__ volatile("cpuid" + : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) + : "a"(leaf)); +} + +// MSR access +static inline __attribute__((always_inline)) uint64_t rdmsr(uint32_t msr) { + uint32_t low, high; + __asm__ volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(msr)); + return ((uint64_t)high << 32) | low; +} + +static inline __attribute__((always_inline)) void wrmsr(uint32_t msr, uint64_t value) { + uint32_t low = value & 0xFFFFFFFF; + uint32_t high = value >> 32; + __asm__ volatile("wrmsr" :: "a"(low), "d"(high), "c"(msr)); +} + #endif diff --git a/kernel/core/Kernel.c b/kernel/core/Kernel.c index 8da2344..27dae63 100644 --- a/kernel/core/Kernel.c +++ b/kernel/core/Kernel.c @@ -7,6 +7,7 @@ #include "ISA.h" #include "Ide.h" #include "Idt.h" +#include "Io.h" #include "KernelHeap.h" #include "LPT/LPT.h" #include "MemOps.h" @@ -640,15 +641,16 @@ static InitResultT PXS2(void) { LPT_Init(); PrintKernelSuccess("System: LPT Driver initialized\n"); - // NEW: Final memory health check PrintKernel("Info: Final memory health check...\n"); GetDetailedMemoryStats(&stats); if (stats.fragmentation_score > 50) { PrintKernelWarning("[WARN] High memory fragmentation detected\n"); } + // Unmask IRQs IRQUnmaskCoreSystems(); + // Memory protection StackGuardInit(); SetupMemoryProtection(); @@ -685,7 +687,7 @@ void KernelMainHigherHalf(void) { PrintKernelSuccess("System: Kernel initialization complete\n"); PrintKernelSuccess("System: Initializing interrupts...\n"); - asm volatile("sti"); + sti(); while (1) { // redundant but added for worst case scenario, should not reach here Yield(); diff --git a/kernel/core/Multiboot2.h b/kernel/core/Multiboot2.h index 31c70f6..80aa241 100644 --- a/kernel/core/Multiboot2.h +++ b/kernel/core/Multiboot2.h @@ -1,8 +1,8 @@ #ifndef MB2_H #define MB2_H #include "stdint.h" -#define MULTIBOOT2_MAGIC_HEADER 0xE85250D6 // in your boot.asm -#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36D76289 // passed to your kernel +#define MULTIBOOT2_MAGIC_HEADER 0xE85250D6 +#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36D76289 #define MULTIBOOT2_TAG_TYPE_END 0 #define MULTIBOOT2_TAG_TYPE_CMDLINE 1 #define MULTIBOOT2_TAG_TYPE_BOOTLOADER_NAME 2 diff --git a/kernel/core/Panic.c b/kernel/core/Panic.c index 3b826db..ae0ff70 100644 --- a/kernel/core/Panic.c +++ b/kernel/core/Panic.c @@ -1,5 +1,5 @@ #include "Panic.h" - +#include "Io.h" // The ONLY necessary includes for display are now Console and Serial #include "Console.h" #include "KernelHeap.h" @@ -61,7 +61,7 @@ static void U32ToDecStr(uint32_t value, char* buffer) { // --- High-Level Panic Screen Composition --- void __attribute__((noreturn)) KernelPanicHandler(const char* message, uint64_t error_code, PanicContext* ctx) { - asm volatile("cli"); + cli(); ClearScreen(); ConsoleSetColor(VGA_COLOR_WHITE); @@ -253,7 +253,7 @@ static inline uint64_t __get_rip(void) { } void __attribute__((noreturn)) PanicFromInterrupt(const char* message, Registers* regs) { - asm volatile("cli"); + cli(); PanicContext ctx = {0}; ctx.rip = regs->rip; ctx.rsp = regs->rsp; @@ -266,7 +266,7 @@ void __attribute__((noreturn)) PanicFromInterrupt(const char* message, Registers } void __attribute__((noreturn)) Panic(const char* message) { - asm volatile("cli"); + cli(); PanicContext ctx = {0}; ctx.rip = __get_rip(); asm volatile("movq %%rsp, %0" : "=r"(ctx.rsp)); @@ -275,7 +275,7 @@ void __attribute__((noreturn)) Panic(const char* message) { } void __attribute__((noreturn)) PanicWithCode(const char* message, uint64_t error_code) { - asm volatile("cli"); + cli(); PanicContext ctx = {0}; ctx.rip = __get_rip(); asm volatile("movq %%rsp, %0" : "=r"(ctx.rsp)); @@ -284,7 +284,7 @@ void __attribute__((noreturn)) PanicWithCode(const char* message, uint64_t error } void __attribute__((noreturn)) PanicWithContext(const char* message, uint64_t error_code, const char* function, const char* file, int line) { - asm volatile("cli"); + cli(); PanicContext ctx = {0}; ctx.rip = __get_rip(); asm volatile("movq %%rsp, %0" : "=r"(ctx.rsp)); diff --git a/kernel/process/Process.c b/kernel/process/Process.c index 2367f4a..24a0e74 100644 --- a/kernel/process/Process.c +++ b/kernel/process/Process.c @@ -426,24 +426,21 @@ void InitScheduler(void) { // Initialize with smart quantum allocation for (int i = 0; i < MAX_PRIORITY_LEVELS; i++) { + // This block had a redundant inner if and a misplaced else clause. if (i < RT_PRIORITY_THRESHOLD) { - // Real-time queues get larger quantums - if (i < RT_PRIORITY_THRESHOLD) { - MLFQscheduler.queues[i].quantum = QUANTUM_BASE << (RT_PRIORITY_THRESHOLD - i); - if (MLFQscheduler.queues[i].quantum > QUANTUM_MAX) { - MLFQscheduler.queues[i].quantum = QUANTUM_MAX; - } - } else { - MLFQscheduler.queues[i].quantum = QUANTUM_BASE >> ((i - RT_PRIORITY_THRESHOLD) * QUANTUM_DECAY_SHIFT); - if (MLFQscheduler.queues[i].quantum < QUANTUM_MIN) { - MLFQscheduler.queues[i].quantum = QUANTUM_MIN; - } + // Real-time queues get larger quantums for higher priority (lower i) + MLFQscheduler.queues[i].quantum = QUANTUM_BASE << (RT_PRIORITY_THRESHOLD - i); + if (MLFQscheduler.queues[i].quantum > QUANTUM_MAX) { + MLFQscheduler.queues[i].quantum = QUANTUM_MAX; } MLFQscheduler.rt_bitmap |= (1U << i); } else { - // Regular queues use exponential decay MLFQscheduler.queues[i].quantum = QUANTUM_BASE >> ((i - RT_PRIORITY_THRESHOLD) * QUANTUM_DECAY_SHIFT); + if (MLFQscheduler.queues[i].quantum < QUANTUM_MIN) { + MLFQscheduler.queues[i].quantum = QUANTUM_MIN; + } } + MLFQscheduler.queues[i].head = NULL; MLFQscheduler.queues[i].tail = NULL; MLFQscheduler.queues[i].count = 0; @@ -505,9 +502,10 @@ void AddToScheduler(uint32_t slot) { proc->priority = priority; proc->base_priority = priority; // Remember original proc->last_scheduled_tick = MLFQscheduler.tick_counter; - + EnQueue(&MLFQscheduler.queues[priority], slot); MLFQscheduler.active_bitmap |= (1U << priority); + if (priority < RT_PRIORITY_THRESHOLD) MLFQscheduler.rt_bitmap |= (1U << priority); MLFQscheduler.total_processes++; } @@ -642,10 +640,8 @@ static void SmartAging(void) { queue->count--; - // To prevent starvation, user processes must be boosted - // to the highest priority (0) to guarantee they get to run. Boosting - // them to a lower priority was ineffective. - uint32_t new_priority = 0; + // IF NONE OTHER THAN 0, breaks + uint32_t new_priority = RT_PRIORITY_THRESHOLD; proc->priority = new_priority; proc->last_scheduled_tick = current_tick; @@ -759,6 +755,12 @@ void FastSchedule(struct Registers* regs) { old_proc->cpu_burst_history[0] = cpu_burst; old_proc->cpu_time_accumulated += cpu_burst; + if (UNLIKELY(!ValidateToken(&old_proc->token, old_proc->pid))) { + // This process ran and its token is now corrupt. Terminate immediately. + ASTerminate(old_proc->pid, "Post-execution token corruption"); + goto select_next; // Don't re-queue a corrupt process + } + FastMemcpy(&old_proc->context, regs, sizeof(struct Registers)); if (LIKELY(MLFQscheduler.quantum_remaining > 0)) { @@ -1360,6 +1362,9 @@ static void DynamoX(void) { if (new_freq < effective_min) new_freq = effective_min; if (new_freq > effective_max) new_freq = effective_max; + uint32_t smoothing_factor = SMOOTHING_FACTOR; // Average over 4 samples (1/4 new, 3/4 old) + new_freq = (new_freq + (controller.current_freq << smoothing_factor) - controller.current_freq) >> smoothing_factor; + // Enhanced hysteresis with stability consideration uint32_t change_threshold = (controller.stability_counter > STABILITY_REQUIREMENT) ? HYSTERESIS_THRESHOLD / 2 : HYSTERESIS_THRESHOLD; diff --git a/kernel/process/Process.h b/kernel/process/Process.h index 64b2e6b..71b2130 100644 --- a/kernel/process/Process.h +++ b/kernel/process/Process.h @@ -11,7 +11,7 @@ // Core Queue Configuration #define MAX_PRIORITY_LEVELS 5 // Reduced from 6 - fewer levels = better cache locality -#define RT_PRIORITY_THRESHOLD 3 // Increased RT levels for better interactive response +#define RT_PRIORITY_THRESHOLD 0 // Increased RT levels for better interactive response #define MAX_PROCESSES 64 // Keep as is // Quantum Management - EXPONENTIAL GROWTH for better differentiation @@ -97,6 +97,7 @@ #define FXP_SHIFT 10 // Use 10 bits for the fractional part #define FXP_SCALE (1 << FXP_SHIFT) // Scaling factor = 1024 +#define SMOOTHING_FACTOR 2 // Average over 4 samples (1/4 new, 3/4 old) #define SAMPLING_INTERVAL 25 // 2x faster sampling (was 50) #define HZ_PER_PROCESS 50 // More responsive per-process scaling (was 30) #define QUEUE_PRESSURE_FACTOR 20 // Stronger pressure response