From d598e90edba94c0af4fb93defd2c2d3ab8bdfa69 Mon Sep 17 00:00:00 2001 From: evb Date: Thu, 4 Feb 2010 07:22:03 +0000 Subject: [PATCH] - Add PL031 RTC code for Versatile. - Add RTC time to TimeInfo convert. - Implement FirmWare GetTime function. Countdown in FreeLDR now working. svn path=/trunk/; revision=45414 --- reactos/boot/armllb/armllb.rbuild | 1 + reactos/boot/armllb/fw.c | 7 +- reactos/boot/armllb/hw/time.c | 91 +++++++++++++++++++++++ reactos/boot/armllb/hw/versatile/hwinfo.c | 9 +++ reactos/boot/armllb/inc/fw.h | 12 ++- reactos/boot/armllb/inc/hw.h | 13 ++++ reactos/boot/armllb/inc/precomp.h | 2 +- 7 files changed, 129 insertions(+), 6 deletions(-) create mode 100755 reactos/boot/armllb/hw/time.c diff --git a/reactos/boot/armllb/armllb.rbuild b/reactos/boot/armllb/armllb.rbuild index ea39a50c5c1..5e254c43071 100644 --- a/reactos/boot/armllb/armllb.rbuild +++ b/reactos/boot/armllb/armllb.rbuild @@ -26,6 +26,7 @@ keyboard.c serial.c + time.c video.c diff --git a/reactos/boot/armllb/fw.c b/reactos/boot/armllb/fw.c index 94350fad460..6e9ead563fc 100644 --- a/reactos/boot/armllb/fw.c +++ b/reactos/boot/armllb/fw.c @@ -171,12 +171,11 @@ LlbFwVideoSync(VOID) return; } -VOID +TIMEINFO* LlbFwGetTime(VOID) { - printf("%s is UNIMPLEMENTED", __FUNCTION__); - while (TRUE); - return; + /* Call existing function */ + return LlbGetTime(); } /* EOF */ diff --git a/reactos/boot/armllb/hw/time.c b/reactos/boot/armllb/hw/time.c new file mode 100755 index 00000000000..f37be249682 --- /dev/null +++ b/reactos/boot/armllb/hw/time.c @@ -0,0 +1,91 @@ +/* + * PROJECT: ReactOS Boot Loader + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: boot/armllb/hw/time.c + * PURPOSE: LLB Time Routines + * PROGRAMMERS: ReactOS Portable Systems Group + */ + +#include "precomp.h" + +#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) + +UCHAR LlbDaysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; +TIMEINFO LlbTime; + +BOOLEAN +NTAPI +LlbIsLeapYear(IN ULONG Year) +{ + /* Every 4, 100, or 400 years */ + return (!(Year % 4) && (Year % 100)) || !(Year % 400); +} + +ULONG +NTAPI +LlbDayOfMonth(IN ULONG Month, + IN ULONG Year) +{ + /* Check how many days a month has, accounting for leap yearS */ + return LlbDaysInMonth[Month] + (LlbIsLeapYear(Year) && Month == 1); +} + +VOID +NTAPI +LlbConvertRtcTime(IN ULONG RtcTime, + OUT TIMEINFO* TimeInfo) +{ + ULONG Month, Year, Days, DaysLeft; + + /* Count the days, keep the minutes */ + Days = RtcTime / 86400; + RtcTime -= Days * 86400; + + /* Get the year, based on days since 1970 */ + Year = 1970 + Days / 365; + + /* Account for leap years which changed the number of days/year */ + Days -= (Year - 1970) * 365 + LEAPS_THRU_END_OF(Year - 1) - LEAPS_THRU_END_OF(1970 - 1); + if (Days < 0) + { + /* We hit a leap year, so fixup the math */ + Year--; + Days += 365 + LlbIsLeapYear(Year); + } + + /* Count months */ + for (Month = 0; Month < 11; Month++) + { + /* How many days in this month? */ + DaysLeft = Days - LlbDayOfMonth(Month, Year); + if (DaysLeft < 0) break; + + /* How many days left total? */ + Days = DaysLeft; + } + + /* Write the structure */ + TimeInfo->Year = Year; + TimeInfo->Day = Days + 1; + TimeInfo->Month = Month + 1; + TimeInfo->Hour = RtcTime / 3600; + RtcTime -= TimeInfo->Hour * 3600; + TimeInfo->Minute = RtcTime / 60; + TimeInfo->Second = RtcTime - TimeInfo->Minute * 60; +} + +TIMEINFO* +NTAPI +LlbGetTime(VOID) +{ + ULONG RtcTime; + + /* Read RTC time */ + RtcTime = LlbHwRtcRead(); + + /* Convert it */ + LlbConvertRtcTime(RtcTime, &LlbTime); + return &LlbTime; +} + +/* EOF */ diff --git a/reactos/boot/armllb/hw/versatile/hwinfo.c b/reactos/boot/armllb/hw/versatile/hwinfo.c index 5c2c0b8f331..667898f17af 100755 --- a/reactos/boot/armllb/hw/versatile/hwinfo.c +++ b/reactos/boot/armllb/hw/versatile/hwinfo.c @@ -8,6 +8,9 @@ #include "precomp.h" +#define PL031_RTC_DR (LlbHwVersaRtcBase + 0x00) +static const ULONG LlbHwVersaRtcBase = 0x101E8000; + ULONG NTAPI LlbHwGetBoardType(VOID) @@ -44,4 +47,10 @@ LlbHwBuildMemoryMap(IN PBIOS_MEMORY_MAP MemoryMap) LlbAllocateMemoryEntry(BiosMemoryReserved, 0x10000000, 128 * 1024 * 1024); } +ULONG +LlbHwRtcRead(VOID) +{ + /* Read RTC value */ + return READ_REGISTER_ULONG(PL031_RTC_DR); +} /* EOF */ diff --git a/reactos/boot/armllb/inc/fw.h b/reactos/boot/armllb/inc/fw.h index 3c44c2dd47f..7bc86dd9b71 100755 --- a/reactos/boot/armllb/inc/fw.h +++ b/reactos/boot/armllb/inc/fw.h @@ -6,6 +6,16 @@ * PROGRAMMERS: ReactOS Portable Systems Group */ +typedef struct _TIMEINFO +{ + USHORT Year; + USHORT Month; + USHORT Day; + USHORT Hour; + USHORT Minute; + USHORT Second; +} TIMEINFO; + VOID LlbFwPutChar( INT Ch @@ -94,7 +104,7 @@ LlbFwVideoSync( VOID ); -VOID +TIMEINFO* LlbFwGetTime( VOID ); diff --git a/reactos/boot/armllb/inc/hw.h b/reactos/boot/armllb/inc/hw.h index 1d8ad187a4f..d82123f7fc5 100755 --- a/reactos/boot/armllb/inc/hw.h +++ b/reactos/boot/armllb/inc/hw.h @@ -104,6 +104,19 @@ LlbHwLoadOsLoaderFromRam( VOID ); +ULONG +NTAPI +LlbHwRtcRead( + VOID +); + +//fix +TIMEINFO* +NTAPI +LlbGetTime( + VOID +); + #ifdef _VERSATILE_ #include "versa.h" #elif _OMAP3_ diff --git a/reactos/boot/armllb/inc/precomp.h b/reactos/boot/armllb/inc/precomp.h index bda644bbd9a..8bd44b7801d 100755 --- a/reactos/boot/armllb/inc/precomp.h +++ b/reactos/boot/armllb/inc/precomp.h @@ -11,8 +11,8 @@ #include "ioaccess.h" #include "machtype.h" #include "osloader.h" -#include "hw.h" #include "fw.h" +#include "hw.h" #include "serial.h" #include "video.h" #include "keyboard.h"