+++ /dev/null
-/** @file\r
- Generic Capsule services\r
-\r
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
-\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include <Common/CapsuleName.h>\r
-\r
-\r
-//\r
-//Max size capsule services support are platform policy,to populate capsules we just need\r
-//memory to maintain them across reset,it is not a problem. And to special capsules ,for\r
-//example,update flash,it is mostly decided by the platform. Here is a sample size for\r
-//different type capsules.\r
-//\r
-#define MAX_SIZE_POPULATE (0)\r
-#define MAX_SIZE_NON_POPULATE (0)\r
-#define MAX_SUPPORT_CAPSULE_NUM 0x10\r
-\r
-\r
-BOOLEAN\r
-EFIAPI\r
-SupportUpdateCapsuleRest (\r
- VOID\r
- )\r
-{\r
- //\r
- //If the platform has a way to guarantee the memory integrity across a system reset, return\r
- //TRUE, else FALSE.\r
- //\r
- return FALSE;\r
-}\r
-\r
-\r
-\r
-VOID\r
-EFIAPI\r
-SupportCapsuleSize (\r
- IN OUT UINT32 *MaxSizePopulate,\r
- IN OUT UINT32 *MaxSizeNonPopulate\r
- )\r
-{\r
- //\r
- //Here is a sample size, different platforms have different sizes.\r
- //\r
- *MaxSizePopulate = MAX_SIZE_POPULATE;\r
- *MaxSizeNonPopulate = MAX_SIZE_NON_POPULATE;\r
- return;\r
-}\r
-\r
-\r
-\r
-\r
-EFI_STATUS\r
-LibUpdateCapsule (\r
- IN UEFI_CAPSULE_HEADER **CapsuleHeaderArray,\r
- IN UINTN CapsuleCount,\r
- IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This code finds if the capsule needs reset to update, if no, update immediately.\r
-\r
-Arguments:\r
-\r
- CapsuleHeaderArray A array of pointers to capsule headers passed in\r
- CapsuleCount The number of capsule\r
- ScatterGatherList Physical address of datablock list points to capsule\r
-\r
-Returns:\r
-\r
- EFI STATUS\r
- EFI_SUCCESS Valid capsule was passed.If CAPSULE_FLAG_PERSIT_ACROSS_RESET is\r
- not set, the capsule has been successfully processed by the firmware.\r
- If it set, the ScattlerGatherList is successfully to be set.\r
- EFI_INVALID_PARAMETER CapsuleCount is less than 1,CapsuleGuid is not supported.\r
- EFI_DEVICE_ERROR Failed to SetVariable or AllocatePool or ProcessFirmwareVolume.\r
-\r
---*/\r
-{\r
- UINTN CapsuleSize;\r
- UINTN ArrayNumber;\r
- VOID *BufferPtr;\r
- EFI_STATUS Status;\r
- EFI_HANDLE FvHandle;\r
- UEFI_CAPSULE_HEADER *CapsuleHeader;\r
-\r
- if ((CapsuleCount < 1) || (CapsuleCount > MAX_SUPPORT_CAPSULE_NUM)){\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- BufferPtr = NULL;\r
- CapsuleHeader = NULL;\r
-\r
- //\r
- //Compare GUIDs with EFI_CAPSULE_GUID, if capsule header contains CAPSULE_FLAGS_PERSIST_ACROSS_RESET\r
- //and CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flags,whatever the GUID is ,the service supports.\r
- //\r
- for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {\r
- CapsuleHeader = CapsuleHeaderArray[ArrayNumber];\r
- if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- if (!CompareGuid (&CapsuleHeader->CapsuleGuid, &gEfiCapsuleGuid)) {\r
- if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
- }\r
-\r
- //\r
- //Assume that capsules have the same flags on resetting or not.\r
- //\r
- CapsuleHeader = CapsuleHeaderArray[0];\r
-\r
- if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {\r
- //\r
- //Check if the platform supports update capsule across a system reset\r
- //\r
- if (!SupportUpdateCapsuleRest()) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (ScatterGatherList == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- } else {\r
- Status = EfiSetVariable (\r
- EFI_CAPSULE_VARIABLE_NAME,\r
- &gEfiCapsuleVendorGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
- sizeof (UINTN),\r
- (VOID *) &ScatterGatherList\r
- );\r
- if (Status != EFI_SUCCESS) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- //The rest occurs in the condition of non-reset mode\r
- //\r
- if (EfiAtRuntime ()) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- //Here should be in the boot-time\r
- //\r
- for (ArrayNumber = 0; ArrayNumber < CapsuleCount ; ArrayNumber++) {\r
- CapsuleHeader = CapsuleHeaderArray[ArrayNumber];\r
- CapsuleSize = CapsuleHeader->CapsuleImageSize - CapsuleHeader->HeaderSize;\r
- Status = gBS->AllocatePool (EfiBootServicesData, CapsuleSize, &BufferPtr);\r
- if (Status != EFI_SUCCESS) {\r
- goto Done;\r
- }\r
- gBS->CopyMem (BufferPtr, (UINT8*)CapsuleHeader+ CapsuleHeader->HeaderSize, CapsuleSize);\r
-\r
- //\r
- //Call DXE service ProcessFirmwareVolume to process immediatelly\r
- //\r
- Status = gDS->ProcessFirmwareVolume (BufferPtr, CapsuleSize, &FvHandle);\r
- if (Status != EFI_SUCCESS) {\r
- gBS->FreePool (BufferPtr);\r
- return EFI_DEVICE_ERROR;\r
- }\r
- gDS->Dispatch ();\r
- gBS->FreePool (BufferPtr);\r
- }\r
- return EFI_SUCCESS;\r
-\r
-Done:\r
- if (BufferPtr != NULL) {\r
- gBS->FreePool (BufferPtr);\r
- }\r
- return EFI_DEVICE_ERROR;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-QueryCapsuleCapabilities (\r
- IN UEFI_CAPSULE_HEADER **CapsuleHeaderArray,\r
- IN UINTN CapsuleCount,\r
- OUT UINT64 *MaxiumCapsuleSize,\r
- OUT EFI_RESET_TYPE *ResetType\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This code is query about capsule capability.\r
-\r
-Arguments:\r
-\r
- CapsuleHeaderArray A array of pointers to capsule headers passed in\r
- CapsuleCount The number of capsule\r
- MaxiumCapsuleSize Max capsule size is supported\r
- ResetType Reset type the capsule indicates, if reset is not needed,return EfiResetCold.\r
- If reset is needed, return EfiResetWarm.\r
-\r
-Returns:\r
-\r
- EFI STATUS\r
- EFI_SUCCESS Valid answer returned\r
- EFI_INVALID_PARAMETER MaxiumCapsuleSize is NULL,ResetType is NULL.CapsuleCount is less than 1,CapsuleGuid is not supported.\r
- EFI_UNSUPPORTED The capsule type is not supported.\r
-\r
---*/\r
-{\r
- UINTN ArrayNumber;\r
- UEFI_CAPSULE_HEADER *CapsuleHeader;\r
- UINT32 MaxSizePopulate;\r
- UINT32 MaxSizeNonPopulate;\r
-\r
-\r
- if ((CapsuleCount < 1) || (CapsuleCount > MAX_SUPPORT_CAPSULE_NUM)){\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((MaxiumCapsuleSize == NULL) ||(ResetType == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- CapsuleHeader = NULL;\r
-\r
- //\r
- //Compare GUIDs with EFI_CAPSULE_GUID, if capsule header contains CAPSULE_FLAGS_PERSIST_ACROSS_RESET\r
- //and CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flags,whatever the GUID is ,the service supports.\r
- //\r
- for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {\r
- CapsuleHeader = CapsuleHeaderArray[ArrayNumber];\r
- if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- if (!CompareGuid (&CapsuleHeader->CapsuleGuid, &gEfiCapsuleGuid)) {\r
- if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
- }\r
-\r
- SupportCapsuleSize(&MaxSizePopulate,&MaxSizeNonPopulate);\r
- //\r
- //Assume that capsules have the same flags on resetting or not.\r
- //\r
- CapsuleHeader = CapsuleHeaderArray[0];\r
- if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {\r
- //\r
- //Check if the platform supports update capsule across a system reset\r
- //\r
- if (!SupportUpdateCapsuleRest()) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- *ResetType = EfiResetWarm;\r
- *MaxiumCapsuleSize = MaxSizePopulate;\r
- } else {\r
- *ResetType = EfiResetCold;\r
- *MaxiumCapsuleSize = MaxSizeNonPopulate;\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-VOID\r
-LibCapsuleVirtualAddressChangeEvent (\r
- VOID\r
- )\r
-{\r
-}\r
-\r
-VOID\r
-LibCapsuleInitialize (\r
- VOID\r
- )\r
-{\r
-}\r
+++ /dev/null
-/** @file\r
- Generic Monotonic Counter services\r
-\r
- Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
- Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
-\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-\r
-**/\r
-\r
-\r
-//\r
-// The current Monotonic count value\r
-//\r
-UINT64 mEfiMtc = 0;\r
-\r
-\r
-//\r
-// Event to use to update the Mtc's high part when wrapping\r
-//\r
-EFI_EVENT mEfiMtcEvent;\r
-\r
-//\r
-// EfiMtcName - Variable name of the MTC value\r
-//\r
-CHAR16 *mEfiMtcName = L"MTC";\r
-\r
-//\r
-// EfiMtcGuid - Guid of the MTC value\r
-//\r
-EFI_GUID mEfiMtcGuid = { 0xeb704011, 0x1402, 0x11d3, { 0x8e, 0x77, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } };\r
-\r
-\r
-\r
-//\r
-// Worker functions\r
-//\r
-\r
-\r
-VOID\r
-EFIAPI\r
-EfiMtcEventHandler (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Monotonic count event handler. This handler updates the high monotonic count.\r
-\r
-Arguments:\r
-\r
- Event The event to handle\r
- Context The event context\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS The event has been handled properly\r
- EFI_NOT_FOUND An error occurred updating the variable.\r
-\r
---*/\r
-{\r
- UINT32 HighCount;\r
-\r
- EfiGetNextHighMonotonicCount (&HighCount);\r
- return;\r
-}\r
-\r
-\r
-\r
-VOID\r
-LibMtcVirtualAddressChangeEvent (VOID)\r
-{\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-LibMtcGetNextHighMonotonicCount (\r
- OUT UINT32 *HighCount\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_TPL OldTpl;\r
-\r
- //\r
- // Check input parameters\r
- //\r
- if (HighCount == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
-\r
- if (!EfiAtRuntime ()) {\r
- // Use a lock if called before ExitBootServices()\r
- OldTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);\r
- }\r
-\r
- *HighCount = (UINT32) RShiftU64 (mEfiMtc, 32) + 1;\r
- mEfiMtc = LShiftU64 (*HighCount, 32);\r
-\r
- if (!EfiAtRuntime ()) {\r
- gBS->RestoreTPL (OldTpl);\r
- }\r
-\r
- //\r
- // Update the NvRam store to match the new high part\r
- //\r
- Status = EfiSetVariable (\r
- mEfiMtcName,\r
- &mEfiMtcGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
- sizeof (UINT32),\r
- HighCount\r
- );\r
-\r
- return Status;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-LibMtcGetNextMonotonicCount (\r
- OUT UINT64 *Count\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_TPL OldTpl;\r
- UINT32 HighCount;\r
- UINTN BufferSize;\r
-\r
- //\r
- // Can not be called after ExitBootServices()\r
- //\r
- if (EfiAtRuntime ()) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Check input parameters\r
- //\r
- if (Count == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (mEfiMtc == 0) {\r
- //\r
- // If the MTC has not been initialized read the variable\r
- //\r
-\r
- //\r
- // Read the last high part\r
- //\r
- BufferSize = sizeof (UINT32);\r
- Status = EfiGetVariable (\r
- mEfiMtcName,\r
- &mEfiMtcGuid,\r
- NULL,\r
- &BufferSize,\r
- &HighCount\r
- );\r
- if (EFI_ERROR (Status)) {\r
- HighCount = 0;\r
- }\r
-\r
- //\r
- // Set the current value\r
- //\r
- mEfiMtc = LShiftU64 (HighCount, 32);\r
- //\r
- // Increment the upper 32 bits for this boot\r
- // Continue even if it fails. It will only fail if the variable services are\r
- // not functional.\r
- //\r
- Status = EfiGetNextHighMonotonicCount (&HighCount);\r
- }\r
-\r
-\r
- //\r
- // Update the monotonic counter with a lock\r
- //\r
- OldTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);\r
- *Count = mEfiMtc;\r
- mEfiMtc++;\r
- gBS->RestoreTPL (OldTpl);\r
-\r
- //\r
- // If the MSB bit of the low part toggled, then signal that the high\r
- // part needs updated now\r
- //\r
- if ((((UINT32) mEfiMtc) ^ ((UINT32) *Count)) & 0x80000000) {\r
- gBS->SignalEvent (mEfiMtcEvent);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-\r
-VOID\r
-LibMtcInitialize (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Initialize event to handle overflows\r
- //\r
- Status = gBS->CreateEvent (\r
- EVT_NOTIFY_SIGNAL,\r
- EFI_TPL_CALLBACK,\r
- EfiMtcEventHandler,\r
- NULL,\r
- &mEfiMtcEvent\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-}\r
-\r
+++ /dev/null
-/** @file\r
- Report status code lib on top of either SerialLib and/or EFI Serial Protocol.\r
- Based on PcdStatusCodeUseEfiSerial & PcdStatusCodeUseHardSerial settings\r
-\r
- There is just a single runtime memory buffer that contans all the data.\r
-\r
- Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
- Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-\r
-**/\r
-\r
-//////////#include "DxeStatusCode.h"\r
-\r
-\r
-EFI_SERIAL_IO_PROTOCOL *mSerialIoProtocol = NULL;\r
-\r
-\r
-EFI_STATUS\r
-LibReportStatusCode (\r
- IN EFI_STATUS_CODE_TYPE CodeType,\r
- IN EFI_STATUS_CODE_VALUE Value,\r
- IN UINT32 Instance,\r
- IN EFI_GUID *CallerId,\r
- IN EFI_STATUS_CODE_DATA *Data OPTIONAL\r
- )\r
-{\r
- CHAR8 *Filename;\r
- CHAR8 *Description;\r
- CHAR8 *Format;\r
- CHAR8 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];\r
- UINT32 ErrorLevel;\r
- UINT32 LineNumber;\r
- UINTN CharCount;\r
- VA_LIST Marker;\r
- EFI_DEBUG_INFO *DebugInfo;\r
- EFI_TPL CurrentTpl;\r
-\r
-\r
- if (FeaturePcdGet (PcdStatusCodeUseEfiSerial)) {\r
- if (EfiAtRuntime ()) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);\r
- gBS->RestoreTPL (CurrentTpl);\r
-\r
- if (CurrentTpl > EFI_TPL_CALLBACK ) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
-\r
- Buffer[0] = '\0';\r
-\r
- if (Data != NULL &&\r
- ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {\r
- //\r
- // Print ASSERT() information into output buffer.\r
- //\r
- CharCount = AsciiSPrint (\r
- Buffer,\r
- EFI_STATUS_CODE_DATA_MAX_SIZE,\r
- "\n\rDXE_ASSERT!: %a (%d): %a\n\r",\r
- Filename,\r
- LineNumber,\r
- Description\r
- );\r
- } else if (Data != NULL &&\r
- ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {\r
- //\r
- // Print DEBUG() information into output buffer.\r
- //\r
- CharCount = AsciiVSPrint (\r
- Buffer,\r
- EFI_STATUS_CODE_DATA_MAX_SIZE,\r
- Format,\r
- Marker\r
- );\r
- } else if (Data != NULL &&\r
- CompareGuid (&Data->Type, &gEfiStatusCodeSpecificDataGuid) &&\r
- (CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {\r
- //\r
- // Print specific data into output buffer.\r
- //\r
- DebugInfo = (EFI_DEBUG_INFO *) (Data + 1);\r
- Marker = (VA_LIST) (DebugInfo + 1);\r
- Format = (CHAR8 *) (((UINT64 *) (DebugInfo + 1)) + 12);\r
-\r
- CharCount = AsciiVSPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, Format, Marker);\r
- } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {\r
- //\r
- // Print ERROR information into output buffer.\r
- //\r
- CharCount = AsciiSPrint (\r
- Buffer,\r
- EFI_STATUS_CODE_DATA_MAX_SIZE,\r
- "ERROR: C%x:V%x I%x",\r
- CodeType,\r
- Value,\r
- Instance\r
- );\r
-\r
- //\r
- // Make sure we don't try to print values that weren't\r
- // intended to be printed, especially NULL GUID pointers.\r
- //\r
-\r
- if (CallerId != NULL) {\r
- CharCount += AsciiSPrint (\r
- &Buffer[CharCount - 1],\r
- (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),\r
- " %g",\r
- CallerId\r
- );\r
- }\r
-\r
- if (Data != NULL) {\r
- CharCount += AsciiSPrint (\r
- &Buffer[CharCount - 1],\r
- (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),\r
- " %x",\r
- Data\r
- );\r
- }\r
-\r
- CharCount += AsciiSPrint (\r
- &Buffer[CharCount - 1],\r
- (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),\r
- "\n\r"\r
- );\r
- } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {\r
- CharCount = AsciiSPrint (\r
- Buffer,\r
- EFI_STATUS_CODE_DATA_MAX_SIZE,\r
- "PROGRESS CODE: V%x I%x\n\r",\r
- Value,\r
- Instance\r
- );\r
- } else {\r
- CharCount = AsciiSPrint (\r
- Buffer,\r
- EFI_STATUS_CODE_DATA_MAX_SIZE,\r
- "Undefined: C%x:V%x I%x\n\r",\r
- CodeType,\r
- Value,\r
- Instance\r
- );\r
- }\r
-\r
-\r
- if (FeaturePcdGet (PcdStatusCodeUseHardSerial)) {\r
- //\r
- // Callout to SerialPort Lib function to do print.\r
- //\r
- SerialPortWrite ((UINT8 *) Buffer, CharCount);\r
- }\r
- if (FeaturePcdGet (PcdStatusCodeUseEfiSerial)) {\r
- if (mSerialIoProtocol == NULL) {\r
- gBS->LocateProtocol (&gEfiSerialIoProtocolGuid, NULL, (VOID **) &mSerialIoProtocol);\r
- }\r
-\r
- if (mSerialIoProtocol == NULL) {\r
- mSerialIoProtocol->Write (\r
- mSerialIoProtocol,\r
- &CharCount,\r
- Buffer\r
- );\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-VOID\r
-LibReportStatusCodeVirtualAddressChangeEvent (\r
- VOID\r
- )\r
-{\r
- return;\r
-}\r
-\r
-VOID\r
-LibReportStatusCodeInitialize (\r
- VOID\r
- )\r
-{\r
- return;\r
-}\r
-\r
-\r
-\r
+++ /dev/null
-/** @file\r
- Simple PC Port 0x92 reset driver\r
-\r
- Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
- Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
-\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-\r
-**/\r
-\r
-\r
-\r
-VOID\r
-LibResetInitializeReset (\r
- VOID\r
- )\r
-{\r
-}\r
-\r
-VOID\r
-LibResetVirtualAddressChangeEvent (\r
- VOID\r
- )\r
-{\r
-}\r
-\r
-\r
-VOID\r
-LibResetSystem (\r
- IN EFI_RESET_TYPE ResetType,\r
- IN EFI_STATUS ResetStatus,\r
- IN UINTN DataSize,\r
- IN CHAR16 *ResetData OPTIONAL\r
- )\r
-{\r
- UINT8 Data;\r
-\r
- switch (ResetType) {\r
- case EfiResetWarm:\r
- case EfiResetCold:\r
- case EfiResetShutdown:\r
- Data = IoRead8 (0x92);\r
- Data |= 1;\r
- IoWrite8 (0x92, Data);\r
- break;\r
-\r
- default:\r
- return ;\r
- }\r
-\r
- //\r
- // Given we should have reset getting here would be bad\r
- //\r
- ASSERT (FALSE);\r
-}\r
-\r
+++ /dev/null
-/** @file\r
- Simple PC RTC\r
-\r
- Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
- Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
- Copyright (c) 2014, ARM Ltd. All rights reserved.\r
-\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-\r
-**/\r
-\r
-\r
-\r
-typedef struct {\r
- EFI_LOCK RtcLock;\r
- UINT16 SavedTimeZone;\r
- UINT8 Daylight;\r
-} PC_RTC_GLOBALS;\r
-\r
-#define PCAT_RTC_ADDRESS_REGISTER 0x70\r
-#define PCAT_RTC_DATA_REGISTER 0x71\r
-\r
-//\r
-// Dallas DS12C887 Real Time Clock\r
-//\r
-#define RTC_ADDRESS_SECONDS 0 // R/W Range 0..59\r
-#define RTC_ADDRESS_SECONDS_ALARM 1 // R/W Range 0..59\r
-#define RTC_ADDRESS_MINUTES 2 // R/W Range 0..59\r
-#define RTC_ADDRESS_MINUTES_ALARM 3 // R/W Range 0..59\r
-#define RTC_ADDRESS_HOURS 4 // R/W Range 1..12 or 0..23 Bit 7 is AM/PM\r
-#define RTC_ADDRESS_HOURS_ALARM 5 // R/W Range 1..12 or 0..23 Bit 7 is AM/PM\r
-#define RTC_ADDRESS_DAY_OF_THE_WEEK 6 // R/W Range 1..7\r
-#define RTC_ADDRESS_DAY_OF_THE_MONTH 7 // R/W Range 1..31\r
-#define RTC_ADDRESS_MONTH 8 // R/W Range 1..12\r
-#define RTC_ADDRESS_YEAR 9 // R/W Range 0..99\r
-#define RTC_ADDRESS_REGISTER_A 10 // R/W[0..6] R0[7]\r
-#define RTC_ADDRESS_REGISTER_B 11 // R/W\r
-#define RTC_ADDRESS_REGISTER_C 12 // RO\r
-#define RTC_ADDRESS_REGISTER_D 13 // RO\r
-#define RTC_ADDRESS_CENTURY 50 // R/W Range 19..20 Bit 8 is R/W\r
-//\r
-// Date and time initial values.\r
-// They are used if the RTC values are invalid during driver initialization\r
-//\r
-#define RTC_INIT_SECOND 0\r
-#define RTC_INIT_MINUTE 0\r
-#define RTC_INIT_HOUR 0\r
-#define RTC_INIT_DAY 1\r
-#define RTC_INIT_MONTH 1\r
-#define RTC_INIT_YEAR 2001\r
-\r
-//\r
-// Register initial values\r
-//\r
-#define RTC_INIT_REGISTER_A 0x26\r
-#define RTC_INIT_REGISTER_B 0x02\r
-#define RTC_INIT_REGISTER_D 0x0\r
-\r
-#pragma pack(1)\r
-//\r
-// Register A\r
-//\r
-typedef struct {\r
- UINT8 RS : 4; // Rate Selection Bits\r
- UINT8 DV : 3; // Divisor\r
- UINT8 UIP : 1; // Update in progress\r
-} RTC_REGISTER_A_BITS;\r
-\r
-typedef union {\r
- RTC_REGISTER_A_BITS Bits;\r
- UINT8 Data;\r
-} RTC_REGISTER_A;\r
-\r
-//\r
-// Register B\r
-//\r
-typedef struct {\r
- UINT8 DSE : 1; // 0 - Daylight saving disabled 1 - Daylight savings enabled\r
- UINT8 MIL : 1; // 0 - 12 hour mode 1 - 24 hour mode\r
- UINT8 DM : 1; // 0 - BCD Format 1 - Binary Format\r
- UINT8 SQWE : 1; // 0 - Disable SQWE output 1 - Enable SQWE output\r
- UINT8 UIE : 1; // 0 - Update INT disabled 1 - Update INT enabled\r
- UINT8 AIE : 1; // 0 - Alarm INT disabled 1 - Alarm INT Enabled\r
- UINT8 PIE : 1; // 0 - Periodic INT disabled 1 - Periodic INT Enabled\r
- UINT8 SET : 1; // 0 - Normal operation. 1 - Updates inhibited\r
-} RTC_REGISTER_B_BITS;\r
-\r
-typedef union {\r
- RTC_REGISTER_B_BITS Bits;\r
- UINT8 Data;\r
-} RTC_REGISTER_B;\r
-\r
-//\r
-// Register C\r
-//\r
-typedef struct {\r
- UINT8 Reserved : 4; // Read as zero. Can not be written.\r
- UINT8 UF : 1; // Update End Interrupt Flag\r
- UINT8 AF : 1; // Alarm Interrupt Flag\r
- UINT8 PF : 1; // Periodic Interrupt Flag\r
- UINT8 IRQF : 1; // Iterrupt Request Flag = PF & PIE | AF & AIE | UF & UIE\r
-} RTC_REGISTER_C_BITS;\r
-\r
-typedef union {\r
- RTC_REGISTER_C_BITS Bits;\r
- UINT8 Data;\r
-} RTC_REGISTER_C;\r
-\r
-//\r
-// Register D\r
-//\r
-typedef struct {\r
- UINT8 Reserved : 7; // Read as zero. Can not be written.\r
- UINT8 VRT : 1; // Valid RAM and Time\r
-} RTC_REGISTER_D_BITS;\r
-\r
-typedef union {\r
- RTC_REGISTER_D_BITS Bits;\r
- UINT8 Data;\r
-} RTC_REGISTER_D;\r
-\r
-#pragma pack()\r
-\r
-PC_RTC_GLOBALS mRtc;\r
-\r
-BOOLEAN\r
-IsLeapYear (\r
- IN EFI_TIME *Time\r
- )\r
-{\r
- if (Time->Year % 4 == 0) {\r
- if (Time->Year % 100 == 0) {\r
- if (Time->Year % 400 == 0) {\r
- return TRUE;\r
- } else {\r
- return FALSE;\r
- }\r
- } else {\r
- return TRUE;\r
- }\r
- } else {\r
- return FALSE;\r
- }\r
-}\r
-\r
-\r
-const INTN mDayOfMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };\r
-\r
-BOOLEAN\r
-DayValid (\r
- IN EFI_TIME *Time\r
- )\r
-{\r
- if (Time->Day < 1 ||\r
- Time->Day > mDayOfMonth[Time->Month - 1] ||\r
- (Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28))\r
- ) {\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-\r
-UINT8\r
-DecimaltoBcd (\r
- IN UINT8 DecValue\r
- )\r
-{\r
- UINTN High;\r
- UINTN Low;\r
-\r
- High = DecValue / 10;\r
- Low = DecValue - (High * 10);\r
-\r
- return (UINT8) (Low + (High << 4));\r
-}\r
-\r
-UINT8\r
-BcdToDecimal (\r
- IN UINT8 BcdValue\r
- )\r
-{\r
- UINTN High;\r
- UINTN Low;\r
-\r
- High = BcdValue >> 4;\r
- Low = BcdValue - (High << 4);\r
-\r
- return (UINT8) (Low + (High * 10));\r
-}\r
-\r
-\r
-\r
-\r
-VOID\r
-ConvertEfiTimeToRtcTime (\r
- IN EFI_TIME *Time,\r
- IN RTC_REGISTER_B RegisterB,\r
- IN UINT8 *Century\r
- )\r
-{\r
- BOOLEAN PM;\r
-\r
- PM = TRUE;\r
- //\r
- // Adjust hour field if RTC in in 12 hour mode\r
- //\r
- if (RegisterB.Bits.MIL == 0) {\r
- if (Time->Hour < 12) {\r
- PM = FALSE;\r
- }\r
-\r
- if (Time->Hour >= 13) {\r
- Time->Hour = (UINT8) (Time->Hour - 12);\r
- } else if (Time->Hour == 0) {\r
- Time->Hour = 12;\r
- }\r
- }\r
- //\r
- // Set the Time/Date/Daylight Savings values.\r
- //\r
- *Century = DecimaltoBcd ((UINT8) (Time->Year / 100));\r
-\r
- Time->Year = (UINT16) (Time->Year % 100);\r
-\r
- if (RegisterB.Bits.DM == 0) {\r
- Time->Year = DecimaltoBcd ((UINT8) Time->Year);\r
- Time->Month = DecimaltoBcd (Time->Month);\r
- Time->Day = DecimaltoBcd (Time->Day);\r
- Time->Hour = DecimaltoBcd (Time->Hour);\r
- Time->Minute = DecimaltoBcd (Time->Minute);\r
- Time->Second = DecimaltoBcd (Time->Second);\r
- }\r
- //\r
- // If we are in 12 hour mode and PM is set, then set bit 7 of the Hour field.\r
- //\r
- if (RegisterB.Bits.MIL == 0 && PM) {\r
- Time->Hour = (UINT8) (Time->Hour | 0x80);\r
- }\r
-}\r
-\r
-/**\r
- Check the validity of all the fields of a data structure of type EFI_TIME\r
-\r
- @param[in] Time Pointer to a data structure of type EFI_TIME that defines a date and time\r
-\r
- @retval EFI_SUCCESS All date and time fields are valid\r
- @retval EFI_INVALID_PARAMETER At least one date or time field is not valid\r
-**/\r
-EFI_STATUS\r
-RtcTimeFieldsValid (\r
- IN EFI_TIME *Time\r
- )\r
-{\r
- if ((Time->Year < 1998 ) ||\r
- (Time->Year > 2099 ) ||\r
- (Time->Month < 1 ) ||\r
- (Time->Month > 12 ) ||\r
- (!DayValid (Time)) ||\r
- (Time->Hour > 23 ) ||\r
- (Time->Minute > 59 ) ||\r
- (Time->Second > 59 ) ||\r
- (Time->Nanosecond > 999999999) ||\r
- ((Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) &&\r
- ((Time->TimeZone < -1440) ||\r
- (Time->TimeZone > 1440 ) ) ) ||\r
- (Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT |\r
- EFI_TIME_IN_DAYLIGHT )))\r
- ) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-UINT8\r
-RtcRead (\r
- IN UINT8 Address\r
- )\r
-{\r
- IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, (UINT8) (Address | (UINT8) (IoRead8 (PCAT_RTC_ADDRESS_REGISTER) & 0x80)));\r
- return IoRead8 (PCAT_RTC_DATA_REGISTER);\r
-}\r
-\r
-VOID\r
-RtcWrite (\r
- IN UINT8 Address,\r
- IN UINT8 Data\r
- )\r
-{\r
- IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, (UINT8) (Address | (UINT8) (IoRead8 (PCAT_RTC_ADDRESS_REGISTER) & 0x80)));\r
- IoWrite8 (PCAT_RTC_DATA_REGISTER, Data);\r
-}\r
-\r
-\r
-EFI_STATUS\r
-RtcTestCenturyRegister (\r
- VOID\r
- )\r
-{\r
- UINT8 Century;\r
- UINT8 Temp;\r
-\r
- Century = RtcRead (RTC_ADDRESS_CENTURY);\r
- //\r
- // RtcWrite (RTC_ADDRESS_CENTURY, 0x00);\r
- //\r
- Temp = (UINT8) (RtcRead (RTC_ADDRESS_CENTURY) & 0x7f);\r
- RtcWrite (RTC_ADDRESS_CENTURY, Century);\r
- if (Temp == 0x19 || Temp == 0x20) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- return EFI_DEVICE_ERROR;\r
-}\r
-\r
-VOID\r
-ConvertRtcTimeToEfiTime (\r
- IN EFI_TIME *Time,\r
- IN RTC_REGISTER_B RegisterB\r
- )\r
-{\r
- BOOLEAN PM;\r
-\r
- if ((Time->Hour) & 0x80) {\r
- PM = TRUE;\r
- } else {\r
- PM = FALSE;\r
- }\r
-\r
- Time->Hour = (UINT8) (Time->Hour & 0x7f);\r
-\r
- if (RegisterB.Bits.DM == 0) {\r
- Time->Year = BcdToDecimal ((UINT8) Time->Year);\r
- Time->Month = BcdToDecimal (Time->Month);\r
- Time->Day = BcdToDecimal (Time->Day);\r
- Time->Hour = BcdToDecimal (Time->Hour);\r
- Time->Minute = BcdToDecimal (Time->Minute);\r
- Time->Second = BcdToDecimal (Time->Second);\r
- }\r
- //\r
- // If time is in 12 hour format, convert it to 24 hour format\r
- //\r
- if (RegisterB.Bits.MIL == 0) {\r
- if (PM && Time->Hour < 12) {\r
- Time->Hour = (UINT8) (Time->Hour + 12);\r
- }\r
-\r
- if (!PM && Time->Hour == 12) {\r
- Time->Hour = 0;\r
- }\r
- }\r
-\r
- Time->Nanosecond = 0;\r
- Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE;\r
- Time->Daylight = 0;\r
-}\r
-\r
-EFI_STATUS\r
-RtcWaitToUpdate (\r
- UINTN Timeout\r
- )\r
-{\r
- RTC_REGISTER_A RegisterA;\r
- RTC_REGISTER_D RegisterD;\r
-\r
- //\r
- // See if the RTC is functioning correctly\r
- //\r
- RegisterD.Data = RtcRead (RTC_ADDRESS_REGISTER_D);\r
-\r
- if (RegisterD.Bits.VRT == 0) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Wait for up to 0.1 seconds for the RTC to be ready.\r
- //\r
- Timeout = (Timeout / 10) + 1;\r
- RegisterA.Data = RtcRead (RTC_ADDRESS_REGISTER_A);\r
- while (RegisterA.Bits.UIP == 1 && Timeout > 0) {\r
- MicroSecondDelay (10);\r
- RegisterA.Data = RtcRead (RTC_ADDRESS_REGISTER_A);\r
- Timeout--;\r
- }\r
-\r
- RegisterD.Data = RtcRead (RTC_ADDRESS_REGISTER_D);\r
- if (Timeout == 0 || RegisterD.Bits.VRT == 0) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-LibGetTime (\r
- OUT EFI_TIME *Time,\r
- OUT EFI_TIME_CAPABILITIES *Capabilities\r
- )\r
-{\r
- EFI_STATUS Status;\r
- RTC_REGISTER_B RegisterB;\r
- UINT8 Century;\r
- UINTN BufferSize;\r
-\r
- //\r
- // Check parameters for null pointer\r
- //\r
- if (Time == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
-\r
- }\r
- //\r
- // Acquire RTC Lock to make access to RTC atomic\r
- //\r
- EfiAcquireLock (&mRtc.RtcLock);\r
-\r
- //\r
- // Wait for up to 0.1 seconds for the RTC to be updated\r
- //\r
- Status = RtcWaitToUpdate (100000);\r
- if (EFI_ERROR (Status)) {\r
- EfiReleaseLock (&mRtc.RtcLock);\r
- return Status;\r
- }\r
- //\r
- // Read Register B\r
- //\r
- RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);\r
-\r
- //\r
- // Get the Time/Date/Daylight Savings values.\r
- //\r
- Time->Second = RtcRead (RTC_ADDRESS_SECONDS);\r
- Time->Minute = RtcRead (RTC_ADDRESS_MINUTES);\r
- Time->Hour = RtcRead (RTC_ADDRESS_HOURS);\r
- Time->Day = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);\r
- Time->Month = RtcRead (RTC_ADDRESS_MONTH);\r
- Time->Year = RtcRead (RTC_ADDRESS_YEAR);\r
-\r
- ConvertRtcTimeToEfiTime (Time, RegisterB);\r
-\r
- if (RtcTestCenturyRegister () == EFI_SUCCESS) {\r
- Century = BcdToDecimal ((UINT8) (RtcRead (RTC_ADDRESS_CENTURY) & 0x7f));\r
- } else {\r
- Century = BcdToDecimal (RtcRead (RTC_ADDRESS_CENTURY));\r
- }\r
-\r
- Time->Year = (UINT16) (Century * 100 + Time->Year);\r
-\r
- //\r
- // Release RTC Lock.\r
- //\r
- EfiReleaseLock (&mRtc.RtcLock);\r
-\r
- //\r
- // Get the variable that containts the TimeZone and Daylight fields\r
- //\r
- Time->TimeZone = mRtc.SavedTimeZone;\r
- Time->Daylight = mRtc.Daylight;\r
-\r
- BufferSize = sizeof (INT16) + sizeof (UINT8);\r
-\r
- //\r
- // Make sure all field values are in correct range\r
- //\r
- Status = RtcTimeFieldsValid (Time);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Fill in Capabilities if it was passed in\r
- //\r
- if (Capabilities) {\r
- Capabilities->Resolution = 1;\r
- //\r
- // 1 hertz\r
- //\r
- Capabilities->Accuracy = 50000000;\r
- //\r
- // 50 ppm\r
- //\r
- Capabilities->SetsToZero = FALSE;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-\r
-EFI_STATUS\r
-LibSetTime (\r
- IN EFI_TIME *Time\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_TIME RtcTime;\r
- RTC_REGISTER_B RegisterB;\r
- UINT8 Century;\r
-\r
- if (Time == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Make sure that the time fields are valid\r
- //\r
- Status = RtcTimeFieldsValid (Time);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- CopyMem (&RtcTime, Time, sizeof (EFI_TIME));\r
-\r
- //\r
- // Acquire RTC Lock to make access to RTC atomic\r
- //\r
- EfiAcquireLock (&mRtc.RtcLock);\r
-\r
- //\r
- // Wait for up to 0.1 seconds for the RTC to be updated\r
- //\r
- Status = RtcWaitToUpdate (100000);\r
- if (EFI_ERROR (Status)) {\r
- EfiReleaseLock (&mRtc.RtcLock);\r
- return Status;\r
- }\r
- //\r
- // Read Register B, and inhibit updates of the RTC\r
- //\r
- RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);\r
- RegisterB.Bits.SET = 1;\r
- RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);\r
-\r
- ConvertEfiTimeToRtcTime (&RtcTime, RegisterB, &Century);\r
-\r
- RtcWrite (RTC_ADDRESS_SECONDS, RtcTime.Second);\r
- RtcWrite (RTC_ADDRESS_MINUTES, RtcTime.Minute);\r
- RtcWrite (RTC_ADDRESS_HOURS, RtcTime.Hour);\r
- RtcWrite (RTC_ADDRESS_DAY_OF_THE_MONTH, RtcTime.Day);\r
- RtcWrite (RTC_ADDRESS_MONTH, RtcTime.Month);\r
- RtcWrite (RTC_ADDRESS_YEAR, (UINT8) RtcTime.Year);\r
- if (RtcTestCenturyRegister () == EFI_SUCCESS) {\r
- Century = (UINT8) ((Century & 0x7f) | (RtcRead (RTC_ADDRESS_CENTURY) & 0x80));\r
- }\r
-\r
- RtcWrite (RTC_ADDRESS_CENTURY, Century);\r
-\r
- //\r
- // Allow updates of the RTC registers\r
- //\r
- RegisterB.Bits.SET = 0;\r
- RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);\r
-\r
- //\r
- // Release RTC Lock.\r
- //\r
- EfiReleaseLock (&mRtc.RtcLock);\r
-\r
- //\r
- // Set the variable that containts the TimeZone and Daylight fields\r
- //\r
- mRtc.SavedTimeZone = Time->TimeZone;\r
- mRtc.Daylight = Time->Daylight;\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-libGetWakeupTime (\r
- OUT BOOLEAN *Enabled,\r
- OUT BOOLEAN *Pending,\r
- OUT EFI_TIME *Time\r
- )\r
-{\r
- EFI_STATUS Status;\r
- RTC_REGISTER_B RegisterB;\r
- RTC_REGISTER_C RegisterC;\r
- UINT8 Century;\r
-\r
- //\r
- // Check parameters for null pointers\r
- //\r
- if ((Enabled == NULL) || (Pending == NULL) || (Time == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
-\r
- }\r
- //\r
- // Acquire RTC Lock to make access to RTC atomic\r
- //\r
- EfiAcquireLock (&mRtc.RtcLock);\r
-\r
- //\r
- // Wait for up to 0.1 seconds for the RTC to be updated\r
- //\r
- Status = RtcWaitToUpdate (100000);\r
- if (EFI_ERROR (Status)) {\r
- EfiReleaseLock (&mRtc.RtcLock);\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Read Register B and Register C\r
- //\r
- RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);\r
- RegisterC.Data = RtcRead (RTC_ADDRESS_REGISTER_C);\r
-\r
- //\r
- // Get the Time/Date/Daylight Savings values.\r
- //\r
- *Enabled = RegisterB.Bits.AIE;\r
- if (*Enabled) {\r
- Time->Second = RtcRead (RTC_ADDRESS_SECONDS_ALARM);\r
- Time->Minute = RtcRead (RTC_ADDRESS_MINUTES_ALARM);\r
- Time->Hour = RtcRead (RTC_ADDRESS_HOURS_ALARM);\r
- Time->Day = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);\r
- Time->Month = RtcRead (RTC_ADDRESS_MONTH);\r
- Time->Year = RtcRead (RTC_ADDRESS_YEAR);\r
- } else {\r
- Time->Second = 0;\r
- Time->Minute = 0;\r
- Time->Hour = 0;\r
- Time->Day = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);\r
- Time->Month = RtcRead (RTC_ADDRESS_MONTH);\r
- Time->Year = RtcRead (RTC_ADDRESS_YEAR);\r
- }\r
-\r
- ConvertRtcTimeToEfiTime (Time, RegisterB);\r
-\r
- if (RtcTestCenturyRegister () == EFI_SUCCESS) {\r
- Century = BcdToDecimal ((UINT8) (RtcRead (RTC_ADDRESS_CENTURY) & 0x7f));\r
- } else {\r
- Century = BcdToDecimal (RtcRead (RTC_ADDRESS_CENTURY));\r
- }\r
-\r
- Time->Year = (UINT16) (Century * 100 + Time->Year);\r
-\r
- //\r
- // Release RTC Lock.\r
- //\r
- EfiReleaseLock (&mRtc.RtcLock);\r
-\r
- //\r
- // Make sure all field values are in correct range\r
- //\r
- Status = RtcTimeFieldsValid (Time);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- *Pending = RegisterC.Bits.AF;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-LibSetWakeupTime (\r
- IN BOOLEAN Enabled,\r
- OUT EFI_TIME *Time\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_TIME RtcTime;\r
- RTC_REGISTER_B RegisterB;\r
- UINT8 Century;\r
- EFI_TIME_CAPABILITIES Capabilities;\r
-\r
- if (Enabled) {\r
-\r
- if (Time == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Make sure that the time fields are valid\r
- //\r
- Status = RtcTimeFieldsValid (Time);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Just support set alarm time within 24 hours\r
- //\r
- LibGetTime (&RtcTime, &Capabilities);\r
- if (Time->Year != RtcTime.Year ||\r
- Time->Month != RtcTime.Month ||\r
- (Time->Day != RtcTime.Day && Time->Day != (RtcTime.Day + 1))\r
- ) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- //\r
- // Make a local copy of the time and date\r
- //\r
- CopyMem (&RtcTime, Time, sizeof (EFI_TIME));\r
-\r
- }\r
- //\r
- // Acquire RTC Lock to make access to RTC atomic\r
- //\r
- EfiAcquireLock (&mRtc.RtcLock);\r
-\r
- //\r
- // Wait for up to 0.1 seconds for the RTC to be updated\r
- //\r
- Status = RtcWaitToUpdate (100000);\r
- if (EFI_ERROR (Status)) {\r
- EfiReleaseLock (&mRtc.RtcLock);\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Read Register B, and inhibit updates of the RTC\r
- //\r
- RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);\r
-\r
- RegisterB.Bits.SET = 1;\r
- RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);\r
-\r
- if (Enabled) {\r
- ConvertEfiTimeToRtcTime (&RtcTime, RegisterB, &Century);\r
-\r
- //\r
- // Set RTC alarm time\r
- //\r
- RtcWrite (RTC_ADDRESS_SECONDS_ALARM, RtcTime.Second);\r
- RtcWrite (RTC_ADDRESS_MINUTES_ALARM, RtcTime.Minute);\r
- RtcWrite (RTC_ADDRESS_HOURS_ALARM, RtcTime.Hour);\r
-\r
- RegisterB.Bits.AIE = 1;\r
-\r
- } else {\r
- RegisterB.Bits.AIE = 0;\r
- }\r
- //\r
- // Allow updates of the RTC registers\r
- //\r
- RegisterB.Bits.SET = 0;\r
- RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);\r
-\r
- //\r
- // Release RTC Lock.\r
- //\r
- EfiReleaseLock (&mRtc.RtcLock);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-\r
-VOID\r
-LibRtcVirtualAddressChangeEvent (\r
- VOID\r
- )\r
-{\r
-}\r
-\r
-\r
-VOID\r
-LibRtcInitialize (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- RTC_REGISTER_A RegisterA;\r
- RTC_REGISTER_B RegisterB;\r
- RTC_REGISTER_C RegisterC;\r
- RTC_REGISTER_D RegisterD;\r
- UINT8 Century;\r
- EFI_TIME Time;\r
-\r
- //\r
- // Acquire RTC Lock to make access to RTC atomic\r
- //\r
- EfiAcquireLock (&mRtc.RtcLock);\r
-\r
- //\r
- // Initialize RTC Register\r
- //\r
- // Make sure Division Chain is properly configured,\r
- // or RTC clock won't "tick" -- time won't increment\r
- //\r
- RegisterA.Data = RTC_INIT_REGISTER_A;\r
- RtcWrite (RTC_ADDRESS_REGISTER_A, RegisterA.Data);\r
-\r
- //\r
- // Read Register B\r
- //\r
- RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);\r
-\r
- //\r
- // Clear RTC flag register\r
- //\r
- RegisterC.Data = RtcRead (RTC_ADDRESS_REGISTER_C);\r
-\r
- //\r
- // Clear RTC register D\r
- //\r
- RegisterD.Data = RTC_INIT_REGISTER_D;\r
- RtcWrite (RTC_ADDRESS_REGISTER_D, RegisterD.Data);\r
-\r
- //\r
- // Wait for up to 0.1 seconds for the RTC to be updated\r
- //\r
- Status = RtcWaitToUpdate (100000);\r
- if (EFI_ERROR (Status)) {\r
- EfiReleaseLock (&mRtc.RtcLock);\r
- return;\r
- }\r
-\r
- //\r
- // Get the Time/Date/Daylight Savings values.\r
- //\r
- Time.Second = RtcRead (RTC_ADDRESS_SECONDS);\r
- Time.Minute = RtcRead (RTC_ADDRESS_MINUTES);\r
- Time.Hour = RtcRead (RTC_ADDRESS_HOURS);\r
- Time.Day = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);\r
- Time.Month = RtcRead (RTC_ADDRESS_MONTH);\r
- Time.Year = RtcRead (RTC_ADDRESS_YEAR);\r
-\r
- ConvertRtcTimeToEfiTime (&Time, RegisterB);\r
-\r
- if (RtcTestCenturyRegister () == EFI_SUCCESS) {\r
- Century = BcdToDecimal ((UINT8) (RtcRead (RTC_ADDRESS_CENTURY) & 0x7f));\r
- } else {\r
- Century = BcdToDecimal (RtcRead (RTC_ADDRESS_CENTURY));\r
- }\r
-\r
- Time.Year = (UINT16) (Century * 100 + Time.Year);\r
-\r
- //\r
- // Set RTC configuration after get original time\r
- //\r
- RtcWrite (RTC_ADDRESS_REGISTER_B, RTC_INIT_REGISTER_B);\r
-\r
- //\r
- // Release RTC Lock.\r
- //\r
- EfiReleaseLock (&mRtc.RtcLock);\r
-\r
- //\r
- // Validate time fields\r
- //\r
- Status = RtcTimeFieldsValid (&Time);\r
- if (EFI_ERROR (Status)) {\r
- Time.Second = RTC_INIT_SECOND;\r
- Time.Minute = RTC_INIT_MINUTE;\r
- Time.Hour = RTC_INIT_HOUR;\r
- Time.Day = RTC_INIT_DAY;\r
- Time.Month = RTC_INIT_MONTH;\r
- Time.Year = RTC_INIT_YEAR;\r
- }\r
- //\r
- // Reset time value according to new RTC configuration\r
- //\r
- LibSetTime (&Time);\r
-\r
- return;\r
-}\r
-\r
-\r
+++ /dev/null
-/** @file\r
- Variable services implemented from system memory\r
-\r
- There is just a single runtime memory buffer that contans all the data.\r
-\r
- Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
- Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
-\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-\r
-**/\r
-\r
-\r
-UINT64 mMaximumVariableStorageSize;\r
-UINT64 mRemainingVariableStorageSize;\r
-UINT64 mMaximumVariableSize;\r
-\r
-typedef struct {\r
- EFI_GUID VendorGuid;\r
- UINT32 Attribute;\r
- UINTN DataSize;\r
-} VARIABLE_ARRAY_ENTRY;\r
-// CHAR16 VariableName[]\r
-// UINT8 Data[]\r
-\r
-VARIABLE_ARRAY_ENTRY *mVariableArray = NULL;\r
-VARIABLE_ARRAY_ENTRY *mVariableArrayNextFree = NULL;\r
-VARIABLE_ARRAY_ENTRY *mVariableArrayEnd = NULL;\r
-\r
-\r
-VARIABLE_ARRAY_ENTRY *\r
-AddEntry (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN UINT32 Attributes,\r
- IN UINTN DataSize,\r
- IN VOID *Data\r
- )\r
-{\r
- UINTN Size;\r
- UINTN SizeOfString;\r
- VARIABLE_ARRAY_ENTRY *Entry;\r
- EFI_TPL CurrentTpl;\r
-\r
-\r
- SizeOfString = StrSize (VariableName);\r
- Size = SizeOfString + sizeof (VARIABLE_ARRAY_ENTRY) + DataSize;\r
- if ((VARIABLE_ARRAY_ENTRY *)(((UINT8 *)mVariableArrayNextFree) + Size) > mVariableArrayEnd) {\r
- // ran out of space\r
- return NULL;\r
- }\r
-\r
- if (!EfiAtRuntime ()) {\r
- // Enter critical section\r
- CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);\r
- }\r
-\r
- Entry = mVariableArrayNextFree;\r
- CopyGuid (&Entry->VendorGuid, VendorGuid);\r
- Entry->Attribute = Attributes;\r
- Entry->DataSize = DataSize;\r
- StrCpy ((CHAR16 *)++mVariableArrayNextFree, VariableName);\r
- mVariableArrayNextFree = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)mVariableArrayNextFree) + SizeOfString);\r
- CopyMem (mVariableArrayNextFree, Data, DataSize);\r
- mVariableArrayNextFree = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)mVariableArrayNextFree) + DataSize);\r
-\r
- if (!EfiAtRuntime ()) {\r
- // Exit Critical section\r
- gBS->RestoreTPL (CurrentTpl);\r
- }\r
-\r
- return Entry;\r
-}\r
-\r
-VOID\r
-DeleteEntry (\r
- IN VARIABLE_ARRAY_ENTRY *Entry\r
- )\r
-{\r
- UINTN Size;\r
- UINT8 *Data;\r
- EFI_TPL CurrentTpl;\r
-\r
- Size = StrSize ((CHAR16 *)(Entry + 1)) + sizeof (VARIABLE_ARRAY_ENTRY) + Entry->DataSize;\r
- Data = ((UINT8 *)Entry) + Size;\r
-\r
- CopyMem (Entry, Data, (UINTN)mVariableArrayNextFree - (UINTN)Data);\r
-\r
- if (!EfiAtRuntime ()) {\r
- // Enter critical section\r
- CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);\r
- }\r
-\r
- mVariableArrayNextFree = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)mVariableArrayNextFree) - Size);\r
-\r
- if (!EfiAtRuntime ()) {\r
- // Exit Critical section\r
- gBS->RestoreTPL (CurrentTpl);\r
- }\r
-}\r
-\r
-\r
-VARIABLE_ARRAY_ENTRY *\r
-GetVariableArrayEntry (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- OUT VOID **Data OPTIONAL\r
- )\r
-{\r
- VARIABLE_ARRAY_ENTRY *Entry;\r
- UINTN Size;\r
-\r
- if (*VariableName == L'\0') {\r
- // by definition first entry is null-terminated string\r
- if (mVariableArray == mVariableArrayNextFree) {\r
- return NULL;\r
- }\r
- return mVariableArray;\r
- }\r
-\r
- for (Entry = mVariableArray; Entry < mVariableArrayEnd;) {\r
- if (CompareGuid (VendorGuid, &Entry->VendorGuid)) {\r
- if (StrCmp (VariableName, (CHAR16 *)(Entry + 1))) {\r
- Size = StrSize ((CHAR16 *)(Entry + 1));\r
- if (Data != NULL) {\r
- *Data = (VOID *)(((UINT8 *)Entry) + (Size + sizeof (VARIABLE_ARRAY_ENTRY)));\r
- }\r
- return Entry;\r
- }\r
- }\r
-\r
- Size = StrSize ((CHAR16 *)(Entry + 1)) + sizeof (VARIABLE_ARRAY_ENTRY) + Entry->DataSize;\r
- Entry = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)Entry) + Size);\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-LibGetVariable (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- OUT UINT32 *Attributes OPTIONAL,\r
- IN OUT UINTN *DataSize,\r
- OUT VOID *Data\r
- )\r
-{\r
- VARIABLE_ARRAY_ENTRY *Entry;\r
- VOID *InternalData;\r
-\r
- if (EfiAtRuntime () && (Attributes != NULL)) {\r
- if ((*Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0) {\r
- return EFI_NOT_FOUND;\r
- }\r
- }\r
-\r
- Entry = GetVariableArrayEntry (VariableName, VendorGuid, &InternalData);\r
- if (Entry == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- if (*DataSize < Entry->DataSize) {\r
- *DataSize = Entry->DataSize;\r
- return EFI_BUFFER_TOO_SMALL;\r
- }\r
-\r
- *DataSize = Entry->DataSize;\r
- if (Attributes != NULL) {\r
- *Attributes = Entry->Attribute;\r
- }\r
-\r
- CopyMem (Data, InternalData, *DataSize);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-LibGetNextVariableName (\r
- IN OUT UINTN *VariableNameSize,\r
- IN OUT CHAR16 *VariableName,\r
- IN OUT EFI_GUID *VendorGuid\r
- )\r
-{\r
- VARIABLE_ARRAY_ENTRY *Entry;\r
- VOID *InternalData;\r
- UINTN StringSize;\r
- BOOLEAN Done;\r
-\r
- for (Done = FALSE; !Done; ) {\r
- Entry = GetVariableArrayEntry (VariableName, VendorGuid, &InternalData);\r
- if (Entry == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- // If we are at runtime skip variables that do not have the Runitme attribute set.\r
- Done = (EfiAtRuntime () && ((Entry->Attribute & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) ? FALSE : TRUE;\r
- }\r
-\r
- StringSize = StrSize ((CHAR16 *)(Entry + 1));\r
- Entry = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)Entry) + (StringSize + sizeof (VARIABLE_ARRAY_ENTRY) + Entry->DataSize));\r
- if (Entry >= mVariableArrayEnd) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- if (*VariableNameSize < StringSize) {\r
- *VariableNameSize = StringSize;\r
- return EFI_BUFFER_TOO_SMALL;\r
- }\r
-\r
- *VariableNameSize = StringSize;\r
- CopyMem (VariableName, (CHAR16 *)(Entry + 1), StringSize);\r
- CopyMem (VendorGuid, &Entry->VendorGuid, sizeof (EFI_GUID));\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-\r
-EFI_STATUS\r
-LibSetVariable (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN UINT32 Attributes,\r
- IN UINTN DataSize,\r
- IN VOID *Data\r
- )\r
-{\r
- VARIABLE_ARRAY_ENTRY *Entry;\r
- VOID *InternalData;\r
-\r
- if (EfiAtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Entry = GetVariableArrayEntry (VariableName, VendorGuid, &InternalData);\r
- if (Entry == NULL) {\r
- if (DataSize == 0) {\r
- return EFI_NOT_FOUND;\r
- }\r
- Entry = AddEntry (VariableName, VendorGuid, Attributes, DataSize, Data);\r
- return (Entry == NULL) ? EFI_OUT_OF_RESOURCES : EFI_SUCCESS;\r
-\r
- } else if (DataSize == 0) {\r
- // DataSize is zero so delete\r
- DeleteEntry (Entry);\r
- } else if (DataSize == Entry->DataSize) {\r
- // No change is size so just update the store\r
- Entry->Attribute |= Attributes;\r
- CopyMem (InternalData, Data, DataSize);\r
- } else {\r
- // Grow the entry by deleting and adding back. Don't lose previous Attributes\r
- Attributes |= Entry->Attribute;\r
- DeleteEntry (Entry);\r
- Entry = AddEntry (VariableName, VendorGuid, Attributes, DataSize, Data);\r
- return (Entry == NULL) ? EFI_OUT_OF_RESOURCES : EFI_SUCCESS;\r
- }\r
-}\r
-\r
-\r
-EFI_STATUS\r
-LibQueryVariableInfo (\r
- IN UINT32 Attributes,\r
- OUT UINT64 *MaximumVariableStorageSize,\r
- OUT UINT64 *RemainingVariableStorageSize,\r
- OUT UINT64 *MaximumVariableSize\r
- )\r
-{\r
- *MaximumVariableStorageSize = mMaximumVariableStorageSize;\r
- *RemainingVariableStorageSize = mRemainingVariableStorageSize;\r
- *MaximumVariableStorageSize = mRemainingVariableStorageSize;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-VOID\r
-LibVariableVirtualAddressChangeEvent (VOID)\r
-{\r
- EfiConvertPointer (0, (VOID **)&mVariableArray);\r
- EfiConvertPointer (0, (VOID **)&mVariableArrayNextFree);\r
- EfiConvertPointer (0, (VOID **)&mVariableArrayEnd);\r
-}\r
-\r
-\r
-VOID\r
-LibVariableInitialize (VOID)\r
-{\r
- UINTN Size;\r
-\r
- Size = PcdGet32 (PcdEmbeddedMemVariableStoreSize);\r
- mVariableArray = mVariableArrayNextFree = (VARIABLE_ARRAY_ENTRY *)AllocateRuntimePool (Size);\r
- ASSERT (mVariableArray != NULL);\r
-\r
- mVariableArrayEnd = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)mVariableArray) + Size);\r
-\r
- mMaximumVariableStorageSize = Size - sizeof (VARIABLE_ARRAY_ENTRY);\r
- mRemainingVariableStorageSize = mMaximumVariableStorageSize;\r
- mMaximumVariableSize = mMaximumVariableStorageSize;\r
-}\r
-\r