-/** @file\r
-*\r
-* Copyright (c) 2011, 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
-\r
-EFI_STATUS\r
-ShutdownUefiBootServices( VOID )\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
- 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
- // 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
- }\r
- } while (EFI_ERROR (Status));\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-BdsConnectAllDrivers( VOID ) {\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
+/** @file
+*
+* Copyright (c) 2011, 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;
+ 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;
+
+ TicksPerSecond = GetPerformanceCounterProperties (NULL, NULL);
+
+ 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 = 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);
+}