-/** @file
-*
-* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
-*
-* This program and the accompanying materials
-* are licensed and made available under the terms and conditions of the BSD License
-* which accompanies this distribution. The full text of the license may be found at
-* http://opensource.org/licenses/bsd-license.php
-*
-* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-*
-**/
-
-#include "BdsInternal.h"
-
-#include <Library/DxeServicesTableLib.h>
-#include <Library/HobLib.h>
-#include <Library/TimerLib.h>
-#include <Library/PrintLib.h>
-#include <Library/SerialPortLib.h>
-
-STATIC CHAR8 *mTokenList[] = {
- /*"SEC",*/
- "PEI",
- "DXE",
- "BDS",
- NULL
-};
-
-EFI_STATUS
-ShutdownUefiBootServices (
- VOID
- )
-{
- EFI_STATUS Status;
- UINTN MemoryMapSize;
- EFI_MEMORY_DESCRIPTOR *MemoryMap;
- UINTN MapKey;
- UINTN DescriptorSize;
- UINT32 DescriptorVersion;
- UINTN Pages;
-
- MemoryMap = NULL;
- MemoryMapSize = 0;
- Pages = 0;
-
- do {
- Status = gBS->GetMemoryMap (
- &MemoryMapSize,
- MemoryMap,
- &MapKey,
- &DescriptorSize,
- &DescriptorVersion
- );
- if (Status == EFI_BUFFER_TOO_SMALL) {
-
- Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;
- MemoryMap = AllocatePages (Pages);
-
- //
- // Get System MemoryMap
- //
- Status = gBS->GetMemoryMap (
- &MemoryMapSize,
- MemoryMap,
- &MapKey,
- &DescriptorSize,
- &DescriptorVersion
- );
- }
-
- // Don't do anything between the GetMemoryMap() and ExitBootServices()
- if (!EFI_ERROR(Status)) {
- Status = gBS->ExitBootServices (gImageHandle, MapKey);
- if (EFI_ERROR(Status)) {
- FreePages (MemoryMap, Pages);
- MemoryMap = NULL;
- MemoryMapSize = 0;
- }
- }
- } while (EFI_ERROR(Status));
-
- return Status;
-}
-
-/**
- Connect all DXE drivers
-
- @retval EFI_SUCCESS All drivers have been connected
- @retval EFI_NOT_FOUND No handles match the search.
- @retval EFI_OUT_OF_RESOURCES There is not resource pool memory to store the matching results.
-
-**/
-EFI_STATUS
-BdsConnectAllDrivers (
- VOID
- )
-{
- UINTN HandleCount, Index;
- EFI_HANDLE *HandleBuffer;
- EFI_STATUS Status;
-
- do {
- // Locate all the driver handles
- Status = gBS->LocateHandleBuffer (
- AllHandles,
- NULL,
- NULL,
- &HandleCount,
- &HandleBuffer
- );
- if (EFI_ERROR (Status)) {
- break;
- }
-
- // Connect every handles
- for (Index = 0; Index < HandleCount; Index++) {
- gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
- }
-
- if (HandleBuffer != NULL) {
- FreePool (HandleBuffer);
- }
-
- // Check if new handles have been created after the start of the previous handles
- Status = gDS->Dispatch ();
- } while (!EFI_ERROR(Status));
-
- return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-InsertSystemMemoryResources (
- LIST_ENTRY *ResourceList,
- EFI_HOB_RESOURCE_DESCRIPTOR *ResHob
- )
-{
- BDS_SYSTEM_MEMORY_RESOURCE *NewResource;
- LIST_ENTRY *Link;
- LIST_ENTRY *NextLink;
- LIST_ENTRY AttachedResources;
- BDS_SYSTEM_MEMORY_RESOURCE *Resource;
- EFI_PHYSICAL_ADDRESS NewResourceEnd;
-
- if (IsListEmpty (ResourceList)) {
- NewResource = AllocateZeroPool (sizeof(BDS_SYSTEM_MEMORY_RESOURCE));
- NewResource->PhysicalStart = ResHob->PhysicalStart;
- NewResource->ResourceLength = ResHob->ResourceLength;
- InsertTailList (ResourceList, &NewResource->Link);
- return EFI_SUCCESS;
- }
-
- InitializeListHead (&AttachedResources);
-
- Link = ResourceList->ForwardLink;
- ASSERT (Link != NULL);
- while (Link != ResourceList) {
- Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link;
-
- // Sanity Check. The resources should not overlapped.
- ASSERT(!((ResHob->PhysicalStart >= Resource->PhysicalStart) && (ResHob->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))));
- ASSERT(!((ResHob->PhysicalStart + ResHob->ResourceLength - 1 >= Resource->PhysicalStart) &&
- ((ResHob->PhysicalStart + ResHob->ResourceLength - 1) < (Resource->PhysicalStart + Resource->ResourceLength))));
-
- // The new resource is attached after this resource descriptor
- if (ResHob->PhysicalStart == Resource->PhysicalStart + Resource->ResourceLength) {
- Resource->ResourceLength = Resource->ResourceLength + ResHob->ResourceLength;
-
- NextLink = RemoveEntryList (&Resource->Link);
- InsertTailList (&AttachedResources, &Resource->Link);
- Link = NextLink;
- }
- // The new resource is attached before this resource descriptor
- else if (ResHob->PhysicalStart + ResHob->ResourceLength == Resource->PhysicalStart) {
- Resource->PhysicalStart = ResHob->PhysicalStart;
- Resource->ResourceLength = Resource->ResourceLength + ResHob->ResourceLength;
-
- NextLink = RemoveEntryList (&Resource->Link);
- InsertTailList (&AttachedResources, &Resource->Link);
- Link = NextLink;
- } else {
- Link = Link->ForwardLink;
- }
- }
-
- if (!IsListEmpty (&AttachedResources)) {
- // See if we can merge the attached resource with other resources
-
- NewResource = (BDS_SYSTEM_MEMORY_RESOURCE*)GetFirstNode (&AttachedResources);
- Link = RemoveEntryList (&NewResource->Link);
- while (!IsListEmpty (&AttachedResources)) {
- // Merge resources
- Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link;
-
- // Ensure they overlap each other
- ASSERT(
- ((NewResource->PhysicalStart >= Resource->PhysicalStart) && (NewResource->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))) ||
- (((NewResource->PhysicalStart + NewResource->ResourceLength) >= Resource->PhysicalStart) && ((NewResource->PhysicalStart + NewResource->ResourceLength) < (Resource->PhysicalStart + Resource->ResourceLength)))
- );
-
- NewResourceEnd = MAX (NewResource->PhysicalStart + NewResource->ResourceLength, Resource->PhysicalStart + Resource->ResourceLength);
- NewResource->PhysicalStart = MIN (NewResource->PhysicalStart, Resource->PhysicalStart);
- NewResource->ResourceLength = NewResourceEnd - NewResource->PhysicalStart;
-
- Link = RemoveEntryList (Link);
- }
- } else {
- // None of the Resource of the list is attached to this ResHob. Create a new entry for it
- NewResource = AllocateZeroPool (sizeof(BDS_SYSTEM_MEMORY_RESOURCE));
- NewResource->PhysicalStart = ResHob->PhysicalStart;
- NewResource->ResourceLength = ResHob->ResourceLength;
- }
- InsertTailList (ResourceList, &NewResource->Link);
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-GetSystemMemoryResources (
- IN LIST_ENTRY *ResourceList
- )
-{
- EFI_HOB_RESOURCE_DESCRIPTOR *ResHob;
-
- InitializeListHead (ResourceList);
-
- // Find the first System Memory Resource Descriptor
- ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
- while ((ResHob != NULL) && (ResHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY)) {
- ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
- }
-
- // Did not find any
- if (ResHob == NULL) {
- return EFI_NOT_FOUND;
- } else {
- InsertSystemMemoryResources (ResourceList, ResHob);
- }
-
- ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
- while (ResHob != NULL) {
- if (ResHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
- InsertSystemMemoryResources (ResourceList, ResHob);
- }
- ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
- }
-
- return EFI_SUCCESS;
-}
-
-VOID
-PrintPerformance (
- VOID
- )
-{
- UINTN Key;
- CONST VOID *Handle;
- CONST CHAR8 *Token, *Module;
- UINT64 Start, Stop, TimeStamp;
- UINT64 Delta, TicksPerSecond, Milliseconds;
- UINTN Index;
- CHAR8 Buffer[100];
- UINTN CharCount;
- BOOLEAN CountUp;
-
- TicksPerSecond = GetPerformanceCounterProperties (&Start, &Stop);
- if (Start < Stop) {
- CountUp = TRUE;
- } else {
- CountUp = FALSE;
- }
-
- TimeStamp = 0;
- Key = 0;
- do {
- Key = GetPerformanceMeasurement (Key, (CONST VOID **)&Handle, &Token, &Module, &Start, &Stop);
- if (Key != 0) {
- for (Index = 0; mTokenList[Index] != NULL; Index++) {
- if (AsciiStriCmp (mTokenList[Index], Token) == 0) {
- Delta = CountUp?(Stop - Start):(Start - Stop);
- TimeStamp += Delta;
- Milliseconds = DivU64x64Remainder (MultU64x32 (Delta, 1000), TicksPerSecond, NULL);
- CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"%6a %6ld ms\n", Token, Milliseconds);
- SerialPortWrite ((UINT8 *) Buffer, CharCount);
- break;
- }
- }
- }
- } while (Key != 0);
-
- CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Total Time = %ld ms\n\n", DivU64x64Remainder (MultU64x32 (TimeStamp, 1000), TicksPerSecond, NULL));
- SerialPortWrite ((UINT8 *) Buffer, CharCount);
-}
-
-EFI_STATUS
-GetEnvironmentVariable (
- IN CONST CHAR16* VariableName,
- IN VOID* DefaultValue,
- IN OUT UINTN* Size,
- OUT VOID** Value
- )
-{
- EFI_STATUS Status;
- UINTN VariableSize;
-
- // Try to get the variable size.
- *Value = NULL;
- VariableSize = 0;
- Status = gRT->GetVariable ((CHAR16 *) VariableName, &gEfiGlobalVariableGuid, NULL, &VariableSize, *Value);
- if (Status == EFI_NOT_FOUND) {
- if ((DefaultValue != NULL) && (Size != NULL) && (*Size != 0)) {
- // If the environment variable does not exist yet then set it with the default value
- Status = gRT->SetVariable (
- (CHAR16*)VariableName,
- &gEfiGlobalVariableGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- *Size,
- DefaultValue
- );
- *Value = DefaultValue;
- } else {
- return EFI_NOT_FOUND;
- }
- } else if (Status == EFI_BUFFER_TOO_SMALL) {
- // Get the environment variable value
- *Value = AllocatePool (VariableSize);
- if (*Value == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = gRT->GetVariable ((CHAR16 *)VariableName, &gEfiGlobalVariableGuid, NULL, &VariableSize, *Value);
- if (EFI_ERROR (Status)) {
- FreePool(*Value);
- return EFI_INVALID_PARAMETER;
- }
-
- if (Size) {
- *Size = VariableSize;
- }
- } else {
- *Value = DefaultValue;
- return Status;
- }
-
- return EFI_SUCCESS;
-}
+/** @file\r
+*\r
+* Copyright (c) 2011-2012, ARM Limited. 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
+#include "BdsInternal.h"\r
+\r
+#include <Library/DxeServicesTableLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/SerialPortLib.h>\r
+\r
+STATIC CHAR8 *mTokenList[] = {\r
+ /*"SEC",*/\r
+ "PEI",\r
+ "DXE",\r
+ "BDS",\r
+ NULL\r
+};\r
+\r
+EFI_STATUS\r
+ShutdownUefiBootServices (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN MemoryMapSize;\r
+ EFI_MEMORY_DESCRIPTOR *MemoryMap;\r
+ UINTN MapKey;\r
+ UINTN DescriptorSize;\r
+ UINT32 DescriptorVersion;\r
+ UINTN Pages;\r
+\r
+ MemoryMap = NULL;\r
+ MemoryMapSize = 0;\r
+ Pages = 0;\r
+\r
+ do {\r
+ Status = gBS->GetMemoryMap (\r
+ &MemoryMapSize,\r
+ MemoryMap,\r
+ &MapKey,\r
+ &DescriptorSize,\r
+ &DescriptorVersion\r
+ );\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+\r
+ Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;\r
+ MemoryMap = AllocatePages (Pages);\r
+\r
+ //\r
+ // Get System MemoryMap\r
+ //\r
+ Status = gBS->GetMemoryMap (\r
+ &MemoryMapSize,\r
+ MemoryMap,\r
+ &MapKey,\r
+ &DescriptorSize,\r
+ &DescriptorVersion\r
+ );\r
+ }\r
+\r
+ // Don't do anything between the GetMemoryMap() and ExitBootServices()\r
+ if (!EFI_ERROR(Status)) {\r
+ Status = gBS->ExitBootServices (gImageHandle, MapKey);\r
+ if (EFI_ERROR(Status)) {\r
+ FreePages (MemoryMap, Pages);\r
+ MemoryMap = NULL;\r
+ MemoryMapSize = 0;\r
+ }\r
+ }\r
+ } while (EFI_ERROR(Status));\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Connect all DXE drivers\r
+\r
+ @retval EFI_SUCCESS All drivers have been connected\r
+ @retval EFI_NOT_FOUND No handles match the search.\r
+ @retval EFI_OUT_OF_RESOURCES There is not resource pool memory to store the matching results.\r
+\r
+**/\r
+EFI_STATUS\r
+BdsConnectAllDrivers (\r
+ VOID\r
+ )\r
+{\r
+ UINTN HandleCount, Index;\r
+ EFI_HANDLE *HandleBuffer;\r
+ EFI_STATUS Status;\r
+\r
+ do {\r
+ // Locate all the driver handles\r
+ Status = gBS->LocateHandleBuffer (\r
+ AllHandles,\r
+ NULL,\r
+ NULL,\r
+ &HandleCount,\r
+ &HandleBuffer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+\r
+ // Connect every handles\r
+ for (Index = 0; Index < HandleCount; Index++) {\r
+ gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);\r
+ }\r
+\r
+ if (HandleBuffer != NULL) {\r
+ FreePool (HandleBuffer);\r
+ }\r
+\r
+ // Check if new handles have been created after the start of the previous handles\r
+ Status = gDS->Dispatch ();\r
+ } while (!EFI_ERROR(Status));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+InsertSystemMemoryResources (\r
+ LIST_ENTRY *ResourceList,\r
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResHob\r
+ )\r
+{\r
+ BDS_SYSTEM_MEMORY_RESOURCE *NewResource;\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *NextLink;\r
+ LIST_ENTRY AttachedResources;\r
+ BDS_SYSTEM_MEMORY_RESOURCE *Resource;\r
+ EFI_PHYSICAL_ADDRESS NewResourceEnd;\r
+\r
+ if (IsListEmpty (ResourceList)) {\r
+ NewResource = AllocateZeroPool (sizeof(BDS_SYSTEM_MEMORY_RESOURCE));\r
+ NewResource->PhysicalStart = ResHob->PhysicalStart;\r
+ NewResource->ResourceLength = ResHob->ResourceLength;\r
+ InsertTailList (ResourceList, &NewResource->Link);\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ InitializeListHead (&AttachedResources);\r
+\r
+ Link = ResourceList->ForwardLink;\r
+ ASSERT (Link != NULL);\r
+ while (Link != ResourceList) {\r
+ Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link;\r
+\r
+ // Sanity Check. The resources should not overlapped.\r
+ ASSERT(!((ResHob->PhysicalStart >= Resource->PhysicalStart) && (ResHob->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))));\r
+ ASSERT(!((ResHob->PhysicalStart + ResHob->ResourceLength - 1 >= Resource->PhysicalStart) &&\r
+ ((ResHob->PhysicalStart + ResHob->ResourceLength - 1) < (Resource->PhysicalStart + Resource->ResourceLength))));\r
+\r
+ // The new resource is attached after this resource descriptor\r
+ if (ResHob->PhysicalStart == Resource->PhysicalStart + Resource->ResourceLength) {\r
+ Resource->ResourceLength = Resource->ResourceLength + ResHob->ResourceLength;\r
+\r
+ NextLink = RemoveEntryList (&Resource->Link);\r
+ InsertTailList (&AttachedResources, &Resource->Link);\r
+ Link = NextLink;\r
+ }\r
+ // The new resource is attached before this resource descriptor\r
+ else if (ResHob->PhysicalStart + ResHob->ResourceLength == Resource->PhysicalStart) {\r
+ Resource->PhysicalStart = ResHob->PhysicalStart;\r
+ Resource->ResourceLength = Resource->ResourceLength + ResHob->ResourceLength;\r
+\r
+ NextLink = RemoveEntryList (&Resource->Link);\r
+ InsertTailList (&AttachedResources, &Resource->Link);\r
+ Link = NextLink;\r
+ } else {\r
+ Link = Link->ForwardLink;\r
+ }\r
+ }\r
+\r
+ if (!IsListEmpty (&AttachedResources)) {\r
+ // See if we can merge the attached resource with other resources\r
+\r
+ NewResource = (BDS_SYSTEM_MEMORY_RESOURCE*)GetFirstNode (&AttachedResources);\r
+ Link = RemoveEntryList (&NewResource->Link);\r
+ while (!IsListEmpty (&AttachedResources)) {\r
+ // Merge resources\r
+ Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link;\r
+\r
+ // Ensure they overlap each other\r
+ ASSERT(\r
+ ((NewResource->PhysicalStart >= Resource->PhysicalStart) && (NewResource->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))) ||\r
+ (((NewResource->PhysicalStart + NewResource->ResourceLength) >= Resource->PhysicalStart) && ((NewResource->PhysicalStart + NewResource->ResourceLength) < (Resource->PhysicalStart + Resource->ResourceLength)))\r
+ );\r
+\r
+ NewResourceEnd = MAX (NewResource->PhysicalStart + NewResource->ResourceLength, Resource->PhysicalStart + Resource->ResourceLength);\r
+ NewResource->PhysicalStart = MIN (NewResource->PhysicalStart, Resource->PhysicalStart);\r
+ NewResource->ResourceLength = NewResourceEnd - NewResource->PhysicalStart;\r
+\r
+ Link = RemoveEntryList (Link);\r
+ }\r
+ } else {\r
+ // None of the Resource of the list is attached to this ResHob. Create a new entry for it\r
+ NewResource = AllocateZeroPool (sizeof(BDS_SYSTEM_MEMORY_RESOURCE));\r
+ NewResource->PhysicalStart = ResHob->PhysicalStart;\r
+ NewResource->ResourceLength = ResHob->ResourceLength;\r
+ }\r
+ InsertTailList (ResourceList, &NewResource->Link);\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetSystemMemoryResources (\r
+ IN LIST_ENTRY *ResourceList\r
+ )\r
+{\r
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResHob;\r
+\r
+ InitializeListHead (ResourceList);\r
+\r
+ // Find the first System Memory Resource Descriptor\r
+ ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);\r
+ while ((ResHob != NULL) && (ResHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY)) {\r
+ ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));\r
+ }\r
+\r
+ // Did not find any\r
+ if (ResHob == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ } else {\r
+ InsertSystemMemoryResources (ResourceList, ResHob);\r
+ }\r
+\r
+ ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));\r
+ while (ResHob != NULL) {\r
+ if (ResHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {\r
+ InsertSystemMemoryResources (ResourceList, ResHob);\r
+ }\r
+ ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+VOID\r
+PrintPerformance (\r
+ VOID\r
+ )\r
+{\r
+ UINTN Key;\r
+ CONST VOID *Handle;\r
+ CONST CHAR8 *Token, *Module;\r
+ UINT64 Start, Stop, TimeStamp;\r
+ UINT64 Delta, TicksPerSecond, Milliseconds;\r
+ UINTN Index;\r
+ CHAR8 Buffer[100];\r
+ UINTN CharCount;\r
+ BOOLEAN CountUp;\r
+\r
+ TicksPerSecond = GetPerformanceCounterProperties (&Start, &Stop);\r
+ if (Start < Stop) {\r
+ CountUp = TRUE;\r
+ } else {\r
+ CountUp = FALSE;\r
+ }\r
+\r
+ TimeStamp = 0;\r
+ Key = 0;\r
+ do {\r
+ Key = GetPerformanceMeasurement (Key, (CONST VOID **)&Handle, &Token, &Module, &Start, &Stop);\r
+ if (Key != 0) {\r
+ for (Index = 0; mTokenList[Index] != NULL; Index++) {\r
+ if (AsciiStriCmp (mTokenList[Index], Token) == 0) {\r
+ Delta = CountUp?(Stop - Start):(Start - Stop);\r
+ TimeStamp += Delta;\r
+ Milliseconds = DivU64x64Remainder (MultU64x32 (Delta, 1000), TicksPerSecond, NULL);\r
+ CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"%6a %6ld ms\n", Token, Milliseconds);\r
+ SerialPortWrite ((UINT8 *) Buffer, CharCount);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ } while (Key != 0);\r
+\r
+ CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Total Time = %ld ms\n\n", DivU64x64Remainder (MultU64x32 (TimeStamp, 1000), TicksPerSecond, NULL));\r
+ SerialPortWrite ((UINT8 *) Buffer, CharCount);\r
+}\r
+\r
+EFI_STATUS\r
+GetEnvironmentVariable (\r
+ IN CONST CHAR16* VariableName,\r
+ IN VOID* DefaultValue,\r
+ IN OUT UINTN* Size,\r
+ OUT VOID** Value\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN VariableSize;\r
+\r
+ // Try to get the variable size.\r
+ *Value = NULL;\r
+ VariableSize = 0;\r
+ Status = gRT->GetVariable ((CHAR16 *) VariableName, &gEfiGlobalVariableGuid, NULL, &VariableSize, *Value);\r
+ if (Status == EFI_NOT_FOUND) {\r
+ if ((DefaultValue != NULL) && (Size != NULL) && (*Size != 0)) {\r
+ // If the environment variable does not exist yet then set it with the default value\r
+ Status = gRT->SetVariable (\r
+ (CHAR16*)VariableName,\r
+ &gEfiGlobalVariableGuid,\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+ *Size,\r
+ DefaultValue\r
+ );\r
+ *Value = DefaultValue;\r
+ } else {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ } else if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ // Get the environment variable value\r
+ *Value = AllocatePool (VariableSize);\r
+ if (*Value == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Status = gRT->GetVariable ((CHAR16 *)VariableName, &gEfiGlobalVariableGuid, NULL, &VariableSize, *Value);\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool(*Value);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (Size) {\r
+ *Size = VariableSize;\r
+ }\r
+ } else {\r
+ *Value = DefaultValue;\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r