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
This commit is contained in:
Bananymous 2023-08-04 11:12:16 +03:00
parent 198e6d7cf6
commit 9363c1cdaf
12 changed files with 77 additions and 54 deletions

View File

@ -41,7 +41,6 @@ set(KERNEL_SOURCES
kernel/PCI.cpp kernel/PCI.cpp
kernel/PIC.cpp kernel/PIC.cpp
kernel/Process.cpp kernel/Process.cpp
kernel/RTC.cpp
kernel/Scheduler.cpp kernel/Scheduler.cpp
kernel/Semaphore.cpp kernel/Semaphore.cpp
kernel/Serial.cpp kernel/Serial.cpp
@ -58,6 +57,7 @@ set(KERNEL_SOURCES
kernel/Terminal/VesaTerminalDriver.cpp kernel/Terminal/VesaTerminalDriver.cpp
kernel/Thread.cpp kernel/Thread.cpp
kernel/Timer/PIT.cpp kernel/Timer/PIT.cpp
kernel/Timer/RTC.cpp
kernel/Timer/Timer.cpp kernel/Timer/Timer.cpp
icxxabi.cpp icxxabi.cpp
) )

View File

@ -1,10 +0,0 @@
#pragma once
#include <BAN/Time.h>
namespace RTC
{
BAN::Time get_current_time();
}

View File

@ -0,0 +1,19 @@
#pragma once
#include <BAN/Time.h>
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);
};
}

View File

@ -2,6 +2,7 @@
#include <BAN/UniqPtr.h> #include <BAN/UniqPtr.h>
#include <BAN/Vector.h> #include <BAN/Vector.h>
#include <kernel/Timer/RTC.h>
namespace Kernel namespace Kernel
{ {
@ -24,12 +25,16 @@ namespace Kernel
uint64_t ms_since_boot() const; uint64_t ms_since_boot() const;
void sleep(uint64_t) const; void sleep(uint64_t) const;
uint64_t get_unix_timestamp();
private: private:
TimerHandler() = default; TimerHandler() = default;
void initialize_timers(); void initialize_timers();
private: private:
uint64_t m_boot_time { 0 };
BAN::UniqPtr<RTC> m_rtc;
BAN::Vector<BAN::UniqPtr<Timer>> m_timers; BAN::Vector<BAN::UniqPtr<Timer>> m_timers;
}; };

View File

@ -1,7 +1,7 @@
#include <BAN/ScopeGuard.h> #include <BAN/ScopeGuard.h>
#include <BAN/StringView.h> #include <BAN/StringView.h>
#include <kernel/FS/Ext2.h> #include <kernel/FS/Ext2.h>
#include <kernel/RTC.h> #include <kernel/Timer/Timer.h>
#define EXT2_DEBUG_PRINT 0 #define EXT2_DEBUG_PRINT 0
#define VERIFY_INODE_EXISTANCE 1 #define VERIFY_INODE_EXISTANCE 1
@ -384,7 +384,7 @@ namespace Kernel
if (error_or.error().get_error_code() != ENOENT) if (error_or.error().get_error_code() != ENOENT)
return error_or.error(); 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 ext2_inode;
ext2_inode.mode = mode; ext2_inode.mode = mode;

View File

