MOS Source Code
Loading...
Searching...
No Matches
rtc.c
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#define CURRENT_YEAR 2024
4
6
7#include "mos/assert.h"
11
12#include <mos/types.h>
13
15 .name = "rtc",
16 .list_node = LIST_NODE_INIT(rtc_clocksource),
17 .frequency = 1000,
18 .ticks = 0,
19};
20
21static const u8 RTC_STATUS_REG_B = 0x0B;
22static const u8 CMOS_PORT_ADDRESS = 0x70;
23static const u8 CMOS_PORT_DATA = 0x71;
24
30
32{
33 return rtc_read_reg(0x0A) & 0x80;
34}
35
37{
38 u8 last_second;
39 u8 last_minute;
40 u8 last_hour;
41 u8 last_day;
42 u8 last_month;
43 u8 last_year;
44
46 ; // Make sure an update isn't in progress
47 time->second = rtc_read_reg(0x00);
48 time->minute = rtc_read_reg(0x02);
49 time->hour = rtc_read_reg(0x04);
50 time->day = rtc_read_reg(0x07);
51 time->month = rtc_read_reg(0x08);
52 time->year = rtc_read_reg(0x09);
53
54 do
55 {
56 last_second = time->second;
57 last_minute = time->minute;
58 last_hour = time->hour;
59 last_day = time->day;
60 last_month = time->month;
61 last_year = time->year;
62
64 ; // Make sure an update isn't in progress
65 time->second = rtc_read_reg(0x00);
66 time->minute = rtc_read_reg(0x02);
67 time->hour = rtc_read_reg(0x04);
68 time->day = rtc_read_reg(0x07);
69 time->month = rtc_read_reg(0x08);
70 time->year = rtc_read_reg(0x09);
71 } while ((last_second != time->second) || (last_minute != time->minute) || (last_hour != time->hour) || (last_day != time->day) || (last_month != time->month) ||
72 (last_year != time->year));
73
74#define bcd_to_binary(val) (((val) & 0x0F) + ((val) / 16) * 10)
75
76 const u8 registerB = rtc_read_reg(0x0B);
77 if (!(registerB & 0x04))
78 {
79 // BCD to binary values
80 time->second = bcd_to_binary(time->second);
81 time->minute = bcd_to_binary(time->minute);
82 time->hour = ((time->hour & 0x0F) + (((time->hour & 0x70) / 16) * 10)) | (time->hour & 0x80); //
83 time->day = bcd_to_binary(time->day);
84 time->month = bcd_to_binary(time->month);
85 time->year = bcd_to_binary(time->year);
86 }
87
88 if (!(registerB & 0x02) && (time->hour & 0x80))
89 {
90 // 12 hour clock to 24 hour
91 time->hour = ((time->hour & 0x7F) + 12) % 24;
92 }
93
94 time->year += (CURRENT_YEAR / 100) * 100;
95 if (time->year < CURRENT_YEAR)
96 time->year += 100;
97}
98
99bool rtc_irq_handler(u32 irq, void *data)
100{
101 MOS_UNUSED(data);
102 MOS_ASSERT(irq == IRQ_CMOS_RTC);
103 rtc_read_reg(0x0C); // select register C and ack the interrupt
105 return true;
106}
107
109{
110 port_outb(CMOS_PORT_ADDRESS, 0x80 | RTC_STATUS_REG_B); // select register B, and disable NMI
111 const u8 val = port_inb(CMOS_PORT_DATA); // read the current value of register B
112 port_outb(CMOS_PORT_ADDRESS, 0x80 | RTC_STATUS_REG_B); // set the index again (a read will reset the index to register D)
113 port_outb(CMOS_PORT_DATA, val | 0x40); // write the previous value ORed with 0x40. This turns on bit 6 of register B
114
115 rtc_read_reg(0x0C); // select register C and ack the interrupt
117}
#define MOS_ASSERT(cond)
Definition assert.h:14
void clocksource_register(clocksource_t *clocksource)
Definition clocksource.c:10
void clocksource_tick(clocksource_t *clocksource)
Definition clocksource.c:17
#define LIST_NODE_INIT(container)
Definition list.h:41
#define MOS_UNUSED(x)
Definition mos_global.h:64
u16 x86_port_t
Definition port.h:8
should_inline void port_outb(u16 port, u8 value)
Definition port.h:31
should_inline u8 port_inb(u16 port)
Definition port.h:10
static clocksource_t rtc_clocksource
Definition rtc.c:14
void rtc_read_time(timeval_t *time)
Definition rtc.c:36
static const u8 RTC_STATUS_REG_B
Definition rtc.c:21
u8 rtc_is_update_in_progress()
Definition rtc.c:31
bool rtc_irq_handler(u32 irq, void *data)
Definition rtc.c:99
#define CURRENT_YEAR
Definition rtc.c:3
static const u8 CMOS_PORT_ADDRESS
Definition rtc.c:22
u8 rtc_read_reg(x86_port_t reg)
Definition rtc.c:25
#define bcd_to_binary(val)
void rtc_init()
Definition rtc.c:108
static const u8 CMOS_PORT_DATA
Definition rtc.c:23
unsigned int u32
Definition types.h:21
unsigned char u8
Definition types.h:19
@ IRQ_CMOS_RTC