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:
parent
198e6d7cf6
commit
9363c1cdaf
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <BAN/Time.h>
|
|
||||||
|
|
||||||
namespace RTC
|
|
||||||
{
|
|
||||||
|
|
||||||
BAN::Time get_current_time();
|
|
||||||
|
|
||||||
}
|
|
|
@ -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);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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,18 +61,18 @@ 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))
|
||||||
{
|
{
|
||||||
time.second = (time.second & 0x0F) + ((time.second / 16) * 10);
|
time.second = (time.second & 0x0F) + ((time.second / 16) * 10);
|
||||||
time.minute = (time.minute & 0x0F) + ((time.minute / 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.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.week_day = (time.week_day & 0x0F) + ((time.week_day / 16) * 10);
|
||||||
time.day = (time.day & 0x0F) + ((time.day / 16) * 10);
|
time.day = (time.day & 0x0F) + ((time.day / 16) * 10);
|
||||||
time.month = (time.month & 0x0F) + ((time.month / 16) * 10);
|
time.month = (time.month & 0x0F) + ((time.month / 16) * 10);
|
||||||
time.year = (time.year & 0x0F) + ((time.year / 16) * 10);
|
time.year = (time.year & 0x0F) + ((time.year / 16) * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert 12 hour clock to 24 hour clock if necessary
|
// Convert 12 hour clock to 24 hour clock if necessary
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -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");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue