Add logic to check uninitialized RTC value in PcRtc driver in MdeModulePkg.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5281 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
xli24 2008-05-23 02:29:11 +00:00
parent bfe03264cb
commit 254ba2477f
2 changed files with 97 additions and 57 deletions

View File

@ -165,16 +165,12 @@ Returns:
Time.Month = RtcRead (RTC_ADDRESS_MONTH); Time.Month = RtcRead (RTC_ADDRESS_MONTH);
Time.Year = RtcRead (RTC_ADDRESS_YEAR); Time.Year = RtcRead (RTC_ADDRESS_YEAR);
ConvertRtcTimeToEfiTime (&Time, RegisterB);
if (RtcTestCenturyRegister () == EFI_SUCCESS) { if (RtcTestCenturyRegister () == EFI_SUCCESS) {
Century = BcdToDecimal8 ((UINT8) (RtcRead (RTC_ADDRESS_CENTURY) & 0x7f)); Century = (UINT8) (RtcRead (RTC_ADDRESS_CENTURY) & 0x7f);
} else { } else {
Century = BcdToDecimal8 (RtcRead (RTC_ADDRESS_CENTURY)); Century = RtcRead (RTC_ADDRESS_CENTURY);
} }
Time.Year = (UINT16) (Century * 100 + Time.Year);
// //
// Set RTC configuration after get original time // Set RTC configuration after get original time
// The value of bit AIE should be reserved. // The value of bit AIE should be reserved.
@ -186,13 +182,18 @@ Returns:
// //
//BugBug: the EfiAtRuntime should be encapsulated in EfiAcquireLock or //BugBug: the EfiAtRuntime should be encapsulated in EfiAcquireLock or
// provide a new instance for EfiAcquireLock, say, RtEfiAcquireLock // provide a new instance for EfiAcquireLock, say, RtEfiAcquireLock
//
if (!EfiAtRuntime ()) { if (!EfiAtRuntime ()) {
EfiReleaseLock (&Global->RtcLock); EfiReleaseLock (&Global->RtcLock);
} }
// //
// Validate time fields // Validate time fields
// //
Status = RtcTimeFieldsValid (&Time); Status = ConvertRtcTimeToEfiTime (&Time, Century, RegisterB);
if (!EFI_ERROR (Status)) {
Status = RtcTimeFieldsValid (&Time);
}
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
Time.Second = RTC_INIT_SECOND; Time.Second = RTC_INIT_SECOND;
Time.Minute = RTC_INIT_MINUTE; Time.Minute = RTC_INIT_MINUTE;
@ -295,16 +296,12 @@ Routine Description:
Time->Month = RtcRead (RTC_ADDRESS_MONTH); Time->Month = RtcRead (RTC_ADDRESS_MONTH);
Time->Year = RtcRead (RTC_ADDRESS_YEAR); Time->Year = RtcRead (RTC_ADDRESS_YEAR);
ConvertRtcTimeToEfiTime (Time, RegisterB);
if (RtcTestCenturyRegister () == EFI_SUCCESS) { if (RtcTestCenturyRegister () == EFI_SUCCESS) {
Century = BcdToDecimal8 ((UINT8) (RtcRead (RTC_ADDRESS_CENTURY) & 0x7f)); Century = (UINT8) (RtcRead (RTC_ADDRESS_CENTURY) & 0x7f);
} else { } else {
Century = BcdToDecimal8 (RtcRead (RTC_ADDRESS_CENTURY)); Century = RtcRead (RTC_ADDRESS_CENTURY);
} }
Time->Year = (UINT16) (Century * 100 + Time->Year);
// //
// Release RTC Lock. // Release RTC Lock.
// //
@ -322,7 +319,10 @@ Routine Description:
// //
// Make sure all field values are in correct range // Make sure all field values are in correct range
// //
Status = RtcTimeFieldsValid (Time); Status = ConvertRtcTimeToEfiTime (Time, Century, RegisterB);
if (!EFI_ERROR (Status)) {
Status = RtcTimeFieldsValid (Time);
}
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
@ -539,16 +539,12 @@ Returns:
Time->Year = RtcRead (RTC_ADDRESS_YEAR); Time->Year = RtcRead (RTC_ADDRESS_YEAR);
} }
ConvertRtcTimeToEfiTime (Time, RegisterB);
if (RtcTestCenturyRegister () == EFI_SUCCESS) { if (RtcTestCenturyRegister () == EFI_SUCCESS) {
Century = BcdToDecimal8 ((UINT8) (RtcRead (RTC_ADDRESS_CENTURY) & 0x7f)); Century = (UINT8) (RtcRead (RTC_ADDRESS_CENTURY) & 0x7f);
} else { } else {
Century = BcdToDecimal8 (RtcRead (RTC_ADDRESS_CENTURY)); Century = RtcRead (RTC_ADDRESS_CENTURY);
} }
Time->Year = (UINT16) (Century * 100 + Time->Year);
// //
// Release RTC Lock. // Release RTC Lock.
// //
@ -560,7 +556,10 @@ Returns:
// //
// Make sure all field values are in correct range // Make sure all field values are in correct range
// //
Status = RtcTimeFieldsValid (Time); Status = ConvertRtcTimeToEfiTime (Time, Century, RegisterB);
if (!EFI_ERROR (Status)) {
Status = RtcTimeFieldsValid (Time);
}
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
@ -719,23 +718,52 @@ Returns:
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
VOID /**
ConvertRtcTimeToEfiTime ( Checks an 8-bit BCD value, and converts to an 8-bit value if valid.
IN EFI_TIME *Time,
IN RTC_REGISTER_B RegisterB This function checks the 8-bit BCD value specified by Value.
If valid, the function converts it to an 8-bit value and returns it.
Otherwise, return 0xff.
@param Value The 8-bit BCD value to check and convert
@return The 8-bit value converted.
0xff if Value is invalid.
**/
UINT8
CheckAndConvertBcd8ToDecimal8 (
IN UINT8 Value
) )
/*++ {
if ((Value < 0xa0) && ((Value & 0xf) < 0xa)) {
return BcdToDecimal8 (Value);
}
Routine Description: return 0xff;
}
Arguments: /**
Converts time read from RTC to EFI_TIME format defined by UEFI spec.
This function converts raw time data read from RTC to the EFI_TIME format
defined by UEFI spec.
If data mode of RTC is BCD, then converts it to decimal,
If RTC is in 12-hour format, then converts it to 24-hour format.
@param Time On input, the time data read from RTC to convert
On output, the time converted to UEFI format
@param Century Value of century read from RTC.
@param RegisterB Value of Register B of RTC, indicating data mode
and hour format.
Returns: **/
--*/ EFI_STATUS
// GC_TODO: Time - add argument and description to function comment ConvertRtcTimeToEfiTime (
// GC_TODO: RegisterB - add argument and description to function comment IN OUT EFI_TIME *Time,
IN UINT8 Century,
IN RTC_REGISTER_B RegisterB
)
{ {
BOOLEAN PM; BOOLEAN PM;
@ -748,13 +776,23 @@ Returns:
Time->Hour = (UINT8) (Time->Hour & 0x7f); Time->Hour = (UINT8) (Time->Hour & 0x7f);
if (RegisterB.Bits.DM == 0) { if (RegisterB.Bits.DM == 0) {
Time->Year = BcdToDecimal8 ((UINT8) Time->Year); Time->Year = CheckAndConvertBcd8ToDecimal8 ((UINT8) Time->Year);
Time->Month = BcdToDecimal8 (Time->Month); Time->Month = CheckAndConvertBcd8ToDecimal8 (Time->Month);
Time->Day = BcdToDecimal8 (Time->Day); Time->Day = CheckAndConvertBcd8ToDecimal8 (Time->Day);
Time->Hour = BcdToDecimal8 (Time->Hour); Time->Hour = CheckAndConvertBcd8ToDecimal8 (Time->Hour);
Time->Minute = BcdToDecimal8 (Time->Minute); Time->Minute = CheckAndConvertBcd8ToDecimal8 (Time->Minute);
Time->Second = BcdToDecimal8 (Time->Second); Time->Second = CheckAndConvertBcd8ToDecimal8 (Time->Second);
Century = CheckAndConvertBcd8ToDecimal8 (Century);
} }
if (Time->Year == 0xff || Time->Month == 0xff || Time->Day == 0xff ||
Time->Hour == 0xff || Time->Minute == 0xff || Time->Second == 0xff ||
Century == 0xff) {
return EFI_INVALID_PARAMETER;
}
Time->Year = (UINT16) (Century * 100 + Time->Year);
// //
// If time is in 12 hour format, convert it to 24 hour format // If time is in 12 hour format, convert it to 24 hour format
// //
@ -771,6 +809,8 @@ Returns:
Time->Nanosecond = 0; Time->Nanosecond = 0;
Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE; Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE;
Time->Daylight = 0; Time->Daylight = 0;
return EFI_SUCCESS;
} }
EFI_STATUS EFI_STATUS

View File

@ -398,27 +398,27 @@ Returns:
--*/ --*/
; ;
VOID /**
Converts time read from RTC to EFI_TIME format defined by UEFI spec.
This function converts raw time data read from RTC to the EFI_TIME format
defined by UEFI spec.
If data mode of RTC is BCD, then converts it to decimal,
If RTC is in 12-hour format, then converts it to 24-hour format.
@param Time On input, the time data read from RTC to convert
On output, the time converted to UEFI format
@param Century Value of century read from RTC.
@param RegisterB Value of Register B of RTC, indicating data mode
and hour format.
**/
EFI_STATUS
ConvertRtcTimeToEfiTime ( ConvertRtcTimeToEfiTime (
IN EFI_TIME *Time, IN OUT EFI_TIME *Time,
IN RTC_REGISTER_B RegisterB IN UINT8 Century,
IN RTC_REGISTER_B RegisterB
) )
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
Time - GC_TODO: add argument description
RegisterB - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
; ;
EFI_STATUS EFI_STATUS