date_time () syscall, Get date-time from RTC
This commit is contained in:
@@ -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
14
include/time.h
Normal 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
|
||||
@@ -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
112
kernel/amd64/rtc.c
Normal 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
10
kernel/amd64/rtc.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)"
|
||||
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user