00001 #include "devices/rtc.h"
00002
00003 #include <stdio.h>
00004 #include "threads/io.h"
00005
00006
00007
00008
00009
00010
00011 #define CMOS_REG_SET 0x70
00012 #define CMOS_REG_IO 0x71
00013
00014
00015
00016
00017 #define RTC_REG_SEC 0
00018 #define RTC_REG_MIN 2
00019 #define RTC_REG_HOUR 4
00020 #define RTC_REG_MDAY 7
00021 #define RTC_REG_MON 8
00022 #define RTC_REG_YEAR 9
00023
00024
00025 #define RTC_REG_A 0x0a
00026 #define RTC_REG_B 0x0b
00027 #define RTC_REG_C 0x0c
00028 #define RTC_REG_D 0x0d
00029
00030
00031 #define RTCSA_UIP 0x80
00032
00033
00034 #define RTCSB_SET 0x80
00035 #define RTCSB_DM 0x04
00036 #define RTCSB_24HR 0x02
00037
00038 static int bcd_to_bin (uint8_t);
00039 static uint8_t cmos_read (uint8_t index);
00040
00041
00042
00043 time_t
00044 rtc_get_time (void)
00045 {
00046 static const int days_per_month[12] =
00047 {
00048 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
00049 };
00050 int sec, min, hour, mday, mon, year;
00051 time_t time;
00052 int i;
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 do
00067 {
00068 sec = bcd_to_bin (cmos_read (RTC_REG_SEC));
00069 min = bcd_to_bin (cmos_read (RTC_REG_MIN));
00070 hour = bcd_to_bin (cmos_read (RTC_REG_HOUR));
00071 mday = bcd_to_bin (cmos_read (RTC_REG_MDAY));
00072 mon = bcd_to_bin (cmos_read (RTC_REG_MON));
00073 year = bcd_to_bin (cmos_read (RTC_REG_YEAR));
00074 }
00075 while (sec != bcd_to_bin (cmos_read (RTC_REG_SEC)));
00076
00077
00078
00079
00080
00081 if (year < 70)
00082 year += 100;
00083 year -= 70;
00084
00085
00086 time = (year * 365 + (year - 1) / 4) * 24 * 60 * 60;
00087 for (i = 1; i <= mon; i++)
00088 time += days_per_month[i - 1] * 24 * 60 * 60;
00089 if (mon > 2 && year % 4 == 0)
00090 time += 24 * 60 * 60;
00091 time += (mday - 1) * 24 * 60 * 60;
00092 time += hour * 60 * 60;
00093 time += min * 60;
00094 time += sec;
00095
00096 return time;
00097 }
00098
00099
00100 static int
00101 bcd_to_bin (uint8_t x)
00102 {
00103 return (x & 0x0f) + ((x >> 4) * 10);
00104 }
00105
00106
00107
00108 static uint8_t
00109 cmos_read (uint8_t index)
00110 {
00111 outb (CMOS_REG_SET, index);
00112 return inb (CMOS_REG_IO);
00113 }