dead simple rtc code for getting current datetime.
authorMinep <zelong56@gmail.com>
Sun, 6 Mar 2022 18:17:32 +0000 (18:17 +0000)
committerMinep <zelong56@gmail.com>
Sun, 6 Mar 2022 18:17:32 +0000 (18:17 +0000)
lunaix-os/hal/rtc.c [new file with mode: 0644]
lunaix-os/includes/hal/io.h
lunaix-os/includes/hal/rtc.h [new file with mode: 0644]
lunaix-os/kernel/k_main.c

diff --git a/lunaix-os/hal/rtc.c b/lunaix-os/hal/rtc.c
new file mode 100644 (file)
index 0000000..319ad65
--- /dev/null
@@ -0,0 +1,47 @@
+#include <hal/rtc.h>
+
+uint8_t
+rtc_read_reg(uint8_t reg_selector)
+{
+    io_outb(RTC_INDEX_PORT, reg_selector);
+    return io_inb(RTC_TARGET_PORT);
+}
+
+uint8_t
+bcd2dec(uint8_t bcd)
+{
+    return (bcd >> 4) * 10 + (bcd & 0x0f);
+}
+
+void
+rtc_get_datetime(rtc_datetime* datetime)
+{
+    datetime->year = rtc_read_reg(RTC_REG_YRS);
+    datetime->month = rtc_read_reg(RTC_REG_MTH);
+    datetime->day = rtc_read_reg(RTC_REG_DAY);
+    datetime->weekday = rtc_read_reg(RTC_REG_WDY);
+    datetime->hour = rtc_read_reg(RTC_REG_HRS);
+    datetime->minute = rtc_read_reg(RTC_REG_MIN);
+    datetime->second = rtc_read_reg(RTC_REG_SEC);
+
+    uint8_t regbv = rtc_read_reg(RTC_REG_B);
+
+    // Convert from bcd to binary when needed
+    if (!RTC_BIN_ENCODED(regbv)) {
+        datetime->year = bcd2dec(datetime->year);
+        datetime->month = bcd2dec(datetime->month);
+        datetime->day = bcd2dec(datetime->day);
+        datetime->hour = bcd2dec(datetime->hour);
+        datetime->minute = bcd2dec(datetime->minute);
+        datetime->second = bcd2dec(datetime->second);
+    }
+
+
+    // To 24 hour format
+    if (!RTC_24HRS_ENCODED(regbv)) {
+        datetime->hour = (datetime->hour >> 7) ? (12 + datetime->hour & 0x80)
+                                               : (datetime->hour & 0x80);
+    }
+
+    datetime->year += RTC_CURRENT_CENTRY * 100;
+}
\ No newline at end of file
index cbcf2bd573644576d0a416d31e176a3e8305a63b..c57de5984a060979e87689d95e77efa375288737 100644 (file)
 
 #include <stdint.h>
 
 
 #include <stdint.h>
 
-static inline uint8_t io_inb(int port) {
+static inline uint8_t
+io_inb(int port)
+{
     uint8_t data;
     uint8_t data;
-    asm volatile("inb %w1,%0" : "=a" (data) : "d" (port));
+    asm volatile("inb %w1,%0" : "=a"(data) : "d"(port));
     return data;
 }
 
     return data;
 }
 
-static inline void io_insb(int port, void* addr, int cnt) {
-    asm volatile("cld\n\trepne\n\tinsb"
-                 : "=D" (addr), "=c" (cnt)
-                 : "d" (port), "0" (addr), "1" (cnt)
+static inline void
+io_insb(int port, void* addr, int cnt)
+{
+    asm volatile("cld\n"
+                 "repne\n"
+                 "insb"
+                 : "=D"(addr), "=c"(cnt)
+                 : "d"(port), "0"(addr), "1"(cnt)
                  : "memory", "cc");
 }
 
                  : "memory", "cc");
 }
 
-static inline uint16_t io_inw(int port) {
+static inline uint16_t
+io_inw(int port)
+{
     uint16_t data;
     uint16_t data;
-    asm volatile("inw %w1,%0" : "=a" (data) : "d" (port));
+    asm volatile("inw %w1,%0" : "=a"(data) : "d"(port));
     return data;
 }
 
     return data;
 }
 
-static inline void io_insw(int port, void* addr, int cnt) {
-    asm volatile("cld\n\trepne\n\tinsw"
-                 : "=D" (addr), "=c" (cnt)
-                 : "d" (port), "0" (addr), "1" (cnt)
+static inline void
+io_insw(int port, void* addr, int cnt)
+{
+    asm volatile("cld\n"
+                 "repne\n"
+                 "insw"
+                 : "=D"(addr), "=c"(cnt)
+                 : "d"(port), "0"(addr), "1"(cnt)
                  : "memory", "cc");
 }
 
                  : "memory", "cc");
 }
 
