AquilaOS documentation
How it works, and its code
Toggle main menu visibility
Loading...
Searching...
No Matches
cmos.c
Go to the documentation of this file.
1
6
7
#include <
core/system.h
>
8
#include <
core/types.h
>
9
#include <
cpu/io.h
>
10
11
#define RTC_SEC 0x00
/* seconds */
12
#define RTC_MIN 0x02
/* minutes */
13
#define RTC_HRS 0x04
/* hours */
14
#define RTC_WD 0x06
/* the day of the week */
15
#define RTC_DOM 0x07
/* the day of the month */
16
#define RTC_MON 0x08
/* the month */
17
#define RTC_YR 0x09
/* the year */
18
#define RTC_SA 0x0A
/* status register A */
19
#define RTC_SB 0x0B
/* status register B */
20
21
#define RTC_UIP 0x80
/* an update in progress (status A) */
22
#define RTC_24H 0x02
/* 24-hour mode (status B) */
23
#define RTC_BIN 0x04
/* binary mode, else BCD (status B) */
24
#define RTC_PM 0x80
/* the PM flag in the hours (12-hour mode) */
25
26
static
struct
ioaddr
cmos
;
27
30
static
uint8_t
cmos_reg_read
(
uint8_t
reg)
31
{
32
io_out8
(&
cmos
, 0, reg & 0x7F);
33
return
io_in8
(&
cmos
, 1);
34
}
35
37
struct
cmos_rtc
{
38
uint8_t
yr
;
39
uint8_t
mon
;
40
uint8_t
mday
;
41
uint8_t
hrs
;
42
uint8_t
min
;
43
uint8_t
sec
;
44
uint8_t
wday
;
45
};
46
48
static
inline
uint8_t
bcd_to_bin
(
uint8_t
bcd)
49
{
50
return
((bcd >> 4) & 0xF) * 10 + (bcd & 0xF);
51
}
52
55
static
int
cmos_time
(
struct
cmos_rtc
*rtc)
56
{
57
uint8_t
fmt =
cmos_reg_read
(
RTC_SB
);
58
59
/* wait for an update in progress to finish, so that the values read
60
* are consistent; bounded, since a machine without a CMOS clock reads
61
* all ones, an update that never ends (an update takes 2 ms at most) */
62
for
(
int
i = 0; i < 1000000 && (
cmos_reg_read
(
RTC_SA
) &
RTC_UIP
); ++i)
63
;
64
65
rtc->
yr
=
cmos_reg_read
(
RTC_YR
);
66
rtc->
mon
=
cmos_reg_read
(
RTC_MON
);
67
rtc->
mday
=
cmos_reg_read
(
RTC_DOM
);
68
rtc->
hrs
=
cmos_reg_read
(
RTC_HRS
);
69
rtc->
min
=
cmos_reg_read
(
RTC_MIN
);
70
rtc->
sec
=
cmos_reg_read
(
RTC_SEC
);
71
rtc->
wday
=
cmos_reg_read
(
RTC_WD
);
72
73
/* the PM flag only means something in 12-hour mode */
74
int
pm = !(fmt &
RTC_24H
) && (rtc->
hrs
&
RTC_PM
);
75
rtc->
hrs
&=
~RTC_PM
;
76
77
if
(!(fmt &
RTC_BIN
)) {
78
/* convert the values from BCD to binary */
79
rtc->
yr
=
bcd_to_bin
(rtc->
yr
);
80
rtc->
mon
=
bcd_to_bin
(rtc->
mon
);
81
rtc->
mday
=
bcd_to_bin
(rtc->
mday
);
82
rtc->
hrs
=
bcd_to_bin
(rtc->
hrs
);
83
rtc->
min
=
bcd_to_bin
(rtc->
min
);
84
rtc->
sec
=
bcd_to_bin
(rtc->
sec
);
85
rtc->
wday
=
bcd_to_bin
(rtc->
wday
);
86
}
87
88
if
(!(fmt &
RTC_24H
)) {
89
/* 12-hour mode: 12 AM is 0, 12 PM is 12 */
90
rtc->
hrs
%= 12;
91
if
(pm) rtc->
hrs
+= 12;
92
}
93
94
return
0;
95
}
96
97
/*
98
* Reads the date and time from the real time clock, as UNIX time.
99
*/
100
int
arch_time_get
(
struct
timespec
*ts)
101
{
102
struct
cmos_rtc
rtc;
103
cmos_time
(&rtc);
104
105
time_t
time = 0;
106
uint32_t
yr
= rtc.
yr
+ 2000;
107
uint32_t
mon
= rtc.
mon
;
108
109
/* the formula below counts months from March, so January and
110
* February are months 13 and 14 of the previous year */
111
if
(
mon
<= 2) {
112
mon
+= 12;
113
yr
-= 1;
114
}
115
116
/* the years, in days */
117
time = (365 *
yr
) + (
yr
/ 4) - (
yr
/ 100) + (
yr
/ 400);
118
/* the months and days, in days */
119
time += (30 *
mon
) + (3 * (
mon
+ 1) / 5) + rtc.
mday
;
120
/* UNIX time starts on January 1st, 1970 */
121
time -= 719561;
122
/* the days, in seconds */
123
time *= 86400;
124
/* and the time of day */
125
time += (3600 * rtc.
hrs
) + (60 * rtc.
min
) + rtc.
sec
;
126
127
ts->
tv_sec
= time;
128
ts->
tv_nsec
= 0;
129
130
return
0;
131
}
132
139
int
x86_cmos_setup
(
struct
ioaddr
*
ioaddr
)
140
{
141
cmos
= *
ioaddr
;
142
printk
(
"cmos: initializing [%p (%s)]\n"
,
cmos
.
addr
,
ioaddr_type_str
(&
cmos
));
143
144
return
0;
145
}
io_in8
static uint8_t io_in8(struct ioaddr *io, uintptr_t off)
Reads an 8-, 16- or 32-bit register.
Definition
io.h:28
io_out8
static void io_out8(struct ioaddr *io, uintptr_t off, uint8_t val)
Writes an 8-, 16- or 32-bit register.
Definition
io.h:44
ioaddr_type_str
static char * ioaddr_type_str(struct ioaddr *io)
Definition
io.h:101
RTC_DOM
#define RTC_DOM
Definition
cmos.c:15
RTC_SEC
#define RTC_SEC
Definition
cmos.c:11
RTC_UIP
#define RTC_UIP
Definition
cmos.c:21
RTC_SB
#define RTC_SB
Definition
cmos.c:19
RTC_MIN
#define RTC_MIN
Definition
cmos.c:12
cmos
static struct ioaddr cmos
Definition
cmos.c:26
RTC_MON
#define RTC_MON
Definition
cmos.c:16
RTC_WD
#define RTC_WD
Definition
cmos.c:14
RTC_YR
#define RTC_YR
Definition
cmos.c:17
RTC_SA
#define RTC_SA
Definition
cmos.c:18
cmos_reg_read
static uint8_t cmos_reg_read(uint8_t reg)
Reads a CMOS register.
Definition
cmos.c:30
bcd_to_bin
static uint8_t bcd_to_bin(uint8_t bcd)
Converts a BCD byte to binary.
Definition
cmos.c:48
RTC_BIN
#define RTC_BIN
Definition
cmos.c:23
RTC_24H
#define RTC_24H
Definition
cmos.c:22
RTC_PM
#define RTC_PM
Definition
cmos.c:24
cmos_time
static int cmos_time(struct cmos_rtc *rtc)
Reads the real time clock's date and time, in binary and in 24-hour time.
Definition
cmos.c:55
RTC_HRS
#define RTC_HRS
Definition
cmos.c:13
system.h
io.h
x86_cmos_setup
int x86_cmos_setup(struct ioaddr *ioaddr)
Sets where the CMOS's ports are.
Definition
cmos.c:139
printk
int printk(const char *fmt,...)
Writes a kernel message, to the message buffer and the consoles.
Definition
printk.c:249
arch_time_get
int arch_time_get(struct timespec *ts)
Reads the date and time from the real time clock.
Definition
rtc.c:16
uint32_t
unsigned int uint32_t
Definition
stddef.h:22
uint8_t
unsigned char uint8_t
Definition
stddef.h:20
cmos_rtc
The real time clock's date and time, as it keeps them.
Definition
cmos.c:37
cmos_rtc::mon
uint8_t mon
Definition
cmos.c:39
cmos_rtc::mday
uint8_t mday
Definition
cmos.c:40
cmos_rtc::min
uint8_t min
Definition
cmos.c:42
cmos_rtc::sec
uint8_t sec
Definition
cmos.c:43
cmos_rtc::yr
uint8_t yr
Definition
cmos.c:38
cmos_rtc::hrs
uint8_t hrs
Definition
cmos.c:41
cmos_rtc::wday
uint8_t wday
Definition
cmos.c:44
ioaddr
Where a device's registers are.
Definition
io.h:95
ioaddr::addr
uintptr_t addr
Definition
io.h:97
timespec
Definition
types.h:30
timespec::tv_nsec
uint32_t tv_nsec
Definition
types.h:32
timespec::tv_sec
time_t tv_sec
Definition
types.h:31
types.h
time_t
uint64_t time_t
Definition
types.h:26
kernel
arch
i386
platform
misc
cmos.c
Generated by
1.18.0