diff --git a/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp b/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp index e69da19..6cd8026 100644 --- a/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp +++ b/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp @@ -35,7 +35,7 @@ namespace APIC uint32_t APIC::Read(uint32_t Register) { - debug("APIC::Read(%#lx)", Register); + debug("APIC::Read(%#lx) [x2=%d]", Register, x2APICSupported ? 1 : 0); if (x2APICSupported) { if (Register != APIC_ICRHI) @@ -50,7 +50,7 @@ namespace APIC void APIC::Write(uint32_t Register, uint32_t Value) { if (Register != APIC_EOI) - debug("APIC::Write(%#lx, %#lx)", Register, Value); + debug("APIC::Write(%#lx, %#lx) [x2=%d]", Register, Value, x2APICSupported ? 1 : 0); if (x2APICSupported) { if (Register != APIC_ICRHI) diff --git a/Architecture/amd64/cpu/GlobalDescriptorTable.cpp b/Architecture/amd64/cpu/GlobalDescriptorTable.cpp index 9cb08e7..239fe09 100644 --- a/Architecture/amd64/cpu/GlobalDescriptorTable.cpp +++ b/Architecture/amd64/cpu/GlobalDescriptorTable.cpp @@ -58,8 +58,8 @@ namespace GlobalDescriptorTable tss[Core].InterruptStackTable[2] = (uint64_t)KernelAllocator.RequestPage(); CPU::x64::ltr(GDT_TSS); - asm volatile("mov %%rsp, %0" - : "=r"(tss[Core].StackPointer[0])); + asmv("mov %%rsp, %0" + : "=r"(tss[Core].StackPointer[0])); trace("GDT_KERNEL_CODE: %#lx", GDT_KERNEL_CODE); trace("GDT_KERNEL_DATA: %#lx", GDT_KERNEL_DATA); diff --git a/Architecture/amd64/cpu/InterruptDescriptorTable.cpp b/Architecture/amd64/cpu/InterruptDescriptorTable.cpp index 7d48691..320417a 100644 --- a/Architecture/amd64/cpu/InterruptDescriptorTable.cpp +++ b/Architecture/amd64/cpu/InterruptDescriptorTable.cpp @@ -156,7 +156,8 @@ namespace InterruptDescriptorTable "jmp InterruptHandlerStub\n"); \ } - // ISR + /* ISR */ + EXCEPTION_HANDLER(0x0); EXCEPTION_HANDLER(0x1); EXCEPTION_HANDLER(0x2); @@ -189,7 +190,9 @@ namespace InterruptDescriptorTable EXCEPTION_HANDLER(0x1d); EXCEPTION_HANDLER(0x1e); EXCEPTION_HANDLER(0x1f); - // IRQ + + /* IRQ */ + INTERRUPT_HANDLER(0x20) INTERRUPT_HANDLER(0x21) INTERRUPT_HANDLER(0x22) @@ -207,7 +210,12 @@ namespace InterruptDescriptorTable INTERRUPT_HANDLER(0x2e) INTERRUPT_HANDLER(0x2f) - INTERRUPT_HANDLER(0x30) + /* Reserved by OS */ + + __attribute__((naked, used, no_stack_protector)) void InterruptHandler_0x30() { asm("pushq $0\npushq $" + "0x30" + "\n" + "jmp SchedulerInterruptStub\n"); } INTERRUPT_HANDLER(0x31) INTERRUPT_HANDLER(0x32) INTERRUPT_HANDLER(0x33) @@ -221,6 +229,9 @@ namespace InterruptDescriptorTable INTERRUPT_HANDLER(0x3b) INTERRUPT_HANDLER(0x3c) INTERRUPT_HANDLER(0x3d) + + /* Free */ + INTERRUPT_HANDLER(0x3e) INTERRUPT_HANDLER(0x3f) INTERRUPT_HANDLER(0x40) @@ -420,6 +431,8 @@ namespace InterruptDescriptorTable void Init(int Core) { + /* ISR */ + SetEntry(0x0, InterruptHandler_0x0, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x1, InterruptHandler_0x1, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x2, InterruptHandler_0x2, FlagGate_32BIT_TRAP, 2, FlagGate_RING0, GDT_KERNEL_CODE); @@ -452,7 +465,9 @@ namespace InterruptDescriptorTable SetEntry(0x1d, InterruptHandler_0x1d, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x1e, InterruptHandler_0x1e, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x1f, InterruptHandler_0x1f, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - // IRQ + + /* IRQ */ + SetEntry(0x20, InterruptHandler_0x20, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x21, InterruptHandler_0x21, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x22, InterruptHandler_0x22, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); @@ -470,6 +485,8 @@ namespace InterruptDescriptorTable SetEntry(0x2e, InterruptHandler_0x2e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x2f, InterruptHandler_0x2f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + /* Reserved by OS */ + SetEntry(0x30, InterruptHandler_0x30, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x31, InterruptHandler_0x31, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x32, InterruptHandler_0x32, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); @@ -484,6 +501,9 @@ namespace InterruptDescriptorTable SetEntry(0x3b, InterruptHandler_0x3b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x3c, InterruptHandler_0x3c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x3d, InterruptHandler_0x3d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + + /* Free */ + SetEntry(0x3e, InterruptHandler_0x3e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x3f, InterruptHandler_0x3f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x40, InterruptHandler_0x40, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); diff --git a/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp b/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp index e098e1e..721d376 100644 --- a/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp +++ b/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp @@ -52,6 +52,8 @@ extern "C" void StartCPU() namespace SMP { + int CPUCores = 0; + void Initialize(void *madt) { if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_VIRTUALBOX) == 0) @@ -67,6 +69,8 @@ namespace SMP else if (Config.Cores != 0) Cores = Config.Cores; + CPUCores = Cores; + for (uint16_t i = 0; i < Cores; i++) { debug("Initializing CPU %d", i); @@ -87,8 +91,8 @@ namespace SMP POKE(volatile uint64_t, STACK) = (uint64_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE; POKE(volatile uint64_t, CORE) = i; - asm volatile("sgdt [0x580]\n" - "sidt [0x590]\n"); + asmv("sgdt [0x580]\n" + "sidt [0x590]\n"); POKE(volatile uint64_t, START_ADDR) = (uintptr_t)&StartCPU; @@ -103,7 +107,7 @@ namespace SMP CPUEnabled = false; } else - KPrint("CPU %d is the BSP", ((ACPI::MADT *)madt)->lapic[i]->APICId); + KPrint("\e058C19CPU \e8888FF%d \e058C19is the BSP", ((ACPI::MADT *)madt)->lapic[i]->APICId); } } } diff --git a/Architecture/amd64/cpu/apic.hpp b/Architecture/amd64/cpu/apic.hpp index 4ecb0f5..6e54a8a 100644 --- a/Architecture/amd64/cpu/apic.hpp +++ b/Architecture/amd64/cpu/apic.hpp @@ -18,12 +18,12 @@ namespace APIC APIC_VER = 0x30, // Local APIC Version APIC_TPR = 0x80, // Task Priority APIC_APR = 0x90, // Arbitration Priority - APIC_PPR = 0xa0, // Processor Priority - APIC_EOI = 0xb0, // EOI - APIC_RRD = 0xc0, // Remote Read - APIC_LDR = 0xd0, // Logical Destination - APIC_DFR = 0xe0, // Destination Format - APIC_SVR = 0xf0, // Spurious Interrupt Vector + APIC_PPR = 0xA0, // Processor Priority + APIC_EOI = 0xB0, // EOI + APIC_RRD = 0xC0, // Remote Read + APIC_LDR = 0xD0, // Logical Destination + APIC_DFR = 0xE0, // Destination Format + APIC_SVR = 0xF0, // Spurious Interrupt Vector APIC_ISR = 0x100, // In-Service (8 registers) APIC_TMR = 0x180, // Trigger Mode (8 registers) APIC_IRR = 0x200, // Interrupt Request (8 registers) @@ -38,7 +38,7 @@ namespace APIC APIC_ERROR = 0x370, // LVT Error APIC_TICR = 0x380, // Initial Count (for Timer) APIC_TCCR = 0x390, // Current Count (for Timer) - APIC_TDCR = 0x3e0, // Divide Configuration (for Timer) + APIC_TDCR = 0x3E0, // Divide Configuration (for Timer) }; class APIC { diff --git a/Core/CrashHandler.cpp b/Core/CrashHandler.cpp index bf5cc32..9ad0af4 100644 --- a/Core/CrashHandler.cpp +++ b/Core/CrashHandler.cpp @@ -89,18 +89,18 @@ namespace CrashHandler // store debug registers debug("Reading debug registers..."); - asm volatile("movq %%dr0, %0" - : "=r"(dr0)); - asm volatile("movq %%dr1, %0" - : "=r"(dr1)); - asm volatile("movq %%dr2, %0" - : "=r"(dr2)); - asm volatile("movq %%dr3, %0" - : "=r"(dr3)); - asm volatile("movq %%dr6, %0" - : "=r"(dr6)); - asm volatile("movq %%dr7, %0" - : "=r"(dr7)); + asmv("movq %%dr0, %0" + : "=r"(dr0)); + asmv("movq %%dr1, %0" + : "=r"(dr1)); + asmv("movq %%dr2, %0" + : "=r"(dr2)); + asmv("movq %%dr3, %0" + : "=r"(dr3)); + asmv("movq %%dr6, %0" + : "=r"(dr6)); + asmv("movq %%dr7, %0" + : "=r"(dr7)); switch (Frame->InterruptNumber) { @@ -272,24 +272,24 @@ namespace CrashHandler // restore debug registers debug("Restoring debug registers..."); - asm volatile("movq %0, %%dr0" - : - : "r"(dr0)); - asm volatile("movq %0, %%dr1" - : - : "r"(dr1)); - asm volatile("movq %0, %%dr2" - : - : "r"(dr2)); - asm volatile("movq %0, %%dr3" - : - : "r"(dr3)); - asm volatile("movq %0, %%dr6" - : - : "r"(dr6)); - asm volatile("movq %0, %%dr7" - : - : "r"(dr7)); + asmv("movq %0, %%dr0" + : + : "r"(dr0)); + asmv("movq %0, %%dr1" + : + : "r"(dr1)); + asmv("movq %0, %%dr2" + : + : "r"(dr2)); + asmv("movq %0, %%dr3" + : + : "r"(dr3)); + asmv("movq %0, %%dr6" + : + : "r"(dr6)); + asmv("movq %0, %%dr7" + : + : "r"(dr7)); struct StackFrame { diff --git a/Core/Power.cpp b/Core/Power.cpp index 84c592d..b17637e 100644 --- a/Core/Power.cpp +++ b/Core/Power.cpp @@ -28,7 +28,7 @@ namespace Power // second attempt to reboot // https://wiki.osdev.org/Reboot uint8_t temp; - asm volatile("cli"); + asmv("cli"); do { temp = inb(0x64); diff --git a/Kernel.cpp b/Kernel.cpp index a36e881..fa2b604 100644 --- a/Kernel.cpp +++ b/Kernel.cpp @@ -82,8 +82,8 @@ EXTERNC void Entry(BootInfo *Info) Interrupts::InitializeTimer(0); KPrint("Initializing SMP"); SMP::Initialize(PowerManager->GetMADT()); - KPrint("\e058C19######## \eE85230END \e058C19########"); CPU::Interrupts(CPU::Enable); TaskManager = new Tasking::Task((Tasking::IP)KernelMainThread); + KPrint("\e058C19######## \eE85230END \e058C19########"); CPU::Stop(); } diff --git a/Tasking/Task.cpp b/Tasking/Task.cpp index 2c2d570..18776dc 100644 --- a/Tasking/Task.cpp +++ b/Tasking/Task.cpp @@ -1,26 +1,101 @@ #include + +#include +#include #include #include -#include -NewLock(TaskingLock); +#include "../kernel.h" #if defined(__amd64__) +#include "../Architecture/amd64/cpu/apic.hpp" #include "../Architecture/amd64/cpu/gdt.hpp" #elif defined(__i386__) #elif defined(__aarch64__) #endif +NewLock(TaskingLock); + namespace Tasking { + extern "C" void OneShot(int TimeSlice) + { #if defined(__amd64__) + ((APIC::Timer *)Interrupts::apicTimer[GetCurrentCPU()->ID])->OneShot(CPU::x64::IRQ16, TimeSlice); #elif defined(__i386__) #elif defined(__aarch64__) #endif + } - void a() + extern "C" __attribute__((naked, used, no_stack_protector)) void IdleProcessLoop() { - return; +#if defined(__amd64__) || defined(__i386__) + asmv("IdleLoop:\n" + "call OneShot\n" + "hlt\n" + "jmp IdleLoop\n"); +#elif defined(__aarch64__) + asmv("IdleLoop:\n" + "wfe\n" + "b IdleLoop\n"); +#endif + } + + /** @brief Called by the IDT (IRQ16 for x64 and x32) */ + extern "C" __attribute__((naked, used, no_stack_protector)) void SchedulerInterruptStub() + { +#if defined(__amd64__) + asm("cld\n" + "pushq %rax\n" + "pushq %rbx\n" + "pushq %rcx\n" + "pushq %rdx\n" + "pushq %rsi\n" + "pushq %rdi\n" + "pushq %rbp\n" + "pushq %r8\n" + "pushq %r9\n" + "pushq %r10\n" + "pushq %r11\n" + "pushq %r12\n" + "pushq %r13\n" + "pushq %r14\n" + "pushq %r15\n" + "movq %ds, %rax\n" + "pushq %rax\n" + "movq %rsp, %rdi\n" + "call SchedulerInterruptHandler\n" + "popq %rax\n" // Pop the DS register + "popq %r15\n" + "popq %r14\n" + "popq %r13\n" + "popq %r12\n" + "popq %r11\n" + "popq %r10\n" + "popq %r9\n" + "popq %r8\n" + "popq %rbp\n" + "popq %rdi\n" + "popq %rsi\n" + "popq %rdx\n" + "popq %rcx\n" + "popq %rbx\n" + "popq %rax\n" + "addq $16, %rsp\n" + "iretq"); +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif + } + + extern "C" __attribute__((no_stack_protector)) void SchedulerInterruptHandler(ThreadFrame *Frame) + { + fixme("SchedulerInterruptHandler: %d", GetCurrentCPU()->ID); +#if defined(__amd64__) + ((APIC::APIC *)Interrupts::apic[GetCurrentCPU()->ID])->EOI(); +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif } PCB *Task::GetCurrentProcess() @@ -36,7 +111,7 @@ namespace Tasking } PCB *Task::CreateProcess(PCB *Parent, - char *Name, + const char *Name, TaskElevation Elevation) { SmartCriticalSection(TaskingLock); @@ -63,7 +138,19 @@ namespace Tasking Task::Task(const IP EntryPoint) { SmartCriticalSection(TaskingLock); - trace("Starting tasking with IP: %#lx", EntryPoint); + KPrint("Starting Tasking With Instruction Pointer: %p (\e666666%s\eCCCCCC)", EntryPoint, KernelSymbolTable->GetSymbolFromAddress(EntryPoint)); +#if defined(__amd64__) || defined(__i386__) + for (int i = 0; i < SMP::CPUCores; i++) + ((APIC::APIC *)Interrupts::apic[i])->RedirectIRQ(i, CPU::x64::IRQ16 - CPU::x64::IRQ0, 1); +#endif + + TaskingLock.Unlock(); + PCB *kproc = CreateProcess(nullptr, "Kernel", TaskElevation::Kernel); + TCB *kthrd = CreateThread(kproc, EntryPoint); + kthrd->Rename("Main Thread"); + TaskingLock.Lock(); + OneShot(100); + debug("Tasking Started"); } Task::~Task() diff --git a/include/cpu.hpp b/include/cpu.hpp index b5aab52..8e3863b 100644 --- a/include/cpu.hpp +++ b/include/cpu.hpp @@ -728,6 +728,8 @@ namespace CPU typedef enum { + /* ISR */ + ISR0 = 0x0, // Divide-by-zero Error ISR1 = 0x1, // Debug ISR2 = 0x2, // Non-maskable Interrupt @@ -761,26 +763,29 @@ namespace CPU ISR30 = 0x1e, // Security Exception ISR31 = 0x1f, // Reserved - IRQ0 = 0x20, // Programmable Interrupt Timer Interrupt - IRQ1 = 0x21, // Keyboard Interrupt - IRQ2 = 0x22, // Cascade (used internally by the two PICs. never raised) - IRQ3 = 0x23, // COM2 (if enabled) - IRQ4 = 0x24, // COM1 (if enabled) - IRQ5 = 0x25, // LPT2 (if enabled) - IRQ6 = 0x26, // Floppy Disk - IRQ7 = 0x27, // LPT1 / Unreliable "spurious" interrupt (usually) - IRQ8 = 0x28, // CMOS real-time clock (if enabled) - IRQ9 = 0x29, // Free for peripherals / legacy SCSI / NIC - IRQ10 = 0x2a, // Free for peripherals / SCSI / NIC - IRQ11 = 0x2b, // Free for peripherals / SCSI / NIC - IRQ12 = 0x2c, // PS2 Mouse - IRQ13 = 0x2d, // FPU / Coprocessor / Inter-processor - IRQ14 = 0x2e, // Primary ATA Hard Disk - IRQ15 = 0x2f, // Secondary ATA Hard Disk + /* IRQ */ - IRQ16 = 0x30, // Reserved for multitasking - IRQ17 = 0x31, // Reserved for monotasking + IRQ0 = 0x20, // Programmable Interrupt Timer Interrupt + IRQ1 = 0x21, // Keyboard Interrupt + IRQ2 = 0x22, // Cascade (used internally by the two PICs. never raised) + IRQ3 = 0x23, // COM2 (if enabled) + IRQ4 = 0x24, // COM1 (if enabled) + IRQ5 = 0x25, // LPT2 (if enabled) + IRQ6 = 0x26, // Floppy Disk + IRQ7 = 0x27, // LPT1 / Unreliable "spurious" interrupt (usually) + IRQ8 = 0x28, // CMOS real-time clock (if enabled) + IRQ9 = 0x29, // Free for peripherals / legacy SCSI / NIC + IRQ10 = 0x2a, // Free for peripherals / SCSI / NIC + IRQ11 = 0x2b, // Free for peripherals / SCSI / NIC + IRQ12 = 0x2c, // PS2 Mouse + IRQ13 = 0x2d, // FPU / Coprocessor / Inter-processor + IRQ14 = 0x2e, // Primary ATA Hard Disk + IRQ15 = 0x2f, // Secondary ATA Hard Disk + /* Reserved by OS */ + + IRQ16 = 0x30, // Reserved for multitasking + IRQ17 = 0x31, IRQ18 = 0x32, IRQ19 = 0x33, IRQ20 = 0x34, @@ -793,6 +798,9 @@ namespace CPU IRQ27 = 0x3b, IRQ28 = 0x3c, IRQ29 = 0x3d, + + /* Free */ + IRQ30 = 0x3e, IRQ31 = 0x3f, IRQ32 = 0x40, diff --git a/include/smp.hpp b/include/smp.hpp index 3766e1e..7e0ab38 100644 --- a/include/smp.hpp +++ b/include/smp.hpp @@ -49,6 +49,7 @@ CPUData *GetCPU(long ID); namespace SMP { + extern int CPUCores; void Initialize(void *madt); } diff --git a/include/task.hpp b/include/task.hpp index 8143ff2..b169cc2 100644 --- a/include/task.hpp +++ b/include/task.hpp @@ -3,13 +3,118 @@ #include +#include +#include + namespace Tasking { typedef unsigned long IP; + typedef unsigned long IPOffset; typedef unsigned long UPID; typedef unsigned long UTID; typedef unsigned long Token; + struct ThreadFrame + { +#if defined(__amd64__) + // uint64_t gs; // General-purpose Segment + // uint64_t fs; // General-purpose Segment + // uint64_t es; // Extra Segment (used for string operations) + uint64_t ds; // Data Segment + uint64_t r15; // General purpose + uint64_t r14; // General purpose + uint64_t r13; // General purpose + uint64_t r12; // General purpose + uint64_t r11; // General purpose + uint64_t r10; // General purpose + uint64_t r9; // General purpose + uint64_t r8; // General purpose + uint64_t rbp; // Base Pointer (meant for stack frames) + uint64_t rdi; // First Argument + uint64_t rsi; // Second Argument + uint64_t rdx; // Data (commonly extends the A register) + uint64_t rcx; // Counter + uint64_t rbx; // Base + uint64_t rax; // Accumulator + uint64_t int_num; // Interrupt Number + uint64_t error_code; // Error code + uint64_t rip; // Instruction Pointer + uint64_t cs; // Code Segment + union + { + struct + { + /** @brief Carry Flag */ + uint64_t CF : 1; + /** @brief Reserved */ + uint64_t always_one : 1; + /** @brief Parity Flag */ + uint64_t PF : 1; + /** @brief Reserved */ + uint64_t _reserved0 : 1; + /** @brief Auxiliary Carry Flag */ + uint64_t AF : 1; + /** @brief Reserved */ + uint64_t _reserved1 : 1; + /** @brief Zero Flag */ + uint64_t ZF : 1; + /** @brief Sign Flag */ + uint64_t SF : 1; + /** @brief Trap Flag */ + uint64_t TF : 1; + /** @brief Interrupt Enable Flag */ + uint64_t IF : 1; + /** @brief Direction Flag */ + uint64_t DF : 1; + /** @brief Overflow Flag */ + uint64_t OF : 1; + /** @brief I/O Privilege Level */ + uint64_t IOPL : 2; + /** @brief Nested Task */ + uint64_t NT : 1; + /** @brief Reserved */ + uint64_t _reserved2 : 1; + /** @brief Resume Flag */ + uint64_t RF : 1; + /** @brief Virtual 8086 Mode */ + uint64_t VM : 1; + /** @brief Alignment Check */ + uint64_t AC : 1; + /** @brief Virtual Interrupt Flag */ + uint64_t VIF : 1; + /** @brief Virtual Interrupt Pending */ + uint64_t VIP : 1; + /** @brief ID Flag */ + uint64_t ID : 1; + /** @brief Reserved */ + uint64_t _reserved3 : 10; + }; + uint64_t raw; + } rflags; // Register Flags + uint64_t rsp; // Stack Pointer + uint64_t ss; // Stack Segment / Data Segment +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif + }; + + enum TaskArchitecture + { + UnknownArchitecture, + x86, + x64, + ARM, + ARM64 + }; + + enum TaskPlatform + { + UnknownPlatform, + Native, + Linux, + Windows + }; + enum TaskElevation { UnknownElevation, @@ -35,19 +140,57 @@ namespace Tasking Token UniqueToken; }; - struct PCB + struct TaskInfo { - UPID PID; - char Name[256]; - TaskSecurity Security; - TaskStatus Status; + uint64_t SpawnTime = 0, UsedTime = 0, OldUsedTime = 0; + uint64_t OldSystemTime = 0, CurrentSystemTime = 0; + uint64_t Year, Month, Day, Hour, Minute, Second; + uint64_t Usage[256]; // MAX_CPU + TaskArchitecture Architecture; + TaskPlatform Platform; + int Priority; + bool Affinity[256]; // MAX_CPU }; struct TCB { - UTID TID; - PCB *Parent; + UTID ID; + char Name[256]; + struct PCB *Parent; IP EntryPoint; + IPOffset Offset; + int ExitCode; + void *Stack; + ThreadFrame Registers; + TaskSecurity Security; + TaskInfo Info; + TaskStatus Status; + TaskElevation Elevation; + + void Rename(const char *name) + { + for (int i = 0; i < 256; i++) + { + Name[i] = name[i]; + if (name[i] == '\0') + break; + } + } + }; + + struct PCB + { + UPID ID; + char Name[256]; + PCB *Parent; + int ExitCode; + TaskSecurity Security; + TaskInfo Info; + TaskStatus Status; + TaskElevation Elevation; + Vector Threads; + Vector Children; + // Memory::PageTable PageTable; }; class Task @@ -55,18 +198,18 @@ namespace Tasking public: /** * @brief Get the Current Process object - * @return PCB* + * @return PCB* */ PCB *GetCurrentProcess(); /** * @brief Get the Current Thread object - * @return TCB* + * @return TCB* */ TCB *GetCurrentThread(); PCB *CreateProcess(PCB *Parent, - char *Name, + const char *Name, TaskElevation Elevation); TCB *CreateThread(PCB *Parent,