-static inline uint32_t io_inl(int port) {
+static inline uint32_t
+io_inl(int port)
+{
     uint32_t data;
     uint32_t data;
-    asm volatile("inl %w1,%0" : "=a" (data) : "d" (port));
+    asm volatile("inl %w1,%0" : "=a"(data) : "d"(port));
     return data;
 }
 
     return data;
 }
 
-static inline void io_insl(int port, void* addr, int cnt) {
-    asm volatile("cld\n\trepne\n\tinsl"
-                 : "=D" (addr), "=c" (cnt)
-                 : "d" (port), "0" (addr), "1" (cnt)
+static inline void
+io_insl(int port, void* addr, int cnt)
+{
+    asm volatile("cld\n"
+                 "repne\n"
+                 "insl"
+                 : "=D"(addr), "=c"(cnt)
+                 : "d"(port), "0"(addr), "1"(cnt)
                  : "memory", "cc");
 }
 
                  : "memory", "cc");
 }
 
-static inline void io_outb(int port, uint8_t data) {
-    asm volatile("outb %0,%w1" : : "a" (data), "d" (port));
+static inline void
+io_outb(int port, uint8_t data)
+{
+    asm volatile("outb %0, %w1" : : "a"(data), "d"(port));
 }
 
 }
 
-static inline void io_outsb(int port, const void* addr, int cnt) {
-    asm volatile("cld\n\trepne\n\toutsb"
-                 : "=S" (addr), "=c" (cnt)
-                 : "d" (port), "0" (addr), "1" (cnt)
+static inline void
+io_outsb(int port, const void* addr, int cnt)
+{
+    asm volatile("cld\n"
+                 "repne\n"
+                 "outsb"
+                 : "=S"(addr), "=c"(cnt)
+                 : "d"(port), "0"(addr), "1"(cnt)
                  : "cc");
 }
 
                  : "cc");
 }
 
-static inline void io_outw(int port, uint16_t data) {
-    asm volatile("outw %0,%w1" : : "a" (data), "d" (port));
+static inline void
+io_outw(int port, uint16_t data)
+{
+    asm volatile("outw %0,%w1" : : "a"(data), "d"(port));
 }
 
 }
 
-static inline void io_outsw(int port, const void* addr, int cnt) {
-    asm volatile("cld\n\trepne\n\toutsw"
-                 : "=S" (addr), "=c" (cnt)
-                 : "d" (port), "0" (addr), "1" (cnt)
+static inline void
+io_outsw(int port, const void* addr, int cnt)
+{
+    asm volatile("cld\n"
+                 "repne\n"
+                 "outsw"
+                 : "=S"(addr), "=c"(cnt)
+                 : "d"(port), "0"(addr), "1"(cnt)
                  : "cc");
 }
 
                  : "cc");
 }
 
-static inline void io_outsl(int port, const void* addr, int cnt) {
-    asm volatile("cld\n\trepne\n\toutsl"
-                 : "=S" (addr), "=c" (cnt)
-                 : "d" (port), "0" (addr), "1" (cnt)
+static inline void
+io_outsl(int port, const void* addr, int cnt)
+{
+    asm volatile("cld\n"
+                 "repne\n"
+                 "outsl"
+                 : "=S"(addr), "=c"(cnt)
+                 : "d"(port), "0"(addr), "1"(cnt)
                  : "cc");
 }
 
                  : "cc");
 }
 
-static inline void io_outl(int port, uint32_t data) {
-    asm volatile("outl %0,%w1" : : "a" (data), "d" (port));
+static inline void
+io_outl(int port, uint32_t data)
+{
+    asm volatile("outl %0,%w1" : : "a"(data), "d"(port));
 }
 
 #endif /* __LUNAIX_IO_H */
 }
 
 #endif /* __LUNAIX_IO_H */
