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_DEVICE_INFO 38
|
||||||
#define SYS_GET_VOLUME_INFO 39
|
#define SYS_GET_VOLUME_INFO 39
|
||||||
#define SYS_VOLUME_DELETE 40
|
#define SYS_VOLUME_DELETE 40
|
||||||
|
#define SYS_DATE_TIME 41
|
||||||
|
|
||||||
#endif // _M_SYSCALL_DEFS_H
|
#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/intr_defs.h>
|
||||||
#include <amd64/msr-index.h>
|
#include <amd64/msr-index.h>
|
||||||
#include <amd64/msr.h>
|
#include <amd64/msr.h>
|
||||||
|
#include <amd64/rtc.h>
|
||||||
#include <amd64/sse.h>
|
#include <amd64/sse.h>
|
||||||
#include <amd64/systick.h>
|
#include <amd64/systick.h>
|
||||||
#include <aux/compiler.h>
|
#include <aux/compiler.h>
|
||||||
@@ -57,6 +58,7 @@ void bootmain (void) {
|
|||||||
|
|
||||||
ioapic_init ();
|
ioapic_init ();
|
||||||
hpet_init ();
|
hpet_init ();
|
||||||
|
rtc_init ();
|
||||||
|
|
||||||
proc_pid_alloc_init ();
|
proc_pid_alloc_init ();
|
||||||
procgroup_pgid_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/syscall.c \
|
||||||
amd64/gdt.c \
|
amd64/gdt.c \
|
||||||
amd64/stall.c \
|
amd64/stall.c \
|
||||||
amd64/systick.c
|
amd64/systick.c \
|
||||||
|
amd64/rtc.c
|
||||||
|
|
||||||
S += amd64/intr_stub.S \
|
S += amd64/intr_stub.S \
|
||||||
amd64/spin.S \
|
amd64/spin.S \
|
||||||
@@ -43,4 +44,5 @@ o += amd64/bootmain.o \
|
|||||||
amd64/gdt.o \
|
amd64/gdt.o \
|
||||||
amd64/sse.o \
|
amd64/sse.o \
|
||||||
amd64/stall.o \
|
amd64/stall.o \
|
||||||
amd64/systick.o
|
amd64/systick.o \
|
||||||
|
amd64/rtc.o
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#include <amd64/hpet.h>
|
#include <amd64/hpet.h>
|
||||||
|
#include <amd64/rtc.h>
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
/// Sleep for given amount of microseconds
|
/// Sleep for given amount of microseconds
|
||||||
void sleep_micro (size_t us) { hpet_sleep_micro (us); }
|
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
|
#define _KERNEL_SYS_TIME_H
|
||||||
|
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
/* May take a timer peripheral lock! */
|
/* May take a timer peripheral lock! */
|
||||||
void sleep_micro (size_t us);
|
void sleep_micro (size_t us);
|
||||||
|
|
||||||
|
void date_time (struct date_time* date_time);
|
||||||
|
|
||||||
#endif // _KERNEL_SYS_TIME_H
|
#endif // _KERNEL_SYS_TIME_H
|
||||||
|
|||||||
@@ -21,8 +21,10 @@
|
|||||||
#include <sys/debug.h>
|
#include <sys/debug.h>
|
||||||
#include <sys/mm.h>
|
#include <sys/mm.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include <syscall/syscall.h>
|
#include <syscall/syscall.h>
|
||||||
#include <syscall_defs.h>
|
#include <syscall_defs.h>
|
||||||
|
#include <time.h>
|
||||||
#include <volume_info.h>
|
#include <volume_info.h>
|
||||||
#include <write_file.h>
|
#include <write_file.h>
|
||||||
|
|
||||||
@@ -1149,6 +1151,30 @@ DEFINE_SYSCALL (sys_volume_delete) {
|
|||||||
return SYSRESULT (ST_OK);
|
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[] = {
|
static syscall_handler_func_t handler_table[] = {
|
||||||
[SYS_QUIT] = &sys_quit,
|
[SYS_QUIT] = &sys_quit,
|
||||||
[SYS_TEST] = &sys_test,
|
[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_DEVICE_INFO] = &sys_get_device_info,
|
||||||
[SYS_GET_VOLUME_INFO] = &sys_get_volume_info,
|
[SYS_GET_VOLUME_INFO] = &sys_get_volume_info,
|
||||||
[SYS_VOLUME_DELETE] = &sys_volume_delete,
|
[SYS_VOLUME_DELETE] = &sys_volume_delete,
|
||||||
|
[SYS_DATE_TIME] = &sys_date_time,
|
||||||
};
|
};
|
||||||
|
|
||||||
syscall_handler_func_t syscall_find_handler (int syscall_num) {
|
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' \
|
FORMAT = clang-format -i $$(git ls-files '*.c' '*.h' ':!malloc.c' ':!malloc.h' \
|
||||||
':!\_fat.c' ':!\_fat.h' ':!\_fatctx.h')
|
':!\_fat.c' ':!\_fat.h' ':!\_fatctx.h')
|
||||||
|
|
||||||
DOCS_COLLECT = $$(git ls-files '*.c' '*.h' ':!\_fat.c' ':!\_fat.h' ':!\_fatctx.h' \
|
DOCS_COLLECT = $$(git ls-files '*.c' '*.h' ':!\_fat.c' ':!\_fat.h' ':!\_fatctx.h')
|
||||||
':!malloc.c' ':!malloc.h')
|
|
||||||
|
|
||||||
cflags += -DPRINTF_INCLUDE_CONFIG_H=1 -D"FAT_PRINTF(a)"
|
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 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 <proc_info.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <time.h>
|
||||||
#include <volume_info.h>
|
#include <volume_info.h>
|
||||||
|
|
||||||
/* Quit the current running process */
|
/* Quit the current running process */
|
||||||
@@ -129,4 +130,7 @@ int get_volume_info (struct volume_info* infos, size_t count);
|
|||||||
/* delete a volume */
|
/* delete a volume */
|
||||||
int volume_delete (const char* key);
|
int volume_delete (const char* key);
|
||||||
|
|
||||||
|
/* Get date-time */
|
||||||
|
int date_time (struct date_time* dt);
|
||||||
|
|
||||||
#endif // _LIBMSL_M_SYSTEM_H
|
#endif // _LIBMSL_M_SYSTEM_H
|
||||||
|
|||||||
Reference in New Issue
Block a user