Skip to content

Commit 33cceff

Browse files
authored
Merge pull request #626 from tier4/feat/rtc_driver_first
feat(rtc): rtc driver implementation initial setup
2 parents bb0ad0d + 2eff6c4 commit 33cceff

File tree

3 files changed

+140
-0
lines changed

3 files changed

+140
-0
lines changed

awkernel_drivers/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,6 @@ pub mod pcie;
2121

2222
#[cfg(feature = "mii")]
2323
pub mod mii;
24+
25+
#[cfg(feature = "x86")]
26+
pub mod rtc;

awkernel_drivers/src/rtc.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//! Real-Time Clock (RTC) driver support
2+
3+
#[cfg(any(target_arch = "x86_64", feature = "x86"))]
4+
pub mod mc146818;
5+
6+
#[cfg(any(target_arch = "x86_64", feature = "x86"))]
7+
pub use mc146818::Mc146818Rtc;
8+
9+
#[derive(Debug, Clone, Copy)]
10+
pub struct DateTime {
11+
pub year: u16, // Full year (e.g., 2024)
12+
pub month: u8, // 1-12
13+
pub day: u8, // 1-31
14+
pub hour: u8, // 0-23 (24-hour format)
15+
pub minute: u8, // 0-59
16+
pub second: u8, // 0-59
17+
}
18+
19+
impl DateTime {
20+
pub fn new(year: u16, month: u8, day: u8, hour: u8, minute: u8, second: u8) -> Self {
21+
Self {
22+
year,
23+
month,
24+
day,
25+
hour,
26+
minute,
27+
second,
28+
}
29+
}
30+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
//! MC146818-compatible CMOS RTC driver for x86_64, x86
2+
3+
use core::arch::asm;
4+
5+
const _IO_RTC: u16 = 0x070;
6+
7+
// The registers, and the bits within each register.
8+
9+
const _MC_SEC: u8 = 0x00; // Time of year: seconds (0-59)
10+
const _MC_MIN: u8 = 0x02; // Time of year: minutes (0-59)
11+
const _MC_HOUR: u8 = 0x04; // Time of year: hour (see above)
12+
const _MC_DOW: u8 = 0x06; // Time of year: day of week (1-7)
13+
const _MC_DOM: u8 = 0x07; // Time of year: day of month (1-31)
14+
const _MC_MONTH: u8 = 0x08; // Time of year: month (1-12)
15+
const _MC_YEAR: u8 = 0x09; // Time of year: year in century (0-99)
16+
17+
const _MC_REGA: u8 = 0x0a; // Control register A
18+
19+
const _MC_REGA_RSMASK: u8 = 0x0f; // Interrupt rate select mask
20+
const _MC_REGA_DVMASK: u8 = 0x70; // Divisor select mask
21+
const _MC_REGA_UIP: u8 = 0x80; // Update in progress; read only
22+
23+
const _MC_REGB: u8 = 0x0b; // Control register B
24+
25+
const _MC_REGB_DSE: u8 = 0x01; // Daylight Saving Enable
26+
const _MC_REGB_24HR: u8 = 0x02; // 24-hour mode (AM/PM mode when clear)
27+
const _MC_REGB_DM: u8 = 0x04; // Binary mode (BCD mode when clear)
28+
const _MC_REGB_SQWE: u8 = 0x08; // Square wave enable, ONLY in BQ3285E
29+
const _MC_REGB_UIE: u8 = 0x10; // Update End interrupt enable
30+
const _MC_REGB_AIE: u8 = 0x20; // Alarm interrupt enable
31+
const _MC_REGB_PIE: u8 = 0x40; // Periodic interrupt enable
32+
const _MC_REGB_SET: u8 = 0x80; // Allow time to be set; stops updates
33+
34+
const _MC_REGC: u8 = 0x0c; // Control register C
35+
36+
const _MC_REGC_UF: u8 = 0x10; // Update End interrupt flag
37+
const _MC_REGC_AF: u8 = 0x20; // Alarm interrupt flag
38+
const _MC_REGC_PF: u8 = 0x40; // Periodic interrupt flag
39+
const _MC_REGC_IRQF: u8 = 0x80; // Interrupt request pending flag
40+
41+
const _MC_REGD: u8 = 0x0d; // Control register D
42+
43+
// MC_REGD_UNUSED 0x7f UNUSED
44+
const _MC_REGD_VRT: u8 = 0x80; // Valid RAM and Time bit
45+
46+
// Number of TOD registers
47+
const _MC_NREGS: usize = 0xe; // 14 registers; CMOS follows
48+
const _MC_NTODREGS: usize = 0xa; // 10 of those are for TOD and alarm
49+
50+
pub struct Mc146818Rtc;
51+
52+
impl Mc146818Rtc {
53+
pub fn new() -> Self {
54+
Self
55+
}
56+
}
57+
58+
impl Default for Mc146818Rtc {
59+
fn default() -> Self {
60+
Self::new()
61+
}
62+
}
63+
impl Mc146818Rtc {
64+
fn _mc146818_read(reg: u8) -> u8 {
65+
unsafe {
66+
asm!(
67+
"out dx, al",
68+
in("dx") _IO_RTC,
69+
in("al") reg,
70+
options(nostack, preserves_flags)
71+
);
72+
73+
awkernel_lib::delay::wait_microsec(1);
74+
75+
let value: u8;
76+
asm!(
77+
"in al, dx",
78+
in("dx") _IO_RTC + 1,
79+
out("al") value,
80+
options(nostack, preserves_flags)
81+
);
82+
value
83+
}
84+
}
85+
86+
fn _mc146818_write(reg: u8, value: u8) {
87+
unsafe {
88+
asm!(
89+
"out dx, al",
90+
in("dx") _IO_RTC,
91+
in("al") reg,
92+
options(nostack, preserves_flags)
93+
);
94+
95+
awkernel_lib::delay::wait_microsec(1);
96+
97+
asm!(
98+
"out dx, al",
99+
in("dx") _IO_RTC + 1,
100+
in("al") value,
101+
options(nostack, preserves_flags)
102+
);
103+
104+
awkernel_lib::delay::wait_microsec(1);
105+
}
106+
}
107+
}

0 commit comments

Comments
 (0)