From: Tulio A M Mendes Date: Thu, 12 Feb 2026 06:37:06 +0000 (-0300) Subject: refactor: extract x86 CMOS I/O from drivers/rtc.c to HAL layer X-Git-Url: https://projects.tadryanom.me/?a=commitdiff_plain;h=945f4be3858ce3c98d66e1fd6cd1ff51bab0bb69;p=AdrOS.git refactor: extract x86 CMOS I/O from drivers/rtc.c to HAL layer 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. --- diff --git a/include/hal/rtc.h b/include/hal/rtc.h new file mode 100644 index 0000000..132fb95 --- /dev/null +++ b/include/hal/rtc.h @@ -0,0 +1,28 @@ +#ifndef HAL_RTC_H +#define HAL_RTC_H + +#include + +/* + * 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 diff --git a/src/drivers/rtc.c b/src/drivers/rtc.c index 4a71ab5..95e4251 100644 --- a/src/drivers/rtc.c +++ b/src/drivers/rtc.c @@ -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 index 0000000..1b07fad --- /dev/null +++ b/src/hal/x86/rtc.c @@ -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); +}