diff --git a/lunaix-os/includes/hal/rtc.h b/lunaix-os/includes/hal/rtc.h
new file mode 100644 (file)
index 0000000..69bf38e
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef __LUNAIX_RTC_H
+#define __LUNAIX_RTC_H
+
+#include "io.h"
+
+#define RTC_INDEX_PORT 0x70
+#define RTC_TARGET_PORT 0x71
+
+#define WITH_NMI_DISABLED 0x80
+
+#define RTC_CURRENT_CENTRY 20
+
+#define RTC_REG_YRS 0x9
+#define RTC_REG_MTH 0x8
+#define RTC_REG_DAY 0x7
+#define RTC_REG_WDY 0x6
+#define RTC_REG_HRS 0x4
+#define RTC_REG_MIN 0x2
+#define RTC_REG_SEC 0x0
+
+#define RTC_REG_A 0xA
+#define RTC_REG_B 0xB
+#define RTC_REG_C 0xC
+#define RTC_REG_D 0xD
+
+#define RTC_BIN_ENCODED(reg)    (reg & 0x04)
+#define RTC_24HRS_ENCODED(reg)  (reg & 0x02)
+
+typedef struct
+{
+    uint32_t year;      // use int32 as we need to store the 4-digit year
+    uint8_t month;
+    uint8_t day;
+    uint8_t weekday;
+    uint8_t hour;
+    uint8_t minute;
+    uint8_t second;
+} rtc_datetime;
+
+
+uint8_t
+rtc_read_reg(uint8_t reg_selector);
+
+void 
+rtc_get_datetime(rtc_datetime* datetime);
+
+#endif /* __LUNAIX_RTC_H */
index 9468db342abcf8bf3fea778c1eebd17564b7e82e..fc57669154f79a48bfd5f004fa98326bca85ecfb 100644 (file)
@@ -1,9 +1,10 @@
-#include <stdint.h>
-#include <lunaix/mm/vmm.h>
-#include <lunaix/mm/kalloc.h>
 #include <hal/cpu.h>
 #include <hal/cpu.h>
+#include <hal/rtc.h>
 #include <libc/stdio.h>
 #include <libc/stdio.h>
+#include <lunaix/mm/kalloc.h>
+#include <lunaix/mm/vmm.h>
 #include <lunaix/spike.h>
 #include <lunaix/spike.h>
+#include <stdint.h>
 
 extern uint8_t __kernel_start;
 
 
 extern uint8_t __kernel_start;
 
@@ -11,28 +12,26 @@ void
 _kernel_main()
 {
     char buf[64];
 _kernel_main()
 {
     char buf[64];
-    
+
     printf("Hello higher half kernel world!\nWe are now running in virtual "
            "address space!\n\n");
     printf("Hello higher half kernel world!\nWe are now running in virtual "
            "address space!\n\n");
-    
+
     cpu_get_brand(buf);
     printf("CPU: %s\n\n", buf);
 
     void* k_start = vmm_v2p(&__kernel_start);
     cpu_get_brand(buf);
     printf("CPU: %s\n\n", buf);
 
     void* k_start = vmm_v2p(&__kernel_start);
-    printf("The kernel's base address mapping: %p->%p\n", &__kernel_start, k_start);
+    printf(
+      "The kernel's base address mapping: %p->%p\n", &__kernel_start, k_start);
 
     // test malloc & free
 
     // test malloc & free
-    
-    uint8_t** arr = (uint8_t**) lxmalloc(10 * sizeof(uint8_t*));
-    
-    for (size_t i = 0; i < 10; i++)
-    {
-        arr[i] = (uint8_t*) lxmalloc((i + 1) * 2);
-    }
 
 
+    uint8_t** arr = (uint8_t**)lxmalloc(10 * sizeof(uint8_t*));
 
 
-    for (size_t i = 0; i < 10; i++)
-    {
+    for (size_t i = 0; i < 10; i++) {
+        arr[i] = (uint8_t*)lxmalloc((i + 1) * 2);
+    }
+
+    for (size_t i = 0; i < 10; i++) {
         lxfree(arr[i]);
     }
 
         lxfree(arr[i]);
     }
 
@@ -41,18 +40,21 @@ _kernel_main()
     big_[1] = 23;
     big_[2] = 3;
 
     big_[1] = 23;
     big_[2] = 3;
 
-    printf("%u, %u, %u", big_[0], big_[1], big_[2]);
-    
+    printf("%u, %u, %u\n", big_[0], big_[1], big_[2]);
+
     // good free
     lxfree(arr);
     lxfree(big_);
 
     // good free
     lxfree(arr);
     lxfree(big_);
 
-    // uint8_t* bad1 = lxmalloc(123);
-    // void* bad2 = lxmalloc(1);
+    rtc_datetime datetime;
 
 
-    // *((uint32_t*)(bad1 - 4)) = 0xc2343312UL;
+    rtc_get_datetime(&datetime);
 
 
-    // // bad free
-    // lxfree(bad1);
-    // lxfree(bad2 - 2);
+    printf("%u/%u/%u %u:%u:%u",
+           datetime.year,
+           datetime.month,
+           datetime.day,
+           datetime.hour,
+           datetime.minute,
+           datetime.second);
 }
\ No newline at end of file
 }
\ No newline at end of file