]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
refactor: extract x86 CMOS I/O from drivers/rtc.c to HAL layer
authorTulio A M Mendes <[email protected]>
Thu, 12 Feb 2026 06:37:06 +0000 (03:37 -0300)
committerTulio A M Mendes <[email protected]>
Fri, 13 Feb 2026 02:44:55 +0000 (23:44 -0300)
Created include/hal/rtc.h with generic HAL RTC interface and
src/hal/x86/rtc.c with x86 CMOS port I/O implementation.

src/drivers/rtc.c is now fully architecture-agnostic: it calls
hal_rtc_read_raw() for hardware access and keeps only the generic
BCD-to-binary conversion and UNIX timestamp calculation logic.

This follows the same HAL pattern used by timer, keyboard, uart,
and video drivers.

include/hal/rtc.h [new file with mode: 0644]
src/drivers/rtc.c
src/hal/x86/rtc.c [new file with mode: 0644]

diff --git a/include/hal/rtc.h b/include/hal/rtc.h
new file mode 100644 (file)
index 0000000..132fb95
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef HAL_RTC_H
+#define HAL_RTC_H
+
+#include <stdint.h>
+
+/*
+ * HAL RTC interface — architecture-specific implementations provide
+ * raw register reads from the hardware real-time clock.
+ *
+ * All values are returned as raw hardware values (may be BCD-encoded
+ * depending on the platform).  The generic driver layer handles
+ * BCD-to-binary conversion and timestamp calculation.
+ */
+
+struct hal_rtc_raw {
+    uint8_t second;
+    uint8_t minute;
+    uint8_t hour;
+    uint8_t day;
+    uint8_t month;
+    uint8_t year;       /* two-digit year from hardware */
+    uint8_t status_b;   /* status/config register (x86: CMOS reg 0x0B) */
+};
+
+void hal_rtc_init(void);
+void hal_rtc_read_raw(struct hal_rtc_raw* raw);
+
+#endif
index 4a71ab5104ec3d4adb37a7e95f91d6238ebe2eab..95e4251f0120998a1c4ac62ee8137041f5cc251d 100644 (file)
@@ -1,56 +1,26 @@
 #include "rtc.h"
-
-#define CMOS_ADDR 0x70
-#define CMOS_DATA 0x71
-
-#define RTC_REG_SEC   0x00
-#define RTC_REG_MIN   0x02
-#define RTC_REG_HOUR  0x04
-#define RTC_REG_DAY   0x07
-#define RTC_REG_MON   0x08
-#define RTC_REG_YEAR  0x09
-#define RTC_REG_STATB 0x0B
-
-static inline void port_outb(uint16_t port, uint8_t val) {
-    __asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port));
-}
-
-static inline uint8_t port_inb(uint16_t port) {
-    uint8_t ret;
-    __asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
-    return ret;
-}
-
-static uint8_t cmos_read(uint8_t reg) {
-    port_outb(CMOS_ADDR, reg);
-    return port_inb(CMOS_DATA);
-}
-
-static int rtc_updating(void) {
-    port_outb(CMOS_ADDR, 0x0A);
-    return port_inb(CMOS_DATA) & 0x80;
-}
+#include "hal/rtc.h"
 
 static uint8_t bcd_to_bin(uint8_t v) {
     return (uint8_t)((v & 0x0F) + ((v >> 4) * 10));
 }
 
 void rtc_init(void) {
-    /* Nothing to do — CMOS is always available on x86 */
+    hal_rtc_init();
 }
 
 void rtc_read(struct rtc_time* t) {
-    while (rtc_updating()) {}
+    struct hal_rtc_raw raw;
+    hal_rtc_read_raw(&raw);
 
-    t->second = cmos_read(RTC_REG_SEC);
-    t->minute = cmos_read(RTC_REG_MIN);
-    t->hour   = cmos_read(RTC_REG_HOUR);
-    t->day    = cmos_read(RTC_REG_DAY);
-    t->month  = cmos_read(RTC_REG_MON);
-    t->year   = cmos_read(RTC_REG_YEAR);
+    t->second = raw.second;
+    t->minute = raw.minute;
+    t->hour   = raw.hour;
+    t->day    = raw.day;
+    t->month  = raw.month;
+    t->year   = raw.year;
 
-    uint8_t statb = cmos_read(RTC_REG_STATB);
-    int bcd = !(statb & 0x04);
+    int bcd = !(raw.status_b & 0x04);
 
     if (bcd) {
         t->second = bcd_to_bin(t->second);
@@ -63,7 +33,7 @@ void rtc_read(struct rtc_time* t) {
 
     t->year += 2000;
 
-    if (!(statb & 0x02) && (cmos_read(RTC_REG_HOUR) & 0x80)) {
+    if (!(raw.status_b & 0x02) && (raw.hour & 0x80)) {
         t->hour = (uint8_t)((t->hour + 12) % 24);
     }
 }
diff --git a/src/hal/x86/rtc.c b/src/hal/x86/rtc.c
new file mode 100644 (file)
index 0000000..1b07fad
--- /dev/null
@@ -0,0 +1,43 @@
+#include "hal/rtc.h"
+
+#include "arch/x86/io.h"
+
+#define CMOS_ADDR 0x70
+#define CMOS_DATA 0x71
+
+#define RTC_REG_SEC   0x00
+#define RTC_REG_MIN   0x02
+#define RTC_REG_HOUR  0x04
+#define RTC_REG_DAY   0x07
+#define RTC_REG_MON   0x08
+#define RTC_REG_YEAR  0x09
+#define RTC_REG_STATA 0x0A
+#define RTC_REG_STATB 0x0B
+
+static uint8_t cmos_read(uint8_t reg) {
+    outb(CMOS_ADDR, reg);
+    return inb(CMOS_DATA);
+}
+
+static int rtc_updating(void) {
+    outb(CMOS_ADDR, RTC_REG_STATA);
+    return inb(CMOS_DATA) & 0x80;
+}
+
+void hal_rtc_init(void) {
+    /* Nothing to do — CMOS is always available on x86 */
+}
+
+void hal_rtc_read_raw(struct hal_rtc_raw* raw) {
+    if (!raw) return;
+
+    while (rtc_updating()) {}
+
+    raw->second   = cmos_read(RTC_REG_SEC);
+    raw->minute   = cmos_read(RTC_REG_MIN);
+    raw->hour     = cmos_read(RTC_REG_HOUR);
+    raw->day      = cmos_read(RTC_REG_DAY);
+    raw->month    = cmos_read(RTC_REG_MON);
+    raw->year     = cmos_read(RTC_REG_YEAR);
+    raw->status_b = cmos_read(RTC_REG_STATB);
+}