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 659adb89a6
commit 7eb2c140fe
12 changed files with 77 additions and 54 deletions

View File

@ -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
)

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/Vector.h>
#include <kernel/Timer/RTC.h>
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<RTC> m_rtc;
BAN::Vector<BAN::UniqPtr<Timer>> m_timers;
};

View File

@ -1,7 +1,7 @@
#include <BAN/ScopeGuard.h>
#include <BAN/StringView.h>
#include <kernel/FS/Ext2.h>
#include <kernel/RTC.h>
#include <kernel/Timer/Timer.h>
#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;

View File

@ -1,6 +1,6 @@
#include <kernel/FS/Pipe.h>
#include <kernel/LockGuard.h>
#include <kernel/RTC.h>
#include <kernel/Timer/Timer.h>
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 };

View File

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

View File

@ -1,6 +1,6 @@
#include <kernel/FS/RamFS/FileSystem.h>
#include <kernel/FS/RamFS/Inode.h>
#include <kernel/RTC.h>
#include <kernel/Timer/Timer.h>
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;

View File

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

View File

@ -1,5 +1,5 @@
#include <kernel/IO.h>
#include <kernel/RTC.h>
#include <kernel/Timer/RTC.h>
#include <string.h>
@ -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

View File

@ -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<RTC>::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;
}
}

View File

@ -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");