commit
f71d3bd0b3
@ -18,17 +18,36 @@
|
|||||||
* and regular decimal integers. */
|
* and regular decimal integers. */
|
||||||
#define from_bcd(val) ((val / 16) * 10 + (val & 0xf))
|
#define from_bcd(val) ((val / 16) * 10 + (val & 0xf))
|
||||||
|
|
||||||
|
#define CMOS_ADDRESS 0x70
|
||||||
|
#define CMOS_DATA 0x71
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CMOS_SECOND = 0,
|
||||||
|
CMOS_MINUTE = 2,
|
||||||
|
CMOS_HOUR = 4,
|
||||||
|
CMOS_DAY = 7,
|
||||||
|
CMOS_MONTH = 8,
|
||||||
|
CMOS_YEAR = 9
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
cmos_dump(
|
cmos_dump(
|
||||||
uint16_t * values
|
uint16_t * values
|
||||||
) {
|
) {
|
||||||
uint16_t index;
|
uint16_t index;
|
||||||
for (index = 0; index < 128; ++index) {
|
for (index = 0; index < 128; ++index) {
|
||||||
outportb(0x70, index);
|
outportb(CMOS_ADDRESS, index);
|
||||||
values[index] = inportb(0x71);
|
values[index] = inportb(CMOS_DATA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int is_update_in_progress(void)
|
||||||
|
{
|
||||||
|
outportb(CMOS_ADDRESS, 0x0a);
|
||||||
|
return inportb(CMOS_DATA) & 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current month and day.
|
* Get the current month and day.
|
||||||
*
|
*
|
||||||
@ -43,8 +62,8 @@ get_date(
|
|||||||
uint16_t values[128]; /* CMOS dump */
|
uint16_t values[128]; /* CMOS dump */
|
||||||
cmos_dump(values);
|
cmos_dump(values);
|
||||||
|
|
||||||
*month = from_bcd(values[8]);
|
*month = from_bcd(values[CMOS_MONTH]);
|
||||||
*day = from_bcd(values[7]);
|
*day = from_bcd(values[CMOS_DAY]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,9 +82,9 @@ get_time(
|
|||||||
uint16_t values[128]; /* CMOS dump */
|
uint16_t values[128]; /* CMOS dump */
|
||||||
cmos_dump(values);
|
cmos_dump(values);
|
||||||
|
|
||||||
*hours = from_bcd(values[4]);
|
*hours = from_bcd(values[CMOS_HOUR]);
|
||||||
*minutes = from_bcd(values[2]);
|
*minutes = from_bcd(values[CMOS_MINUTE]);
|
||||||
*seconds = from_bcd(values[0]);
|
*seconds = from_bcd(values[CMOS_SECOND]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t secs_of_years(int years) {
|
uint32_t secs_of_years(int years) {
|
||||||
@ -127,16 +146,37 @@ uint32_t boot_time = 0;
|
|||||||
|
|
||||||
uint32_t read_cmos(void) {
|
uint32_t read_cmos(void) {
|
||||||
uint16_t values[128];
|
uint16_t values[128];
|
||||||
|
uint16_t old_values[128];
|
||||||
|
|
||||||
|
while (is_update_in_progress())
|
||||||
|
;
|
||||||
|
|
||||||
cmos_dump(values);
|
cmos_dump(values);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
memcpy(old_values, values, 128);
|
||||||
|
while (is_update_in_progress())
|
||||||
|
;
|
||||||
|
|
||||||
|
cmos_dump(values);
|
||||||
|
} while ((old_values[CMOS_SECOND] != values[CMOS_SECOND]) ||
|
||||||
|
(old_values[CMOS_MINUTE] != values[CMOS_MINUTE]) ||
|
||||||
|
(old_values[CMOS_HOUR] != values[CMOS_HOUR]) ||
|
||||||
|
(old_values[CMOS_DAY] != values[CMOS_DAY]) ||
|
||||||
|
(old_values[CMOS_MONTH] != values[CMOS_MONTH]) ||
|
||||||
|
(old_values[CMOS_YEAR] != values[CMOS_YEAR]));
|
||||||
|
|
||||||
/* Math Time */
|
/* Math Time */
|
||||||
uint32_t time = secs_of_years(from_bcd(values[9]) - 1) +
|
uint32_t time =
|
||||||
secs_of_month(from_bcd(values[8]) - 1, from_bcd(values[9])) +
|
secs_of_years(from_bcd(values[CMOS_YEAR]) - 1) +
|
||||||
(from_bcd(values[7]) - 1) * 86400 +
|
secs_of_month(from_bcd(values[CMOS_MONTH]) - 1,
|
||||||
(from_bcd(values[4])) * 3600 +
|
from_bcd(values[CMOS_YEAR])) +
|
||||||
(from_bcd(values[2])) * 60 +
|
(from_bcd(values[CMOS_DAY]) - 1) * 86400 +
|
||||||
from_bcd(values[0]) +
|
(from_bcd(values[CMOS_HOUR])) * 3600 +
|
||||||
0;
|
(from_bcd(values[CMOS_MINUTE])) * 60 +
|
||||||
|
from_bcd(values[CMOS_SECOND]) + 0;
|
||||||
|
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user