@ -1,6 +1,6 @@
#include <kernel/FS/Pipe.h> #include <kernel/FS/Pipe.h>
#include <kernel/LockGuard.h> #include <kernel/LockGuard.h>
#include <kernel/RTC.h> #include <kernel/Timer/Timer.h>
namespace Kernel namespace Kernel
{ {
@ -17,7 +17,7 @@ namespace Kernel
: m_uid(credentials.euid()) : m_uid(credentials.euid())
, m_gid(credentials.egid()) , 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_atime = { .tv_sec = current_time, .tv_nsec = 0 };
m_mtime = { .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 }; 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); memmove(m_buffer.data(), m_buffer.data() + to_copy, m_buffer.size() - to_copy);
MUST(m_buffer.resize(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_atime = { .tv_sec = current_time, .tv_nsec = 0 };
m_semaphore.unblock(); m_semaphore.unblock();
@ -76,7 +76,7 @@ namespace Kernel
TRY(m_buffer.resize(old_size + count)); TRY(m_buffer.resize(old_size + count));
memcpy(m_buffer.data() + old_size, buffer, 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_mtime = { .tv_sec = current_time, .tv_nsec = 0 };
m_ctime = { .tv_sec = current_time, .tv_nsec = 0 }; m_ctime = { .tv_sec = current_time, .tv_nsec = 0 };

View File

@ -2,7 +2,6 @@
#include <kernel/FS/RamFS/FileSystem.h> #include <kernel/FS/RamFS/FileSystem.h>
#include <kernel/FS/RamFS/Inode.h> #include <kernel/FS/RamFS/Inode.h>
#include <kernel/LockGuard.h> #include <kernel/LockGuard.h>
#include <kernel/RTC.h>
namespace Kernel namespace Kernel
{ {

View File

@ -1,6 +1,6 @@
#include <kernel/FS/RamFS/FileSystem.h> #include <kernel/FS/RamFS/FileSystem.h>
#include <kernel/FS/RamFS/Inode.h> #include <kernel/FS/RamFS/Inode.h>
#include <kernel/RTC.h> #include <kernel/Timer/Timer.h>
namespace Kernel namespace Kernel
{ {
@ -23,7 +23,7 @@ namespace Kernel
RamInode::RamInode(RamFileSystem& fs, mode_t mode, uid_t uid, gid_t gid) RamInode::RamInode(RamFileSystem& fs, mode_t mode, uid_t uid, gid_t gid)
: m_fs(fs) : 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; timespec current_timespec;
current_timespec.tv_sec = current_unix_time; current_timespec.tv_sec = current_unix_time;
current_timespec.tv_nsec = 0; current_timespec.tv_nsec = 0;

View File

@ -2,6 +2,7 @@
#include <kernel/CriticalScope.h> #include <kernel/CriticalScope.h>
#include <kernel/FS/DevFS/FileSystem.h> #include <kernel/FS/DevFS/FileSystem.h>
#include <kernel/Input/PS2Keyboard.h> #include <kernel/Input/PS2Keyboard.h>
#include <kernel/Timer/Timer.h>
#include <sys/sysmacros.h> #include <sys/sysmacros.h>

View File

@ -1,5 +1,5 @@
#include <kernel/IO.h> #include <kernel/IO.h>
#include <kernel/RTC.h> #include <kernel/Timer/RTC.h>
#include <string.h> #include <string.h>
@ -18,38 +18,38 @@
#define CMOS_REGISTER_STATUS_1 0x0A #define CMOS_REGISTER_STATUS_1 0x0A
#define CMOS_REGISTER_STATUS_2 0x0B #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); IO::outb(CMOS_ADDRESS, CMOS_REGISTER_STATUS_1);
return IO::inb(CMOS_DATA) & 0x80; 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); IO::outb(CMOS_ADDRESS, reg);
return IO::inb(CMOS_DATA); 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.second = read_register8(CMOS_REGISTER_SECOND);
out.minute = get_rtc_register(CMOS_REGISTER_MINUTE); out.minute = read_register8(CMOS_REGISTER_MINUTE);
out.hour = get_rtc_register(CMOS_REGISTER_HOUR); out.hour = read_register8(CMOS_REGISTER_HOUR);
out.week_day = get_rtc_register(CMOS_REGISTER_WEEK_DAY); out.week_day = read_register8(CMOS_REGISTER_WEEK_DAY);
out.day = get_rtc_register(CMOS_REGISTER_DAY); out.day = read_register8(CMOS_REGISTER_DAY);
out.month = get_rtc_register(CMOS_REGISTER_MONTH); out.month = read_register8(CMOS_REGISTER_MONTH);
out.year = get_rtc_register(CMOS_REGISTER_YEAR); out.year = read_register8(CMOS_REGISTER_YEAR);
} }
BAN::Time get_current_time() BAN::Time RTC::get_current_time()
{ {
BAN::Time last_time = {}; BAN::Time last_time = {};
BAN::Time time = {}; BAN::Time time = {};
while (get_update_in_progress()) while (is_update_in_progress())
continue; continue;
get_time(time); get_time(time);
@ -61,7 +61,7 @@ namespace RTC
get_time(time); get_time(time);
} }
uint8_t regB = get_rtc_register(0x0B); uint8_t regB = read_register8(0x0B);
// Convert BCD to binary values if necessary // Convert BCD to binary values if necessary
if (!(regB & 0x04)) if (!(regB & 0x04))

View File

@ -9,9 +9,10 @@ namespace Kernel
void TimerHandler::initialize() void TimerHandler::initialize()
{ {
ASSERT(s_instance == nullptr); ASSERT(s_instance == nullptr);
s_instance = new TimerHandler; auto* temp = new TimerHandler;
ASSERT(s_instance); ASSERT(temp);
s_instance->initialize_timers(); temp->initialize_timers();
s_instance = temp;
} }
TimerHandler& TimerHandler::get() TimerHandler& TimerHandler::get()
@ -27,6 +28,9 @@ namespace Kernel
void TimerHandler::initialize_timers() void TimerHandler::initialize_timers()
{ {
m_rtc = MUST(BAN::UniqPtr<RTC>::create());
m_boot_time = BAN::to_unix_time(m_rtc->get_current_time());
if (auto res = PIT::create(); res.is_error()) if (auto res = PIT::create(); res.is_error())
dwarnln("PIT: {}", res.error()); dwarnln("PIT: {}", res.error());
else else
@ -48,4 +52,9 @@ namespace Kernel
return m_timers.front()->sleep(ms); return m_timers.front()->sleep(ms);
} }
uint64_t TimerHandler::get_unix_timestamp()
{
return m_boot_time + ms_since_boot() / 1000;
}
} }

View File

@ -138,6 +138,15 @@ extern "C" void kernel_main()
ASSERT(terminal_driver); ASSERT(terminal_driver);
dprintln("VESA initialized"); 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(); DevFileSystem::initialize();
dprintln("devfs initialized"); dprintln("devfs initialized");
@ -148,15 +157,6 @@ extern "C" void kernel_main()
parse_command_line(); parse_command_line();
dprintln("command line parsed, root='{}'", cmdline.root); 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()); MUST(Scheduler::initialize());
dprintln("Scheduler initialized"); dprintln("Scheduler initialized");