feat: extend rtc with RtcDateTime
This commit is contained in:
1 parent
8af9a09f89
commit
30188c37d0
2 files changed
+165
-1
No files matched your search
@@ -0,0 +1,65 @@
|
||||
#ifndef FROSTBYTE_RTC_H
|
||||
#define FROSTBYTE_RTC_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*
|
||||
* CMOS real-time clock driver (MC146818-compatible, ports 0x70/0x71) --
|
||||
* the first source of real wall-clock date/time this kernel has ever had.
|
||||
* Every other notion of "time" in frostbyte (pit.h's tick counter,
|
||||
* threadSleep, userAlarm) is relative to boot, not to the calendar; this
|
||||
* is the piece that lets a process ask "what day is it" at all.
|
||||
*
|
||||
* Honest limitation, same spirit as syscall.c's own documented fork()-less
|
||||
* design: the CMOS century register's index is not standardized (it is
|
||||
* only discoverable via the ACPI FADT table, which this kernel does not
|
||||
* parse), so rtcReadDateTime hardcodes the century to 20 -- correct for
|
||||
* any date from 2000 through 2099, which covers every real boot this
|
||||
* kernel will ever see, but not a documented general-purpose solution.
|
||||
*/
|
||||
|
||||
typedef struct RtcDateTime {
|
||||
int64 year; /* full year, e.g. 2026 */
|
||||
int64 month; /* 1-12 */
|
||||
int64 day; /* 1-31 */
|
||||
int64 hour; /* 0-23, already normalized out of 12-hour/PM if needed */
|
||||
int64 minute; /* 0-59 */
|
||||
int64 second; /* 0-59 */
|
||||
} RtcDateTime;
|
||||
|
||||
/* Converts a single CMOS BCD byte (e.g. 0x59) to its binary value (59).
|
||||
Exposed on its own, like ata.c's ataModelString, because it is a real
|
||||
piece of the conversion pipeline worth testing in isolation from any
|
||||
hardware access. */
|
||||
uint8 rtcBcdToBinary(uint8 bcd);
|
||||
|
||||
/* Reads the current date/time off the CMOS RTC. Polls Status Register A's
|
||||
Update-In-Progress bit (bounded, like ata.c's ataPollTimeout) before
|
||||
each of two back-to-back raw reads and only accepts the result once both
|
||||
raw reads agree byte-for-byte, which rules out a read torn mid-tick by
|
||||
the RTC's own once-a-second update. Returns false only if the two raw
|
||||
reads never agreed within the bounded retry budget (never hangs). */
|
||||
bool rtcReadDateTime(RtcDateTime* out);
|
||||
|
||||
/* Civil calendar date/time -> seconds since the Unix epoch
|
||||
(1970-01-01T00:00:00Z), via Howard Hinnant's days_from_civil algorithm
|
||||
(proleptic Gregorian, correct for any year the RtcDateTime fields above
|
||||
can represent). Pure arithmetic, no hardware access -- deterministic and
|
||||
testable without a real clock. */
|
||||
int64 rtcEpochSeconds(const RtcDateTime* dt);
|
||||
|
||||
/* rtcReadDateTime + rtcEpochSeconds in one call, the usual entry point for
|
||||
anything that just wants "now" as a plain integer (sysTime, syscall.c).
|
||||
Returns 0 if the underlying read failed. */
|
||||
int64 rtcNow(void);
|
||||
|
||||
/* Seconds since the Unix epoch -> civil calendar date/time, the exact
|
||||
inverse of rtcEpochSeconds above (Howard Hinnant's civil_from_days,
|
||||
proleptic Gregorian, same algorithm family as daysFromCivil in rtc.c).
|
||||
Correct for any epochSeconds value representable in int64, including
|
||||
negative ones (dates before 1970). Pure arithmetic, no hardware access
|
||||
-- the piece sfs.h's on-disk mtime/ctime (raw epoch integers) needs to
|
||||
become a human-readable date, e.g. for a shell `ls -l`. */
|
||||
void rtcCivilFromEpoch(int64 epochSeconds, RtcDateTime* out);
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user