/** @file\r
UEFI PropertiesTable support\r
\r
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2015 - 2017, 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
#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \\r
((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))\r
\r
-#define IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE SIGNATURE_32 ('I','P','R','C')\r
-\r
-typedef struct {\r
- UINT32 Signature;\r
- LIST_ENTRY Link;\r
- EFI_PHYSICAL_ADDRESS CodeSegmentBase;\r
- UINT64 CodeSegmentSize;\r
-} IMAGE_PROPERTIES_RECORD_CODE_SECTION;\r
-\r
-#define IMAGE_PROPERTIES_RECORD_SIGNATURE SIGNATURE_32 ('I','P','R','D')\r
-\r
-typedef struct {\r
- UINT32 Signature;\r
- LIST_ENTRY Link;\r
- EFI_PHYSICAL_ADDRESS ImageBase;\r
- UINT64 ImageSize;\r
- UINTN CodeSegmentCount;\r
- LIST_ENTRY CodeSegmentList;\r
-} IMAGE_PROPERTIES_RECORD;\r
-\r
#define IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('I','P','P','D')\r
\r
typedef struct {\r
\r
EFI_LOCK mPropertiesTableLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);\r
\r
+BOOLEAN mPropertiesTableEnable;\r
+\r
+BOOLEAN mPropertiesTableEndOfDxe = FALSE;\r
+\r
//\r
// Below functions are for MemoryMap\r
//\r
it is the size of new memory map after merge.\r
@param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.\r
**/\r
-STATIC\r
VOID\r
MergeMemoryMap (\r
IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,\r
CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof(EFI_MEMORY_DESCRIPTOR));\r
NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
\r
- MemoryBlockLength = (UINT64) (EfiPagesToSize (MemoryMapEntry->NumberOfPages));\r
- if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&\r
- (MemoryMapEntry->Type == NextMemoryMapEntry->Type) &&\r
- (MemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) &&\r
- ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart)) {\r
- NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;\r
- MemoryMapEntry = NextMemoryMapEntry;\r
- }\r
+ do {\r
+ MemoryBlockLength = (UINT64) (EfiPagesToSize (MemoryMapEntry->NumberOfPages));\r
+ if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&\r
+ (MemoryMapEntry->Type == NextMemoryMapEntry->Type) &&\r
+ (MemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) &&\r
+ ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart)) {\r
+ MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;\r
+ if (NewMemoryMapEntry != MemoryMapEntry) {\r
+ NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;\r
+ }\r
+\r
+ NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);\r
+ continue;\r
+ } else {\r
+ MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);\r
+ break;\r
+ }\r
+ } while (TRUE);\r
\r
MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize);\r
//\r
// DATA\r
//\r
- NewRecord->Type = EfiRuntimeServicesData;\r
+ if (!mPropertiesTableEnable) {\r
+ NewRecord->Type = TempRecord.Type;\r
+ } else {\r
+ NewRecord->Type = EfiRuntimeServicesData;\r
+ }\r
NewRecord->PhysicalStart = TempRecord.PhysicalStart;\r
NewRecord->VirtualStart = 0;\r
NewRecord->NumberOfPages = EfiSizeToPages(ImageRecordCodeSection->CodeSegmentBase - NewRecord->PhysicalStart);\r
//\r
// CODE\r
//\r
- NewRecord->Type = EfiRuntimeServicesCode;\r
+ if (!mPropertiesTableEnable) {\r
+ NewRecord->Type = TempRecord.Type;\r
+ } else {\r
+ NewRecord->Type = EfiRuntimeServicesCode;\r
+ }\r
NewRecord->PhysicalStart = ImageRecordCodeSection->CodeSegmentBase;\r
NewRecord->VirtualStart = 0;\r
NewRecord->NumberOfPages = EfiSizeToPages(ImageRecordCodeSection->CodeSegmentSize);\r
// Final DATA\r
//\r
if (TempRecord.PhysicalStart < ImageEnd) {\r
- NewRecord->Type = EfiRuntimeServicesData;\r
+ if (!mPropertiesTableEnable) {\r
+ NewRecord->Type = TempRecord.Type;\r
+ } else {\r
+ NewRecord->Type = EfiRuntimeServicesData;\r
+ }\r
NewRecord->PhysicalStart = TempRecord.PhysicalStart;\r
NewRecord->VirtualStart = 0;\r
NewRecord->NumberOfPages = EfiSizeToPages (ImageEnd - TempRecord.PhysicalStart);\r
UINT64 PhysicalEnd;\r
UINTN NewRecordCount;\r
UINTN TotalNewRecordCount;\r
+ BOOLEAN IsLastRecordData;\r
\r
if (MaxSplitRecordCount == 0) {\r
CopyMem (NewRecord, OldRecord, DescriptorSize);\r
// If this is still address in this record, need record.\r
//\r
NewRecord = PREVIOUS_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);\r
- if (NewRecord->Type == EfiRuntimeServicesData) {\r
+ IsLastRecordData = FALSE;\r
+ if (!mPropertiesTableEnable) {\r
+ if ((NewRecord->Attribute & EFI_MEMORY_XP) != 0) {\r
+ IsLastRecordData = TRUE;\r
+ }\r
+ } else {\r
+ if (NewRecord->Type == EfiRuntimeServicesData) {\r
+ IsLastRecordData = TRUE;\r
+ }\r
+ }\r
+ if (IsLastRecordData) {\r
//\r
// Last record is DATA, just merge it.\r
//\r
// Last record is CODE, create a new DATA entry.\r
//\r
NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);\r
- NewRecord->Type = EfiRuntimeServicesData;\r
+ if (!mPropertiesTableEnable) {\r
+ NewRecord->Type = TempRecord.Type;\r
+ } else {\r
+ NewRecord->Type = EfiRuntimeServicesData;\r
+ }\r
NewRecord->PhysicalStart = TempRecord.PhysicalStart;\r
NewRecord->VirtualStart = 0;\r
NewRecord->NumberOfPages = TempRecord.NumberOfPages;\r
TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart);\r
} while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));\r
\r
+ //\r
+ // The logic in function SplitTable() ensures that TotalNewRecordCount will not be zero if the\r
+ // code reaches here.\r
+ //\r
+ ASSERT (TotalNewRecordCount != 0);\r
return TotalNewRecordCount - 1;\r
}\r
\r
}\r
\r
/**\r
- This function for GetMemoryMap() with properties table.\r
+ This function for GetMemoryMap() with properties table capability.\r
\r
It calls original GetMemoryMap() to get the original memory map information. Then\r
plus the additional memory map entries for PE Code/Data seperation.\r
@retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
-CoreGetMemoryMapPropertiesTable (\r
+CoreGetMemoryMapWithSeparatedImageSection (\r
IN OUT UINTN *MemoryMapSize,\r
IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,\r
OUT UINTN *MapKey,\r
if (Status == EFI_BUFFER_TOO_SMALL) {\r
*MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount;\r
} else if (Status == EFI_SUCCESS) {\r
+ ASSERT (MemoryMap != NULL);\r
if (OldMemoryMapSize - *MemoryMapSize < (*DescriptorSize) * AdditionalRecordCount) {\r
*MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount;\r
//\r
//\r
\r
/**\r
- Set PropertiesTable accroding to PE/COFF image section alignment.\r
+ Set PropertiesTable according to PE/COFF image section alignment.\r
\r
@param SectionAlignment PE/COFF section alignment\r
**/\r
IN UINT32 SectionAlignment\r
)\r
{\r
- if (((SectionAlignment & (SIZE_4KB - 1)) != 0) &&\r
+ if (((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) &&\r
((mPropertiesTable.MemoryProtectionAttribute & EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) != 0)) {\r
DEBUG ((EFI_D_VERBOSE, "SetPropertiesTableSectionAlignment - Clear\n"));\r
- mPropertiesTable.MemoryProtectionAttribute &= ~EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA;\r
+ mPropertiesTable.MemoryProtectionAttribute &= ~((UINT64)EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);\r
gBS->GetMemoryMap = CoreGetMemoryMap;\r
gBS->Hdr.CRC32 = 0;\r
gBS->CalculateCrc32 ((UINT8 *)gBS, gBS->Hdr.HeaderSize, &gBS->Hdr.CRC32);\r
\r
@param ImageRecord image record to be sorted\r
**/\r
-STATIC\r
VOID\r
SortImageRecordCodeSection (\r
IN IMAGE_PROPERTIES_RECORD *ImageRecord\r
@retval TRUE image record is valid\r
@retval FALSE image record is invalid\r
**/\r
-STATIC\r
BOOLEAN\r
IsImageRecordCodeSectionValid (\r
IN IMAGE_PROPERTIES_RECORD *ImageRecord\r
IMAGE_PROPERTIES_RECORD *ImageRecord;\r
CHAR8 *PdbPointer;\r
IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;\r
- UINT16 Magic;\r
\r
DEBUG ((EFI_D_VERBOSE, "InsertImageRecord - 0x%x\n", RuntimeImage));\r
DEBUG ((EFI_D_VERBOSE, "InsertImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize));\r
\r
+ if (mPropertiesTableEndOfDxe) {\r
+ DEBUG ((DEBUG_INFO, "Do not insert runtime image record after EndOfDxe\n"));\r
+ return ;\r
+ }\r
+\r
ImageRecord = AllocatePool (sizeof(*ImageRecord));\r
if (ImageRecord == NULL) {\r
return ;\r
//\r
// Get SectionAlignment\r
//\r
- if (Hdr.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
- //\r
- // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value\r
- // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the\r
- // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC\r
- // then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC\r
- //\r
- Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
- } else {\r
- //\r
- // Get the magic value from the PE/COFF Optional Header\r
- //\r
- Magic = Hdr.Pe32->OptionalHeader.Magic;\r
- }\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment;\r
} else {\r
SectionAlignment = Hdr.Pe32Plus->OptionalHeader.SectionAlignment;\r
}\r
\r
SetPropertiesTableSectionAlignment (SectionAlignment);\r
- if ((SectionAlignment & (SIZE_4KB - 1)) != 0) {\r
- DEBUG ((EFI_D_ERROR, "!!!!!!!! InsertImageRecord - Section Alignment(0x%x) is not 4K !!!!!!!!\n", SectionAlignment));\r
+ if ((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) {\r
+ DEBUG ((EFI_D_WARN, "!!!!!!!! InsertImageRecord - Section Alignment(0x%x) is not %dK !!!!!!!!\n",\r
+ SectionAlignment, RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10));\r
PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageAddress);\r
if (PdbPointer != NULL) {\r
- DEBUG ((EFI_D_ERROR, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));\r
+ DEBUG ((EFI_D_WARN, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));\r
}\r
goto Finish;\r
}\r
InsertTailList (&mImagePropertiesPrivateData.ImageRecordList, &ImageRecord->Link);\r
mImagePropertiesPrivateData.ImageRecordCount++;\r
\r
- SortImageRecord ();\r
-\r
if (mImagePropertiesPrivateData.CodeSegmentCountMax < ImageRecord->CodeSegmentCount) {\r
mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount;\r
}\r
\r
+ SortImageRecord ();\r
+\r
Finish:\r
return ;\r
}\r
\r
/**\r
- Find image record accroding to image base and size.\r
+ Find image record according to image base and size.\r
\r
@param ImageBase Base of PE image\r
@param ImageSize Size of PE image\r
DEBUG ((EFI_D_VERBOSE, "RemoveImageRecord - 0x%x\n", RuntimeImage));\r
DEBUG ((EFI_D_VERBOSE, "RemoveImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize));\r
\r
+ if (mPropertiesTableEndOfDxe) {\r
+ DEBUG ((DEBUG_INFO, "Do not remove runtime image record after EndOfDxe\n"));\r
+ return ;\r
+ }\r
+\r
ImageRecord = FindImageRecord ((EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize);\r
if (ImageRecord == NULL) {\r
DEBUG ((EFI_D_ERROR, "!!!!!!!! ImageRecord not found !!!!!!!!\n"));\r
VOID *Context\r
)\r
{\r
- if (PcdGetBool (PropertiesTableEnable)) {\r
+ mPropertiesTableEndOfDxe = TRUE;\r
+ if (PcdGetBool (PcdPropertiesTableEnable)) {\r
EFI_STATUS Status;\r
\r
Status = gBS->InstallConfigurationTable (&gEfiPropertiesTableGuid, &mPropertiesTable);\r
\r
DEBUG ((EFI_D_INFO, "MemoryProtectionAttribute - 0x%016lx\n", mPropertiesTable.MemoryProtectionAttribute));\r
if ((mPropertiesTable.MemoryProtectionAttribute & EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {\r
+ DEBUG ((EFI_D_ERROR, "MemoryProtectionAttribute NON_EXECUTABLE_PE_DATA is not set, "));\r
+ DEBUG ((EFI_D_ERROR, "because Runtime Driver Section Alignment is not %dK.\n", RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10));\r
return ;\r
}\r
\r
- gBS->GetMemoryMap = CoreGetMemoryMapPropertiesTable;\r
+ gBS->GetMemoryMap = CoreGetMemoryMapWithSeparatedImageSection;\r
gBS->Hdr.CRC32 = 0;\r
gBS->CalculateCrc32 ((UINT8 *)gBS, gBS->Hdr.HeaderSize, &gBS->Hdr.CRC32);\r
\r
DEBUG ((EFI_D_VERBOSE, "Total Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));\r
DEBUG ((EFI_D_VERBOSE, "Dump ImageRecord:\n"));\r
DumpImageRecord ();\r
+\r
+ mPropertiesTableEnable = TRUE;\r
}\r
}\r
\r