feat: add time syscall & command in shell
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "Syscall.hpp"
|
||||
#include <Timekeeping/Time.hpp>
|
||||
#include <Terminal/Terminal.hpp>
|
||||
#include <Fs/Vfs.hpp>
|
||||
#include <Memory/Heap.hpp>
|
||||
@@ -256,7 +257,18 @@ namespace Zenith {
|
||||
return (rows << 32) | (cols & 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
static void Sys_Reset() {
|
||||
static void Sys_GetTime(DateTime* out) {
|
||||
if (out == nullptr) return;
|
||||
Timekeeping::DateTime dt = Timekeeping::GetDateTime();
|
||||
out->Year = dt.Year;
|
||||
out->Month = dt.Month;
|
||||
out->Day = dt.Day;
|
||||
out->Hour = dt.Hour;
|
||||
out->Minute = dt.Minute;
|
||||
out->Second = dt.Second;
|
||||
}
|
||||
|
||||
static void Sys_Reset() {
|
||||
/*
|
||||
Triple fault for now; TODO: implement UEFI runtime function for clean reboot.
|
||||
|
||||
@@ -349,6 +361,9 @@ namespace Zenith {
|
||||
case SYS_SHUTDOWN:
|
||||
/* Unimplemented */
|
||||
return -1;
|
||||
case SYS_GETTIME:
|
||||
Sys_GetTime((DateTime*)frame->arg1);
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@@ -375,7 +390,7 @@ namespace Zenith {
|
||||
Hal::WriteMSR(Hal::IA32_FMASK, 0x200);
|
||||
|
||||
Kt::KernelLogStream(Kt::OK, "Syscall") << "SYSCALL/SYSRET initialized (LSTAR="
|
||||
<< kcp::hex << (uint64_t)SyscallEntry << kcp::dec << ", 26 syscalls)";
|
||||
<< kcp::hex << (uint64_t)SyscallEntry << kcp::dec << ", 29 syscalls)";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,6 +39,16 @@ namespace Zenith {
|
||||
static constexpr uint64_t SYS_GETARGS = 25;
|
||||
static constexpr uint64_t SYS_RESET = 26;
|
||||
static constexpr uint64_t SYS_SHUTDOWN = 27;
|
||||
static constexpr uint64_t SYS_GETTIME = 28;
|
||||
|
||||
struct DateTime {
|
||||
uint16_t Year;
|
||||
uint8_t Month;
|
||||
uint8_t Day;
|
||||
uint8_t Hour;
|
||||
uint8_t Minute;
|
||||
uint8_t Second;
|
||||
};
|
||||
|
||||
struct FbInfo {
|
||||
uint64_t width;
|
||||
|
||||
@@ -4,12 +4,70 @@
|
||||
*/
|
||||
|
||||
#include "Time.hpp"
|
||||
#include "ApicTimer.hpp"
|
||||
#include <Terminal/Terminal.hpp>
|
||||
#include <CppLib/Stream.hpp>
|
||||
|
||||
using namespace Kt;
|
||||
|
||||
static int64_t g_bootEpoch = 0;
|
||||
|
||||
static bool IsLeapYear(int year) {
|
||||
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
|
||||
}
|
||||
|
||||
static int DaysInMonth(int month, int year) {
|
||||
static const int days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
if (month == 2 && IsLeapYear(year)) return 29;
|
||||
return days[month];
|
||||
}
|
||||
|
||||
static int64_t DateToEpoch(int year, int month, int day, int hour, int minute, int second) {
|
||||
int64_t days = 0;
|
||||
for (int y = 1970; y < year; y++) {
|
||||
days += IsLeapYear(y) ? 366 : 365;
|
||||
}
|
||||
for (int m = 1; m < month; m++) {
|
||||
days += DaysInMonth(m, year);
|
||||
}
|
||||
days += day - 1;
|
||||
return days * 86400 + hour * 3600 + minute * 60 + second;
|
||||
}
|
||||
|
||||
static Timekeeping::DateTime EpochToDate(int64_t epoch) {
|
||||
Timekeeping::DateTime dt = {};
|
||||
int64_t rem = epoch;
|
||||
int year = 1970;
|
||||
while (true) {
|
||||
int64_t daysInYear = IsLeapYear(year) ? 366 : 365;
|
||||
if (rem < daysInYear * 86400) break;
|
||||
rem -= daysInYear * 86400;
|
||||
year++;
|
||||
}
|
||||
dt.Year = (uint16_t)year;
|
||||
|
||||
int dayOfYear = (int)(rem / 86400);
|
||||
rem -= (int64_t)dayOfYear * 86400;
|
||||
|
||||
int month = 1;
|
||||
while (month <= 12) {
|
||||
int dim = DaysInMonth(month, year);
|
||||
if (dayOfYear < dim) break;
|
||||
dayOfYear -= dim;
|
||||
month++;
|
||||
}
|
||||
dt.Month = (uint8_t)month;
|
||||
dt.Day = (uint8_t)(dayOfYear + 1);
|
||||
|
||||
dt.Hour = (uint8_t)(rem / 3600);
|
||||
rem %= 3600;
|
||||
dt.Minute = (uint8_t)(rem / 60);
|
||||
dt.Second = (uint8_t)(rem % 60);
|
||||
return dt;
|
||||
}
|
||||
|
||||
void Timekeeping::Init(uint16_t Year, uint8_t Month, uint8_t Day, uint8_t Hour, uint8_t Minute, uint8_t Second) {
|
||||
g_bootEpoch = DateToEpoch(Year, Month, Day, Hour, Minute, Second);
|
||||
/* Hardcode CET for now */
|
||||
TimeZone CET = {
|
||||
"Central European Time",
|
||||
@@ -63,4 +121,12 @@ void Timekeeping::Init(uint16_t Year, uint8_t Month, uint8_t Day, uint8_t Hour,
|
||||
CString dateString = panelStr.c_str();
|
||||
|
||||
UpdatePanelBar(dateString);
|
||||
}
|
||||
|
||||
int64_t Timekeeping::GetUnixTimestamp() {
|
||||
return g_bootEpoch + (int64_t)(Timekeeping::GetMilliseconds() / 1000);
|
||||
}
|
||||
|
||||
Timekeeping::DateTime Timekeeping::GetDateTime() {
|
||||
return EpochToDate(GetUnixTimestamp());
|
||||
}
|
||||
@@ -41,5 +41,16 @@ namespace Timekeeping {
|
||||
"December"
|
||||
};
|
||||
|
||||
struct DateTime {
|
||||
uint16_t Year;
|
||||
uint8_t Month;
|
||||
uint8_t Day;
|
||||
uint8_t Hour;
|
||||
uint8_t Minute;
|
||||
uint8_t Second;
|
||||
};
|
||||
|
||||
void Init(uint16_t Year, uint8_t Month, uint8_t Day, uint8_t Hour, uint8_t Minute, uint8_t Second);
|
||||
int64_t GetUnixTimestamp();
|
||||
DateTime GetDateTime();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user