The GCD services are used to manage the memory and I/O regions that\r
are accessible to the CPU that is executing the DXE core.\r
\r
-Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2006 - 2011, Intel Corporation. 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
{ 0, 0, FALSE }\r
};\r
\r
+///\r
+/// Lookup table used to print GCD Memory Space Map\r
+///\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mGcdMemoryTypeNames[] = {\r
+ "NonExist ", // EfiGcdMemoryTypeNonExistent\r
+ "Reserved ", // EfiGcdMemoryTypeReserved\r
+ "SystemMem", // EfiGcdMemoryTypeSystemMemory\r
+ "MMIO ", // EfiGcdMemoryTypeMemoryMappedIo\r
+ "Unknown " // EfiGcdMemoryTypeMaximum\r
+};\r
+\r
+///\r
+/// Lookup table used to print GCD I/O Space Map\r
+///\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mGcdIoTypeNames[] = {\r
+ "NonExist", // EfiGcdIoTypeNonExistent\r
+ "Reserved", // EfiGcdIoTypeReserved\r
+ "I/O ", // EfiGcdIoTypeIo\r
+ "Unknown " // EfiGcdIoTypeMaximum \r
+};\r
+\r
+///\r
+/// Lookup table used to print GCD Allocation Types\r
+///\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mGcdAllocationTypeNames[] = {\r
+ "AnySearchBottomUp ", // EfiGcdAllocateAnySearchBottomUp\r
+ "MaxAddressSearchBottomUp ", // EfiGcdAllocateMaxAddressSearchBottomUp\r
+ "AtAddress ", // EfiGcdAllocateAddress\r
+ "AnySearchTopDown ", // EfiGcdAllocateAnySearchTopDown\r
+ "MaxAddressSearchTopDown ", // EfiGcdAllocateMaxAddressSearchTopDown\r
+ "Unknown " // EfiGcdMaxAllocateType\r
+};\r
+\r
+/**\r
+ Dump the entire contents if the GCD Memory Space Map using DEBUG() macros when\r
+ PcdDebugPrintErrorLevel has the DEBUG_GCD bit set.\r
+\r
+ @param InitialMap TRUE if the initial GCD Memory Map is being dumped. Otherwise, FALSE.\r
+ \r
+**/\r
+VOID\r
+EFIAPI\r
+CoreDumpGcdMemorySpaceMap (\r
+ BOOLEAN InitialMap\r
+ )\r
+{\r
+ DEBUG_CODE (\r
+ EFI_STATUS Status;\r
+ UINTN NumberOfDescriptors;\r
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;\r
+ UINTN Index;\r
+ \r
+ Status = CoreGetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ if (InitialMap) {\r
+ DEBUG ((DEBUG_GCD, "GCD:Initial GCD Memory Space Map\n"));\r
+ }\r
+ DEBUG ((DEBUG_GCD, "GCDMemType Range Capabilities Attributes \n"));\r
+ DEBUG ((DEBUG_GCD, "========== ================================= ================ ================\n"));\r
+ for (Index = 0; Index < NumberOfDescriptors; Index++) {\r
+ DEBUG ((DEBUG_GCD, "%a %016lx-%016lx %016lx %016lx%c\n", \r
+ mGcdMemoryTypeNames[MIN (MemorySpaceMap[Index].GcdMemoryType, EfiGcdMemoryTypeMaximum)],\r
+ MemorySpaceMap[Index].BaseAddress, \r
+ MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - 1,\r
+ MemorySpaceMap[Index].Capabilities, \r
+ MemorySpaceMap[Index].Attributes,\r
+ MemorySpaceMap[Index].ImageHandle == NULL ? ' ' : '*'\r
+ ));\r
+ }\r
+ DEBUG ((DEBUG_GCD, "\n"));\r
+ FreePool (MemorySpaceMap);\r
+ );\r
+}\r
+\r
+/**\r
+ Dump the entire contents if the GCD I/O Space Map using DEBUG() macros when \r
+ PcdDebugPrintErrorLevel has the DEBUG_GCD bit set.\r
+\r
+ @param InitialMap TRUE if the initial GCD I/O Map is being dumped. Otherwise, FALSE.\r
+ \r
+**/\r
+VOID\r
+EFIAPI\r
+CoreDumpGcdIoSpaceMap (\r
+ BOOLEAN InitialMap\r
+ )\r
+{\r
+ DEBUG_CODE (\r
+ EFI_STATUS Status;\r
+ UINTN NumberOfDescriptors;\r
+ EFI_GCD_IO_SPACE_DESCRIPTOR *IoSpaceMap;\r
+ UINTN Index;\r
+ \r
+ Status = CoreGetIoSpaceMap (&NumberOfDescriptors, &IoSpaceMap);\r
+ ASSERT_EFI_ERROR (Status);\r
+ \r
+ if (InitialMap) {\r
+ DEBUG ((DEBUG_GCD, "GCD:Initial GCD I/O Space Map\n"));\r
+ } \r
+ \r
+ DEBUG ((DEBUG_GCD, "GCDIoType Range \n"));\r
+ DEBUG ((DEBUG_GCD, "========== =================================\n"));\r
+ for (Index = 0; Index < NumberOfDescriptors; Index++) {\r
+ DEBUG ((DEBUG_GCD, "%a %016lx-%016lx%c\n", \r
+ mGcdIoTypeNames[MIN (IoSpaceMap[Index].GcdIoType, EfiGcdIoTypeMaximum)],\r
+ IoSpaceMap[Index].BaseAddress, \r
+ IoSpaceMap[Index].BaseAddress + IoSpaceMap[Index].Length - 1,\r
+ IoSpaceMap[Index].ImageHandle == NULL ? ' ' : '*'\r
+ ));\r
+ }\r
+ DEBUG ((DEBUG_GCD, "\n"));\r
+ FreePool (IoSpaceMap);\r
+ );\r
+}\r
+ \r
+\r
\r
/**\r
Acquire memory lock on mGcdMemorySpaceLock.\r
EFI_GCD_MAP_ENTRY *BottomEntry;\r
LIST_ENTRY *StartLink;\r
LIST_ENTRY *EndLink;\r
-\r
- EFI_CPU_ARCH_PROTOCOL *CpuArch;\r
- UINT64 CpuArchAttributes;\r
+ UINT64 CpuArchAttributes;\r
\r
if (Length == 0) {\r
+ DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER));\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {\r
CoreAcquireGcdMemoryLock ();\r
Map = &mGcdMemorySpaceMap;\r
- }\r
- if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {\r
+ } else if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {\r
CoreAcquireGcdIoLock ();\r
Map = &mGcdIoSpaceMap;\r
+ } else {\r
+ ASSERT (FALSE);\r
}\r
\r
//\r
\r
goto Done;\r
}\r
+ ASSERT (StartLink != NULL && EndLink != NULL);\r
\r
//\r
// Verify that the list of descriptors are unallocated non-existent memory.\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
}\r
+ ASSERT (TopEntry != NULL && BottomEntry != NULL);\r
\r
if (Operation == GCD_SET_ATTRIBUTES_MEMORY_OPERATION) {\r
//\r
// Call CPU Arch Protocol to attempt to set attributes on the range\r
//\r
CpuArchAttributes = ConverToCpuArchAttributes (Attributes);\r
- if ( CpuArchAttributes != INVALID_CPU_ARCH_ATTRIBUTES ) {\r
- Status = CoreLocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&CpuArch);\r
- if (EFI_ERROR (Status)) {\r
- Status = EFI_ACCESS_DENIED;\r
- goto Done;\r
- }\r
-\r
- Status = CpuArch->SetMemoryAttributes (\r
- CpuArch,\r
- BaseAddress,\r
- Length,\r
- CpuArchAttributes\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
+ if (CpuArchAttributes != INVALID_CPU_ARCH_ATTRIBUTES) {\r
+ if (gCpu != NULL) {\r
+ Status = gCpu->SetMemoryAttributes (\r
+ gCpu,\r
+ BaseAddress,\r
+ Length,\r
+ CpuArchAttributes\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
}\r
}\r
-\r
}\r
\r
//\r
Status = CoreCleanupGcdMapEntry (TopEntry, BottomEntry, StartLink, EndLink, Map);\r
\r
Done:\r
+ DEBUG ((DEBUG_GCD, " Status = %r\n", Status));\r
+\r
if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {\r
CoreReleaseGcdMemoryLock ();\r
+ CoreDumpGcdMemorySpaceMap (FALSE);\r
}\r
if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {\r
CoreReleaseGcdIoLock ();\r
+ CoreDumpGcdIoSpaceMap (FALSE);\r
}\r
\r
return Status;\r
// Make sure parameters are valid\r
//\r
if (GcdAllocateType < 0 || GcdAllocateType >= EfiGcdMaxAllocateType) {\r
+ DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER));\r
return EFI_INVALID_PARAMETER;\r
}\r
if (GcdMemoryType < 0 || GcdMemoryType >= EfiGcdMemoryTypeMaximum) {\r
+ DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER));\r
return EFI_INVALID_PARAMETER;\r
}\r
if (GcdIoType < 0 || GcdIoType >= EfiGcdIoTypeMaximum) {\r
+ DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER));\r
return EFI_INVALID_PARAMETER;\r
}\r
if (BaseAddress == NULL) {\r
+ DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER));\r
return EFI_INVALID_PARAMETER;\r
}\r
if (ImageHandle == NULL) {\r
+ DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER));\r
return EFI_INVALID_PARAMETER;\r
}\r
if (Alignment >= 64) {\r
+ DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_NOT_FOUND));\r
return EFI_NOT_FOUND;\r
}\r
if (Length == 0) {\r
+ DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER));\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {\r
CoreAcquireGcdMemoryLock ();\r
Map = &mGcdMemorySpaceMap;\r
- }\r
- if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {\r
+ } else if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {\r
CoreAcquireGcdIoLock ();\r
Map = &mGcdIoSpaceMap;\r
+ } else {\r
+ ASSERT (FALSE);\r
}\r
\r
Found = FALSE;\r
Status = EFI_NOT_FOUND;\r
goto Done;\r
}\r
+ ASSERT (StartLink != NULL && EndLink != NULL);\r
\r
//\r
// Verify that the list of descriptors are unallocated memory matching GcdMemoryType.\r
Status = EFI_NOT_FOUND;\r
goto Done;\r
}\r
+ ASSERT (StartLink != NULL && EndLink != NULL);\r
\r
Link = StartLink;\r
//\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
}\r
+ ASSERT (TopEntry != NULL && BottomEntry != NULL);\r
\r
//\r
// Convert/Insert the list of descriptors from StartLink to EndLink\r
Status = CoreCleanupGcdMapEntry (TopEntry, BottomEntry, StartLink, EndLink, Map);\r
\r
Done:\r
+ DEBUG ((DEBUG_GCD, " Status = %r", Status));\r
+ if (!EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_GCD, " (BaseAddress = %016lx)", *BaseAddress));\r
+ }\r
+ DEBUG ((DEBUG_GCD, "\n"));\r
+ \r
if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {\r
CoreReleaseGcdMemoryLock ();\r
+ CoreDumpGcdMemorySpaceMap (FALSE);\r
}\r
if ((Operation & GCD_IO_SPACE_OPERATION) !=0) {\r
CoreReleaseGcdIoLock ();\r
+ CoreDumpGcdIoSpaceMap (FALSE);\r
}\r
\r
return Status;\r
IN UINT64 Capabilities\r
)\r
{\r
+ DEBUG ((DEBUG_GCD, "GCD:AddMemorySpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));\r
+ DEBUG ((DEBUG_GCD, " GcdMemoryType = %a\n", mGcdMemoryTypeNames[MIN (GcdMemoryType, EfiGcdMemoryTypeMaximum)]));\r
+ DEBUG ((DEBUG_GCD, " Capabilities = %016lx\n", Capabilities));\r
+\r
//\r
// Make sure parameters are valid\r
//\r
IN EFI_HANDLE DeviceHandle OPTIONAL\r
)\r
{\r
+ DEBUG ((DEBUG_GCD, "GCD:AllocateMemorySpace(Base=%016lx,Length=%016lx)\n", *BaseAddress, Length));\r
+ DEBUG ((DEBUG_GCD, " GcdAllocateType = %a\n", mGcdAllocationTypeNames[MIN (GcdAllocateType, EfiGcdMaxAllocateType)]));\r
+ DEBUG ((DEBUG_GCD, " GcdMemoryType = %a\n", mGcdMemoryTypeNames[MIN (GcdMemoryType, EfiGcdMemoryTypeMaximum)]));\r
+ DEBUG ((DEBUG_GCD, " Alignment = %016lx\n", LShiftU64 (1, Alignment)));\r
+ DEBUG ((DEBUG_GCD, " ImageHandle = %p\n", ImageHandle));\r
+ DEBUG ((DEBUG_GCD, " DeviceHandle = %p\n", DeviceHandle));\r
+ \r
return CoreAllocateSpace (\r
GCD_ALLOCATE_MEMORY_OPERATION,\r
GcdAllocateType,\r
IN UINT64 Length\r
)\r
{\r
+ DEBUG ((DEBUG_GCD, "GCD:FreeMemorySpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));\r
+\r
return CoreConvertSpace (GCD_FREE_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, 0, 0);\r
}\r
\r
IN UINT64 Length\r
)\r
{\r
+ DEBUG ((DEBUG_GCD, "GCD:RemoveMemorySpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));\r
+ \r
return CoreConvertSpace (GCD_REMOVE_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, 0, 0);\r
}\r
\r
if (EFI_ERROR (Status)) {\r
Status = EFI_NOT_FOUND;\r
} else {\r
+ ASSERT (StartLink != NULL && EndLink != NULL);\r
//\r
// Copy the contents of the found descriptor into Descriptor\r
//\r
IN UINT64 Attributes\r
)\r
{\r
+ DEBUG ((DEBUG_GCD, "GCD:SetMemorySpaceAttributes(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));\r
+ DEBUG ((DEBUG_GCD, " Attributes = %016lx\n", Attributes));\r
+\r
return CoreConvertSpace (GCD_SET_ATTRIBUTES_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, 0, Attributes);\r
}\r
\r
IN UINT64 Length\r
)\r
{\r
+ DEBUG ((DEBUG_GCD, "GCD:AddIoSpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));\r
+ DEBUG ((DEBUG_GCD, " GcdIoType = %a\n", mGcdIoTypeNames[MIN (GcdIoType, EfiGcdIoTypeMaximum)]));\r
+ \r
//\r
// Make sure parameters are valid\r
//\r
IN EFI_HANDLE DeviceHandle OPTIONAL\r
)\r
{\r
+ DEBUG ((DEBUG_GCD, "GCD:AllocateIoSpace(Base=%016lx,Length=%016lx)\n", *BaseAddress, Length));\r
+ DEBUG ((DEBUG_GCD, " GcdAllocateType = %a\n", mGcdAllocationTypeNames[MIN (GcdAllocateType, EfiGcdMaxAllocateType)]));\r
+ DEBUG ((DEBUG_GCD, " GcdMemoryType = %a\n", mGcdIoTypeNames[MIN (GcdIoType, EfiGcdMemoryTypeMaximum)]));\r
+ DEBUG ((DEBUG_GCD, " Alignment = %016lx\n", LShiftU64 (1, Alignment)));\r
+ DEBUG ((DEBUG_GCD, " ImageHandle = %p\n", ImageHandle));\r
+ DEBUG ((DEBUG_GCD, " DeviceHandle = %p\n", DeviceHandle));\r
+ \r
return CoreAllocateSpace (\r
GCD_ALLOCATE_IO_OPERATION,\r
GcdAllocateType,\r
IN UINT64 Length\r
)\r
{\r
+ DEBUG ((DEBUG_GCD, "GCD:FreeIoSpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));\r
+\r
return CoreConvertSpace (GCD_FREE_IO_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, 0, 0);\r
}\r
\r
IN UINT64 Length\r
)\r
{\r
+ DEBUG ((DEBUG_GCD, "GCD:RemoveIoSpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));\r
+ \r
return CoreConvertSpace (GCD_REMOVE_IO_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, 0, 0);\r
}\r
\r
if (EFI_ERROR (Status)) {\r
Status = EFI_NOT_FOUND;\r
} else {\r
+ ASSERT (StartLink != NULL && EndLink != NULL);\r
//\r
// Copy the contents of the found descriptor into Descriptor\r
//\r
EFI_PHYSICAL_ADDRESS HighAddress;\r
EFI_HOB_RESOURCE_DESCRIPTOR *MaxResourceHob;\r
EFI_HOB_GUID_TYPE *GuidHob;\r
+ UINT32 ReservedCodePageNumber;\r
\r
//\r
// Point at the first HOB. This must be the PHIT HOB.\r
// Cache the PHIT HOB for later use\r
//\r
PhitHob = Hob.HandoffInformationTable;\r
-\r
+ \r
+ if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {\r
+ ReservedCodePageNumber = PcdGet32(PcdLoadFixAddressRuntimeCodePageNumber);\r
+ ReservedCodePageNumber += PcdGet32(PcdLoadFixAddressBootTimeCodePageNumber);\r
+ \r
+ //\r
+ // cache the Top address for loading modules at Fixed Address \r
+ //\r
+ gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress = PhitHob->EfiMemoryTop \r
+ + EFI_PAGES_TO_SIZE(ReservedCodePageNumber);\r
+ }\r
//\r
// See if a Memory Type Information HOB is available\r
//\r
// The max address must be within the physically addressible range for the processor.\r
//\r
MaxMemoryLength = 0;\r
- MaxAddress = EFI_MAX_ADDRESS;\r
+ MaxAddress = MAX_ADDRESS;\r
do {\r
HighAddress = 0;\r
Found = FALSE;\r
\r
InsertHeadList (&mGcdMemorySpaceMap, &Entry->Link);\r
\r
+ CoreDumpGcdMemorySpaceMap (TRUE);\r
+ \r
//\r
// Initialize the GCD I/O Space Map\r
//\r
\r
InsertHeadList (&mGcdIoSpaceMap, &Entry->Link);\r
\r
+ CoreDumpGcdIoSpaceMap (TRUE);\r
+ \r
//\r
// Walk the HOB list and add all resource descriptors to the GCD\r
//\r
// Add and allocate the remaining unallocated system memory to the memory services.\r
//\r
Status = CoreGetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);\r
+ ASSERT (Status == EFI_SUCCESS);\r
+\r
for (Index = 0; Index < NumberOfDescriptors; Index++) {\r
if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeSystemMemory) {\r
if (MemorySpaceMap[Index].ImageHandle == NULL) {\r