From 7eb2c140fe24b7e07318abcd0751a4f3d52196bf Mon Sep 17 00:00:00 2001 From: Bananymous Date: Fri, 4 Aug 2023 11:12:16 +0300 Subject: [PATCH] Kernel: Move RTC to Timer directory PIT ms counter seems to be off by multiple seconds/minute. I will be probably changing to HPET for system time --- kernel/CMakeLists.txt | 2 +- kernel/include/kernel/RTC.h | 10 ------ kernel/include/kernel/Timer/RTC.h | 19 ++++++++++++ kernel/include/kernel/Timer/Timer.h | 5 +++ kernel/kernel/FS/Ext2.cpp | 4 +-- kernel/kernel/FS/Pipe.cpp | 8 ++--- kernel/kernel/FS/RamFS/FileSystem.cpp | 1 - kernel/kernel/FS/RamFS/Inode.cpp | 4 +-- kernel/kernel/Input/PS2Keyboard.cpp | 1 + kernel/kernel/{ => Timer}/RTC.cpp | 44 +++++++++++++-------------- kernel/kernel/Timer/Timer.cpp | 15 +++++++-- kernel/kernel/kernel.cpp | 18 +++++------ 12 files changed, 77 insertions(+), 54 deletions(-) delete mode 100644 kernel/include/kernel/RTC.h create mode 100644 kernel/include/kernel/Timer/RTC.h rename kernel/kernel/{ => Timer}/RTC.cpp (50%) diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 9f0899ca..e3990b57 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -41,7 +41,6 @@ set(KERNEL_SOURCES kernel/PCI.cpp kernel/PIC.cpp kernel/Process.cpp - kernel/RTC.cpp kernel/Scheduler.cpp kernel/Semaphore.cpp kernel/Serial.cpp @@ -58,6 +57,7 @@ set(KERNEL_SOURCES kernel/Terminal/VesaTerminalDriver.cpp kernel/Thread.cpp kernel/Timer/PIT.cpp + kernel/Timer/RTC.cpp kernel/Timer/Timer.cpp icxxabi.cpp ) diff --git a/kernel/include/kernel/RTC.h b/kernel/include/kernel/RTC.h deleted file mode 100644 index af5f6b11..00000000 --- a/kernel/include/kernel/RTC.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include - -namespace RTC -{ - - BAN::Time get_current_time(); - -} \ No newline at end of file diff --git a/kernel/include/kernel/Timer/RTC.h b/kernel/include/kernel/Timer/RTC.h new file mode 100644 index 00000000..5b343163 --- /dev/null +++ b/kernel/include/kernel/Timer/RTC.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +namespace Kernel +{ + + class RTC + { + public: + BAN::Time get_current_time(); + + private: + bool is_update_in_progress(); + uint8_t read_register8(uint8_t reg); + void get_time(BAN::Time& out); + }; + +} diff --git a/kernel/include/kernel/Timer/Timer.h b/kernel/include/kernel/Timer/Timer.h index e72450f5..8117102e 100644 --- a/kernel/include/kernel/Timer/Timer.h +++ b/kernel/include/kernel/Timer/Timer.h @@ -2,6 +2,7 @@ #include #include +#include namespace Kernel { @@ -24,12 +25,16 @@ namespace Kernel uint64_t ms_since_boot() const; void sleep(uint64_t) const; + uint64_t get_unix_timestamp(); + private: TimerHandler() = default; void initialize_timers(); private: + uint64_t m_boot_time { 0 }; + BAN::UniqPtr m_rtc; BAN::Vector> m_timers; }; diff --git a/kernel/kernel/FS/Ext2.cpp b/kernel/kernel/FS/Ext2.cpp index d9050c3b..08f3114e 100644 --- a/kernel/kernel/FS/Ext2.cpp +++ b/kernel/kernel/FS/Ext2.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #define EXT2_DEBUG_PRINT 0 #define VERIFY_INODE_EXISTANCE 1 @@ -384,7 +384,7 @@ namespace Kernel if (error_or.error().get_error_code() != ENOENT) return error_or.error(); - uint64_t current_time = BAN::to_unix_time(RTC::get_current_time()); + uint64_t current_time = TimerHandler::get().get_unix_timestamp(); Ext2::Inode ext2_inode; ext2_inode.mode = mode; diff --git a/kernel/kernel/FS/Pipe.cpp b/kernel/kernel/FS/Pipe.cpp index c0159d01..8f01beaf 100644 --- a/kernel/kernel/FS/Pipe.cpp +++ b/kernel/kernel/FS/Pipe.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include namespace Kernel { @@ -17,7 +17,7 @@ namespace Kernel : m_uid(credentials.euid()) , m_gid(credentials.egid()) { - uint64_t current_time = BAN::to_unix_time(RTC::get_current_time()); + uint64_t current_time = TimerHandler::get().get_unix_timestamp(); m_atime = { .tv_sec = current_time, .tv_nsec = 0 }; m_mtime = { .tv_sec = current_time, .tv_nsec = 0 }; m_ctime = { .tv_sec = current_time, .tv_nsec = 0 }; @@ -57,7 +57,7 @@ namespace Kernel memmove(m_buffer.data(), m_buffer.data() + to_copy, m_buffer.size() - to_copy); MUST(m_buffer.resize(m_buffer.size() - to_copy)); - uint64_t current_time = BAN::to_unix_time(RTC::get_current_time()); + uint64_t current_time = TimerHandler::get().get_unix_timestamp(); m_atime = { .tv_sec = current_time, .tv_nsec = 0 }; m_semaphore.unblock(); @@ -76,7 +76,7 @@ namespace Kernel TRY(m_buffer.resize(old_size + count)); memcpy(m_buffer.data() + old_size, buffer, count); - uint64_t current_time = BAN::to_unix_time(RTC::get_current_time()); + uint64_t current_time = TimerHandler::get().get_unix_timestamp(); m_mtime = { .tv_sec = current_time, .tv_nsec = 0 }; m_ctime = { .tv_sec = current_time, .tv_nsec = 0 }; diff --git a/kernel/kernel/FS/RamFS/FileSystem.cpp b/kernel/kernel/FS/RamFS/FileSystem.cpp index c6fa9ed5..0fe660ba 100644 --- a/kernel/kernel/FS/RamFS/FileSystem.cpp +++ b/kernel/kernel/FS/RamFS/FileSystem.cpp @@ -2,7 +2,6 @@ #include #include #include -#include namespace Kernel { diff --git a/kernel/kernel/FS/RamFS/Inode.cpp b/kernel/kernel/FS/RamFS/Inode.cpp index 5471d321..81716ba4 100644 --- a/kernel/kernel/FS/RamFS/Inode.cpp +++ b/kernel/kernel/FS/RamFS/Inode.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include namespace Kernel { @@ -23,7 +23,7 @@ namespace Kernel RamInode::RamInode(RamFileSystem& fs, mode_t mode, uid_t uid, gid_t gid) : m_fs(fs) { - uint64_t current_unix_time = BAN::to_unix_time(RTC::get_current_time()); + uint64_t current_unix_time = TimerHandler::get().get_unix_timestamp(); timespec current_timespec; current_timespec.tv_sec = current_unix_time; current_timespec.tv_nsec = 0; diff --git a/kernel/kernel/Input/PS2Keyboard.cpp b/kernel/kernel/Input/PS2Keyboard.cpp index 37e2c7ee..10885c86 100644 --- a/kernel/kernel/Input/PS2Keyboard.cpp +++ b/kernel/kernel/Input/PS2Keyboard.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include diff --git a/kernel/kernel/RTC.cpp b/kernel/kernel/Timer/RTC.cpp similarity index 50% rename from kernel/kernel/RTC.cpp rename to kernel/kernel/Timer/RTC.cpp index 5da86c98..d0d7a80e 100644 --- a/kernel/kernel/RTC.cpp +++ b/kernel/kernel/Timer/RTC.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include @@ -18,38 +18,38 @@ #define CMOS_REGISTER_STATUS_1 0x0A #define CMOS_REGISTER_STATUS_2 0x0B -namespace RTC +namespace Kernel { - static bool get_update_in_progress() + bool RTC::is_update_in_progress() { IO::outb(CMOS_ADDRESS, CMOS_REGISTER_STATUS_1); return IO::inb(CMOS_DATA) & 0x80; } - static uint8_t get_rtc_register(uint8_t reg) + uint8_t RTC::read_register8(uint8_t reg) { IO::outb(CMOS_ADDRESS, reg); return IO::inb(CMOS_DATA); } - static void get_time(BAN::Time& out) + void RTC::get_time(BAN::Time& out) { - out.second = get_rtc_register(CMOS_REGISTER_SECOND); - out.minute = get_rtc_register(CMOS_REGISTER_MINUTE); - out.hour = get_rtc_register(CMOS_REGISTER_HOUR); - out.week_day = get_rtc_register(CMOS_REGISTER_WEEK_DAY); - out.day = get_rtc_register(CMOS_REGISTER_DAY); - out.month = get_rtc_register(CMOS_REGISTER_MONTH); - out.year = get_rtc_register(CMOS_REGISTER_YEAR); + out.second = read_register8(CMOS_REGISTER_SECOND); + out.minute = read_register8(CMOS_REGISTER_MINUTE); + out.hour = read_register8(CMOS_REGISTER_HOUR); + out.week_day = read_register8(CMOS_REGISTER_WEEK_DAY); + out.day = read_register8(CMOS_REGISTER_DAY); + out.month = read_register8(CMOS_REGISTER_MONTH); + out.year = read_register8(CMOS_REGISTER_YEAR); } - BAN::Time get_current_time() + BAN::Time RTC::get_current_time() { BAN::Time last_time = {}; BAN::Time time = {}; - while (get_update_in_progress()) + while (is_update_in_progress()) continue; get_time(time); @@ -61,18 +61,18 @@ namespace RTC get_time(time); } - uint8_t regB = get_rtc_register(0x0B); + uint8_t regB = read_register8(0x0B); // Convert BCD to binary values if necessary if (!(regB & 0x04)) { - time.second = (time.second & 0x0F) + ((time.second / 16) * 10); - time.minute = (time.minute & 0x0F) + ((time.minute / 16) * 10); - time.hour = ((time.hour & 0x0F) + (((time.hour & 0x70) / 16) * 10) ) | (time.hour & 0x80); - time.week_day = (time.week_day & 0x0F) + ((time.week_day / 16) * 10); - time.day = (time.day & 0x0F) + ((time.day / 16) * 10); - time.month = (time.month & 0x0F) + ((time.month / 16) * 10); - time.year = (time.year & 0x0F) + ((time.year / 16) * 10); + time.second = (time.second & 0x0F) + ((time.second / 16) * 10); + time.minute = (time.minute & 0x0F) + ((time.minute / 16) * 10); + time.hour = ((time.hour & 0x0F) + (((time.hour & 0x70) / 16) * 10) ) | (time.hour & 0x80); + time.week_day = (time.week_day & 0x0F) + ((time.week_day / 16) * 10); + time.day = (time.day & 0x0F) + ((time.day / 16) * 10); + time.month = (time.month & 0x0F) + ((time.month / 16) * 10); + time.year = (time.year & 0x0F) + ((time.year / 16) * 10); } // Convert 12 hour clock to 24 hour clock if necessary diff --git a/kernel/kernel/Timer/Timer.cpp b/kernel/kernel/Timer/Timer.cpp index b5448e27..c0a9cdc9 100644 --- a/kernel/kernel/Timer/Timer.cpp +++ b/kernel/kernel/Timer/Timer.cpp @@ -9,9 +9,10 @@ namespace Kernel void TimerHandler::initialize() { ASSERT(s_instance == nullptr); - s_instance = new TimerHandler; - ASSERT(s_instance); - s_instance->initialize_timers(); + auto* temp = new TimerHandler; + ASSERT(temp); + temp->initialize_timers(); + s_instance = temp; } TimerHandler& TimerHandler::get() @@ -27,6 +28,9 @@ namespace Kernel void TimerHandler::initialize_timers() { + m_rtc = MUST(BAN::UniqPtr::create()); + m_boot_time = BAN::to_unix_time(m_rtc->get_current_time()); + if (auto res = PIT::create(); res.is_error()) dwarnln("PIT: {}", res.error()); else @@ -48,4 +52,9 @@ namespace Kernel return m_timers.front()->sleep(ms); } + uint64_t TimerHandler::get_unix_timestamp() + { + return m_boot_time + ms_since_boot() / 1000; + } + } \ No newline at end of file diff --git a/kernel/kernel/kernel.cpp b/kernel/kernel/kernel.cpp index ed67feb5..020fe3e4 100644 --- a/kernel/kernel/kernel.cpp +++ b/kernel/kernel/kernel.cpp @@ -138,6 +138,15 @@ extern "C" void kernel_main() ASSERT(terminal_driver); dprintln("VESA initialized"); + MUST(ACPI::initialize()); + dprintln("ACPI initialized"); + + InterruptController::initialize(cmdline.force_pic); + dprintln("Interrupt controller initialized"); + + TimerHandler::initialize(); + dprintln("Timers initialized"); + DevFileSystem::initialize(); dprintln("devfs initialized"); @@ -148,15 +157,6 @@ extern "C" void kernel_main() parse_command_line(); dprintln("command line parsed, root='{}'", cmdline.root); - MUST(ACPI::initialize()); - dprintln("ACPI initialized"); - - InterruptController::initialize(cmdline.force_pic); - dprintln("Interrupt controller initialized"); - - TimerHandler::initialize(); - dprintln("Timers initialized"); - MUST(Scheduler::initialize()); dprintln("Scheduler initialized");