diff --git a/Architecture/amd64/DifferentiatedSystemDescriptionTable.cpp b/Architecture/amd64/DifferentiatedSystemDescriptionTable.cpp index b81d7fc..4c0b102 100644 --- a/Architecture/amd64/DifferentiatedSystemDescriptionTable.cpp +++ b/Architecture/amd64/DifferentiatedSystemDescriptionTable.cpp @@ -61,8 +61,8 @@ namespace ACPI else if (Event & ACPI_POWER_BUTTON) { this->Shutdown(); - Time tm = ReadClock(); - while (tm.Second == ReadClock().Second) + Time::Clock tm = Time::ReadClock(); + while (tm.Second == Time::ReadClock().Second) ; outw(0xB004, 0x2000); outw(0x604, 0x2000); diff --git a/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp b/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp index 62cec0a..6f84d69 100644 --- a/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp +++ b/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp @@ -239,7 +239,7 @@ namespace APIC } this->Write(APIC_TPR, 0x0); - this->Write(APIC_SVR, this->Read(APIC_SVR) | 0x100); // 0x1FF or 0x100 ? on https://wiki.osdev.org/APIC is 0x100 + // this->Write(APIC_SVR, this->Read(APIC_SVR) | 0x100); // 0x1FF or 0x100 ? on https://wiki.osdev.org/APIC is 0x100 if (!this->x2APICSupported) { @@ -292,8 +292,8 @@ namespace APIC LVTTimer timer = {.raw = 0}; timer.Vector = Vector; timer.TimerMode = 0; - this->lapic->Write(APIC_TDCR, 0x0); - this->lapic->Write(APIC_TICR, (Ticks / 10) * Miliseconds); + this->lapic->Write(APIC_TDCR, DivideBy16); + this->lapic->Write(APIC_TICR, Ticks * Miliseconds); this->lapic->Write(APIC_TIMER, timer.raw); } @@ -301,6 +301,8 @@ namespace APIC { SmartCriticalSection(APICLock); this->lapic = apic; + LVTTimerDivide Divider = DivideBy16; + trace("Initializing APIC timer on CPU %d", GetCurrentCPU()->ID); // Setup the spurrious interrupt vector @@ -309,51 +311,13 @@ namespace APIC Spurious.Software = 1; this->lapic->Write(APIC_SVR, Spurious.raw); - this->lapic->Write(APIC_TDCR, 0x0); + this->lapic->Write(APIC_TDCR, Divider); this->lapic->Write(APIC_TICR, 0xFFFFFFFF); - // After PIT sleep is completed. Mask the timer. - LVTTimer masktimer = {.raw = 0x10000}; - - // // PIT Config - // int Count = 10000; /* µs */ - // int Ticks = 1193180 / (Count / 100); - - // // https://wiki.osdev.org/Programmable_Interval_Timer#I.2FO_Ports - - // // PIT Prepare - // int IOIn = inb(0x61); - // IOIn = (IOIn & 0xFD) | 1; - // outb(0x61, IOIn); - // outb(0x43, 178); - // outb(0x40, Ticks & 0xff); - // inb(0x60); - // outb(0x40, Ticks >> 8); - - // // PIT Start - // IOIn = inb(0x61); - // IOIn = (IOIn & 0xFC); - // outb(0x61, IOIn); - // IOIn |= 1; - // outb(0x61, IOIn); - // uint32_t Loop = 0; - // while ((inb(0x61) & 0x20) != 0) - // ++Loop; - - // 10000ms - for (int i = 0; i < 10000; i++) - inb(0x80); // 1µs + TimeManager->Sleep(10); // Mask the timer - this->lapic->Write(APIC_TIMER, masktimer.raw); - - // // Disable the PIT - // outb(0x43, 0x28); - // outb(0x40, 0x0); - - // outb(0x21, 0xFF); - // outb(0xA1, 0xFF); - + this->lapic->Write(APIC_TIMER, 0x10000 /* LVTTimer.Mask flag */); Ticks = 0xFFFFFFFF - this->lapic->Read(APIC_TCCR); // Config for IRQ0 timer @@ -363,7 +327,7 @@ namespace APIC timer.TimerMode = Periodic; // Initialize APIC timer - this->lapic->Write(APIC_TDCR, 0x0); + this->lapic->Write(APIC_TDCR, Divider); this->lapic->Write(APIC_TICR, Ticks); this->lapic->Write(APIC_TIMER, timer.raw); trace("%d APIC Timer %d ticks in.", GetCurrentCPU()->ID, Ticks); diff --git a/Core/Time.cpp b/Core/Time.cpp index ec28c99..96c9ac3 100644 --- a/Core/Time.cpp +++ b/Core/Time.cpp @@ -1,38 +1,41 @@ #include #include -Time ReadClock() +namespace Time { - Time tm; + Clock ReadClock() + { + Clock tm; #if defined(__amd64__) || defined(__i386__) - uint32_t t = 0; - outb(0x70, 0x00); - t = inb(0x71); - tm.Second = ((t & 0x0F) + ((t >> 4) * 10)); - outb(0x70, 0x02); - t = inb(0x71); - tm.Minute = ((t & 0x0F) + ((t >> 4) * 10)); - outb(0x70, 0x04); - t = inb(0x71); - tm.Hour = ((t & 0x0F) + ((t >> 4) * 10)); - outb(0x70, 0x07); - t = inb(0x71); - tm.Day = ((t & 0x0F) + ((t >> 4) * 10)); - outb(0x70, 0x08); - t = inb(0x71); - tm.Month = ((t & 0x0F) + ((t >> 4) * 10)); - outb(0x70, 0x09); - t = inb(0x71); - tm.Year = ((t & 0x0F) + ((t >> 4) * 10)); - tm.Counter = 0; + uint32_t t = 0; + outb(0x70, 0x00); + t = inb(0x71); + tm.Second = ((t & 0x0F) + ((t >> 4) * 10)); + outb(0x70, 0x02); + t = inb(0x71); + tm.Minute = ((t & 0x0F) + ((t >> 4) * 10)); + outb(0x70, 0x04); + t = inb(0x71); + tm.Hour = ((t & 0x0F) + ((t >> 4) * 10)); + outb(0x70, 0x07); + t = inb(0x71); + tm.Day = ((t & 0x0F) + ((t >> 4) * 10)); + outb(0x70, 0x08); + t = inb(0x71); + tm.Month = ((t & 0x0F) + ((t >> 4) * 10)); + outb(0x70, 0x09); + t = inb(0x71); + tm.Year = ((t & 0x0F) + ((t >> 4) * 10)); + tm.Counter = 0; #elif defined(__aarch64__) - tm.Year = 0; - tm.Month = 0; - tm.Day = 0; - tm.Hour = 0; - tm.Minute = 0; - tm.Second = 0; - tm.Counter = 0; + tm.Year = 0; + tm.Month = 0; + tm.Day = 0; + tm.Hour = 0; + tm.Minute = 0; + tm.Second = 0; + tm.Counter = 0; #endif - return tm; + return tm; + } } diff --git a/Core/Timer.cpp b/Core/Timer.cpp new file mode 100644 index 0000000..b064bbf --- /dev/null +++ b/Core/Timer.cpp @@ -0,0 +1,55 @@ +#include + +#include +#include +#include + +#if defined(__amd64__) +#include "../Architecture/amd64/acpi.hpp" +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif + +namespace Time +{ + void time::Sleep(uint64_t Milliseconds) + { + uint64_t Target = mminq(&((HPET *)hpet)->MainCounterValue) + (Milliseconds * 1000000000) / clk; + while (mminq(&((HPET *)hpet)->MainCounterValue) < Target) + ; + } + + time::time(void *_acpi) + { + if (_acpi) + { +#if defined(__amd64__) + this->acpi = _acpi; + ACPI::ACPI *acpi = (ACPI::ACPI *)this->acpi; + if (acpi->HPET) + { + Memory::Virtual().Map((void *)acpi->HPET->Address.Address, + (void *)acpi->HPET->Address.Address, + Memory::PTFlag::RW | Memory::PTFlag::PCD); + this->hpet = (void *)acpi->HPET->Address.Address; + HPET *hpet = (HPET *)this->hpet; + trace("%s timer is at address %016p", acpi->HPET->Header.OEMID, (void *)acpi->HPET->Address.Address); + clk = hpet->GeneralCapabilities >> 32; + mmoutq(&hpet->GeneralConfiguration, 0); + mmoutq(&hpet->MainCounterValue, 0); + mmoutq(&hpet->GeneralConfiguration, 1); + } + else + { + trace("HPET not found"); + } +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif + } + } + + time::~time() + { + } +} diff --git a/Kernel.cpp b/Kernel.cpp index 7d22d20..dd9e3c4 100644 --- a/Kernel.cpp +++ b/Kernel.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -20,9 +19,10 @@ SymbolResolver::Symbols *KernelSymbolTable = nullptr; Power::Power *PowerManager = nullptr; PCI::PCI *PCIManager = nullptr; Tasking::Task *TaskManager = nullptr; +Time::time *TimeManager = nullptr; KernelConfig Config; -Time BootClock; +Time::Clock BootClock; // For the Display class. Printing on first buffer as default. extern "C" void putchar(char c) { Display->Print(c, 0); } @@ -30,7 +30,7 @@ extern "C" void putchar(char c) { Display->Print(c, 0); } EXTERNC void KPrint(const char *Format, ...) { SmartLock(KernelLock); - Time tm = ReadClock(); + Time::Clock tm = Time::ReadClock(); printf_("\eCCCCCC[\e00AEFF%02ld:%02ld:%02ld\eCCCCCC] ", tm.Hour, tm.Minute, tm.Second); va_list args; va_start(args, Format); @@ -44,7 +44,7 @@ EXTERNC void Entry(BootInfo *Info) { trace("Hello, World!"); InitializeMemoryManagement(Info); - BootClock = ReadClock(); + BootClock = Time::ReadClock(); bInfo = (BootInfo *)KernelAllocator.RequestPages(TO_PAGES(sizeof(BootInfo))); memcpy(bInfo, Info, sizeof(BootInfo)); debug("BootInfo structure is at %p", bInfo); @@ -78,6 +78,14 @@ EXTERNC void Entry(BootInfo *Info) } KPrint("Enabling Interrupts on Bootstrap Processor"); Interrupts::Enable(0); + KPrint("Initializing Timers"); +#if defined(__amd64__) + TimeManager = new Time::time(PowerManager->GetACPI()); +#elif defined(__i386__) + TimeManager = new Time::time(PowerManager->GetACPI()); +#elif defined(__aarch64__) + TimeManager = new Time::time(nullptr); +#endif KPrint("Initializing Bootstrap Processor Timer"); Interrupts::InitializeTimer(0); KPrint("Initializing SMP"); diff --git a/include/task.hpp b/include/task.hpp index 557ebca..69c7874 100644 --- a/include/task.hpp +++ b/include/task.hpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include namespace Tasking { @@ -99,6 +101,11 @@ namespace Tasking break; } } + + void SetPriority(int priority) + { + Info.Priority = priority; + } }; struct PCB @@ -113,6 +120,7 @@ namespace Tasking Vector Threads; Vector Children; Memory::PageTable *PageTable; + HashMap *IPCHandles; }; enum TokenTrustLevel diff --git a/include/time.hpp b/include/time.hpp index fc92c9b..19aa907 100644 --- a/include/time.hpp +++ b/include/time.hpp @@ -3,12 +3,41 @@ #include -struct Time +namespace Time { - uint64_t Year, Month, Day, Hour, Minute, Second; - uint64_t Counter; -}; + struct Clock + { + uint64_t Year, Month, Day, Hour, Minute, Second; + uint64_t Counter; + }; -Time ReadClock(); + Clock ReadClock(); + + class time + { + private: + struct HPET + { + uint64_t GeneralCapabilities; + uint64_t Reserved0; + uint64_t GeneralConfiguration; + uint64_t Reserved1; + uint64_t GeneralIntStatus; + uint64_t Reserved2; + uint64_t Reserved3[24]; + uint64_t MainCounterValue; + uint64_t Reserved4; + }; + + void *acpi; + void *hpet; + uint32_t clk = 0; + + public: + void Sleep(uint64_t Milliseconds); + time(void *acpi); + ~time(); + }; +} #endif // !__FENNIX_KERNEL_TIME_H__ diff --git a/include/types.h b/include/types.h index cf692a9..b8be4eb 100644 --- a/include/types.h +++ b/include/types.h @@ -54,6 +54,53 @@ typedef __builtin_va_list va_list; #define VPOKE(type, address) (*((volatile type *)(address))) #define POKE(type, address) (*((type *)(address))) + +#ifndef __cplusplus + +#ifdef __STDC__ +#ifdef __STDC_VERSION__ +#if (__STDC_VERSION__ >= 201710L) +#define C_LANGUAGE_STANDARD 2018 +#elif (__STDC_VERSION__ >= 201112L) +#define C_LANGUAGE_STANDARD 2011 +#elif (__STDC_VERSION__ >= 199901L) +#define C_LANGUAGE_STANDARD 1999 +#elif (__STDC_VERSION__ >= 199409L) +#define C_LANGUAGE_STANDARD 1995 +#endif +#else +#define C_LANGUAGE_STANDARD 1990 +#endif +#else +#define C_LANGUAGE_STANDARD 1972 +#endif + +#else + +#ifdef __STDC__ +#ifdef __cplusplus +#if (__cplusplus >= 202100L) +#define CPP_LANGUAGE_STANDARD 2023 +#elif (__cplusplus >= 202002L) +#define CPP_LANGUAGE_STANDARD 2020 +#elif (__cplusplus >= 201703L) +#define CPP_LANGUAGE_STANDARD 2017 +#elif (__cplusplus >= 201402L) +#define CPP_LANGUAGE_STANDARD 2014 +#elif (__cplusplus >= 201103L) +#define CPP_LANGUAGE_STANDARD 2011 +#elif (__cplusplus >= 199711L) +#define CPP_LANGUAGE_STANDARD 1998 +#endif +#else +#define CPP_LANGUAGE_STANDARD __cplusplus +#endif +#else +#define CPP_LANGUAGE_STANDARD __cplusplus +#endif + +#endif // __cplusplus + typedef __INT8_TYPE__ int8_t; typedef __INT16_TYPE__ int16_t; typedef __INT32_TYPE__ int32_t; diff --git a/kernel.h b/kernel.h index 8a987d4..0ff0902 100644 --- a/kernel.h +++ b/kernel.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #endif @@ -21,6 +22,7 @@ extern Power::Power *PowerManager; extern PCI::PCI *PCIManager; extern KernelConfig Config; extern Tasking::Task *TaskManager; +extern Time::time *TimeManager; #endif EXTERNC void KPrint(const char *format, ...);