--- /dev/null
+#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
#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);
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);
}
}
--- /dev/null
+#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);
+}