date_time () syscall, Get date-time from RTC
All checks were successful
Build ISO image / build-and-deploy (push) Successful in 32s
Build documentation / build-and-deploy (push) Successful in 41s

This commit is contained in:
2026-04-12 21:13:20 +02:00
parent 6c01de8b0d
commit 245196b80f
12 changed files with 183 additions and 4 deletions

View File

@@ -41,5 +41,6 @@
#define SYS_GET_DEVICE_INFO 38
#define SYS_GET_VOLUME_INFO 39
#define SYS_VOLUME_DELETE 40
#define SYS_DATE_TIME 41
#endif // _M_SYSCALL_DEFS_H

14
include/time.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef _TIME_H
#define _TIME_H
struct date_time {
int sec;
int min;
int hour;
int day;
int weekday;
int month;
int year;
};
#endif // _TIME_H

View File

@@ -6,6 +6,7 @@
#include <amd64/intr_defs.h>
#include <amd64/msr-index.h>
#include <amd64/msr.h>
#include <amd64/rtc.h>
#include <amd64/sse.h>
#include <amd64/systick.h>
#include <aux/compiler.h>
@@ -57,6 +58,7 @@ void bootmain (void) {
ioapic_init ();
hpet_init ();
rtc_init ();
proc_pid_alloc_init ();
procgroup_pgid_alloc_init ();

112
kernel/amd64/rtc.c Normal file
View File

@@ -0,0 +1,112 @@
#include <amd64/io.h>
#include <amd64/rtc.h>
#include <libk/std.h>
#include <limine/requests.h>
#include <sys/debug.h>
#include <sys/spin.h>
#include <sys/stall.h>
#include <time.h>
#include <uacpi/acpi.h>
#include <uacpi/status.h>
#include <uacpi/tables.h>
#include <uacpi/uacpi.h>
#define RTC_CMOS_ADDR 0x70
#define RTC_CMOS_DATA 0x71
static uint8_t rtc_century;
#define RTC_SEC 0x00
#define RTC_SEC_ALARM 0x01
#define RTC_MIN 0x02
#define RTC_MIN_ALARM 0x03
#define RTC_HOUR 0x04
#define RTC_HOUR_ALARM 0x05
#define RTC_WEEK_DAY 0x06
#define RTC_DAY 0x07
#define RTC_MONTH 0x08
#define RTC_YEAR 0x09
#define RTC_REG_A 0x0A
#define RTC_REG_B 0x0B
#define RTC_REG_C 0x0C
#define RTC_REG_D 0x0D
#define RTC_REG_A_UIP (1 << 7)
#define RTC_REG_B_HOURFMT (1 << 1)
#define RTC_REG_B_DATAMODE (1 << 2)
static uint8_t rtc_read (uint8_t addr) {
outb (RTC_CMOS_ADDR, RTC_REG_A);
while (inb (RTC_CMOS_DATA) & RTC_REG_A_UIP)
;
outb (RTC_CMOS_ADDR, addr);
return inb (RTC_CMOS_DATA);
}
static void rtc_write (uint8_t addr, uint8_t value) {
outb (RTC_CMOS_ADDR, addr);
outb (RTC_CMOS_DATA, value);
}
static uint8_t rtc_bcd_to_bin (uint8_t value) { return (value & 0xF) + (value >> 4) * 10; }
static uint8_t rtc_bin_to_bcd (uint8_t value) { return ((value / 10) << 4) + (value % 10); }
void rtc_init (void) {
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
struct uacpi_table fadt_table;
uacpi_status status = uacpi_table_find_by_signature (ACPI_FADT_SIGNATURE, &fadt_table);
if (status != UACPI_STATUS_OK) {
DEBUG ("Could not find FADT table!\n");
spin ();
}
struct acpi_fadt* fadt = (struct acpi_fadt*)fadt_table.virt_addr;
rtc_century = fadt->century;
}
void rtc_date_time (struct date_time* date_time) {
if (rtc_read (RTC_REG_A) & RTC_REG_A_UIP)
stall_ms (1);
uint8_t sec = rtc_read (RTC_SEC);
uint8_t min = rtc_read (RTC_MIN);
uint8_t hour = rtc_read (RTC_HOUR);
uint8_t weekday = rtc_read (RTC_WEEK_DAY);
uint8_t day = rtc_read (RTC_DAY);
uint8_t month = rtc_read (RTC_MONTH);
uint8_t year = rtc_read (RTC_YEAR);
uint8_t century = rtc_century != 0 ? rtc_read (rtc_century) : 0;
uint8_t b = rtc_read (RTC_REG_B);
/* BCD */
if ((~b) & RTC_REG_B_DATAMODE) {
sec = rtc_bcd_to_bin (sec);
min = rtc_bcd_to_bin (min);
hour = rtc_bcd_to_bin (hour);
day = rtc_bcd_to_bin (day);
month = rtc_bcd_to_bin (month);
year = rtc_bcd_to_bin (year);
if (rtc_century != 0)
century = rtc_bcd_to_bin (century);
}
weekday--;
int full_year;
if (rtc_century != 0)
full_year = (century * 100) + year;
else
full_year = (year < 80) ? (2000 + year) : (1900 + year);
date_time->sec = sec;
date_time->min = min;
date_time->hour = hour;
date_time->day = day;
date_time->weekday = weekday;
date_time->month = month;
date_time->year = full_year;
}

10
kernel/amd64/rtc.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef _KERNEL_AMD64_RTC_H
#define _KERNEL_AMD64_RTC_H
#include <time.h>
void rtc_init (void);
void rtc_date_time (struct date_time* date_time);
#endif // _KERNEL_AMD64_RTC_H

View File

@@ -14,7 +14,8 @@ c += amd64/bootmain.c \
amd64/syscall.c \
amd64/gdt.c \
amd64/stall.c \
amd64/systick.c
amd64/systick.c \
amd64/rtc.c
S += amd64/intr_stub.S \
amd64/spin.S \
@@ -43,4 +44,5 @@ o += amd64/bootmain.o \
amd64/gdt.o \
amd64/sse.o \
amd64/stall.o \
amd64/systick.o
amd64/systick.o \
amd64/rtc.o

View File

@@ -1,6 +1,9 @@
#include <amd64/hpet.h>
#include <amd64/rtc.h>
#include <libk/std.h>
#include <sys/time.h>
/// Sleep for given amount of microseconds
void sleep_micro (size_t us) { hpet_sleep_micro (us); }
void date_time (struct date_time* date_time) { rtc_date_time (date_time); }

View File

@@ -2,8 +2,11 @@
#define _KERNEL_SYS_TIME_H
#include <libk/std.h>
#include <time.h>
/* May take a timer peripheral lock! */
void sleep_micro (size_t us);
void date_time (struct date_time* date_time);
#endif // _KERNEL_SYS_TIME_H

View File

@@ -21,8 +21,10 @@
#include <sys/debug.h>
#include <sys/mm.h>
#include <sys/proc.h>
#include <sys/time.h>
#include <syscall/syscall.h>
#include <syscall_defs.h>
#include <time.h>
#include <volume_info.h>
#include <write_file.h>
@@ -1149,6 +1151,30 @@ DEFINE_SYSCALL (sys_volume_delete) {
return SYSRESULT (ST_OK);
}
/* int date_time (struct date_time* dt) */
DEFINE_SYSCALL (sys_date_time) {
uint64_t fpg, fp;
uintptr_t uvaddr_dt = a1;
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
uintptr_t out_paddr;
spin_lock (&proc->lock, &fp);
struct procgroup* procgroup = proc->procgroup;
spin_unlock (&proc->lock, fp);
struct date_time* dt = sys_get_user_buffer (procgroup, uvaddr_dt, sizeof (struct date_time));
if (dt == NULL)
return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
date_time (dt);
return ST_OK;
}
static syscall_handler_func_t handler_table[] = {
[SYS_QUIT] = &sys_quit,
[SYS_TEST] = &sys_test,
@@ -1190,6 +1216,7 @@ static syscall_handler_func_t handler_table[] = {
[SYS_GET_DEVICE_INFO] = &sys_get_device_info,
[SYS_GET_VOLUME_INFO] = &sys_get_volume_info,
[SYS_VOLUME_DELETE] = &sys_volume_delete,
[SYS_DATE_TIME] = &sys_date_time,
};
syscall_handler_func_t syscall_find_handler (int syscall_num) {

View File

@@ -1,8 +1,7 @@
FORMAT = clang-format -i $$(git ls-files '*.c' '*.h' ':!malloc.c' ':!malloc.h' \
':!\_fat.c' ':!\_fat.h' ':!\_fatctx.h')
DOCS_COLLECT = $$(git ls-files '*.c' '*.h' ':!\_fat.c' ':!\_fat.h' ':!\_fatctx.h' \
':!malloc.c' ':!malloc.h')
DOCS_COLLECT = $$(git ls-files '*.c' '*.h' ':!\_fat.c' ':!\_fat.h' ':!\_fatctx.h')
cflags += -DPRINTF_INCLUDE_CONFIG_H=1 -D"FAT_PRINTF(a)"

View File

@@ -124,3 +124,5 @@ int get_volume_info (struct volume_info* infos, size_t count) {
}
int volume_delete (const char* key) { return (int)do_syscall (SYS_VOLUME_DELETE, key); }
int date_time (struct date_time* dt) { return (int)do_syscall (SYS_DATE_TIME, dt); }

View File

@@ -7,6 +7,7 @@
#include <proc_info.h>
#include <stddef.h>
#include <stdint.h>
#include <time.h>
#include <volume_info.h>
/* Quit the current running process */
@@ -129,4 +130,7 @@ int get_volume_info (struct volume_info* infos, size_t count);
/* delete a volume */
int volume_delete (const char* key);
/* Get date-time */
int date_time (struct date_time* dt);
#endif // _LIBMSL_M_SYSTEM_H