IntelFrameworkModulePkg AcpiS3SaveDxe: Reduce reserved memory consumption

Reduce reserved memory consumption by page table buffer,
then OS can have more available memory to use.
Take PhysicalAddressBits = 48 and 2MB page granularity as example,
1:1 Virtual to Physical identity mapping page table buffer needs to be
((512 + 1) * 512 + 1) * 4096 = 1075843072 bytes = 0x40201000 bytes.

When BIOS does not support long mode waking vector, only allocate
2 pages (1G page enabled) or 6 pages for 4G page table, and 8 extra
pages to handles > 4G request by page fault.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18068 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Star Zeng 2015-07-27 03:04:03 +00:00 committed by lzeng14
parent c6368abcf0
commit 353f5ba92f
2 changed files with 128 additions and 78 deletions

View File

@ -2,7 +2,7 @@
This is an implementation of the ACPI S3 Save protocol. This is defined in This is an implementation of the ACPI S3 Save protocol. This is defined in
S3 boot path specification 0.9. S3 boot path specification 0.9.
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions are licensed and made available under the terms and conditions
@ -32,6 +32,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "AcpiS3Save.h" #include "AcpiS3Save.h"
//
// 8 extra pages for PF handler.
//
#define EXTRA_PAGE_TABLE_PAGES 8
/** /**
Hook point for AcpiVariableThunkPlatform for InstallAcpiS3Save. Hook point for AcpiVariableThunkPlatform for InstallAcpiS3Save.
**/ **/
@ -303,21 +308,61 @@ FindAcpiFacsTable (
} }
/** /**
Allocates and fills in the Page Directory and Page Table Entries to The function will check if long mode waking vector is supported.
establish a 1:1 Virtual to Physical mapping.
@param[in] Facs Pointer to FACS table.
@retval TRUE Long mode waking vector is supported.
@retval FALSE Long mode waking vector is not supported.
**/
BOOLEAN
IsLongModeWakingVectorSupport (
IN EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs
)
{
if ((Facs == NULL) ||
(Facs->Signature != EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ) {
//
// Something wrong with FACS.
//
return FALSE;
}
if (Facs->XFirmwareWakingVector != 0) {
if ((Facs->Version == EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) &&
((Facs->Flags & EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F) != 0)) {
//
// BIOS supports 64bit waking vector.
//
if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
return TRUE;
}
}
}
return FALSE;
}
/**
Allocates page table buffer.
@param[in] LongModeWakingVectorSupport Support long mode waking vector or not.
If BootScriptExector driver will run in 64-bit mode, this function will establish the 1:1 If BootScriptExector driver will run in 64-bit mode, this function will establish the 1:1
virtual to physical mapping page table. virtual to physical mapping page table when long mode waking vector is supported, otherwise
create 4G page table when long mode waking vector is not supported and let PF handler to
handle > 4G request.
If BootScriptExector driver will not run in 64-bit mode, this function will do nothing. If BootScriptExector driver will not run in 64-bit mode, this function will do nothing.
@return the 1:1 Virtual to Physical identity mapping page table base address. @return Page table base address.
**/ **/
EFI_PHYSICAL_ADDRESS EFI_PHYSICAL_ADDRESS
S3CreateIdentityMappingPageTables ( S3AllocatePageTablesBuffer (
VOID IN BOOLEAN LongModeWakingVectorSupport
) )
{ {
if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) { if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
UINTN ExtraPageTablePages;
UINT32 RegEax; UINT32 RegEax;
UINT32 RegEdx; UINT32 RegEdx;
UINT8 PhysicalAddressBits; UINT8 PhysicalAddressBits;
@ -328,10 +373,6 @@ S3CreateIdentityMappingPageTables (
VOID *Hob; VOID *Hob;
BOOLEAN Page1GSupport; BOOLEAN Page1GSupport;
S3NvsPageTableAddress = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdIdentifyMappingPageTablePtr);
if (S3NvsPageTableAddress != 0x0) {
return S3NvsPageTableAddress;
} else {
Page1GSupport = FALSE; Page1GSupport = FALSE;
if (PcdGetBool(PcdUse1GPageTable)) { if (PcdGetBool(PcdUse1GPageTable)) {
AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
@ -367,6 +408,16 @@ S3CreateIdentityMappingPageTables (
PhysicalAddressBits = 48; PhysicalAddressBits = 48;
} }
ExtraPageTablePages = 0;
if (!LongModeWakingVectorSupport) {
//
// Create 4G page table when BIOS does not support long mode waking vector,
// and let PF handler to handle > 4G request.
//
PhysicalAddressBits = 32;
ExtraPageTablePages = EXTRA_PAGE_TABLE_PAGES;
}
// //
// Calculate the table entries needed. // Calculate the table entries needed.
// //
@ -386,16 +437,16 @@ S3CreateIdentityMappingPageTables (
} else { } else {
TotalPageTableSize = (UINTN)(1 + NumberOfPml4EntriesNeeded); TotalPageTableSize = (UINTN)(1 + NumberOfPml4EntriesNeeded);
} }
DEBUG ((EFI_D_ERROR, "TotalPageTableSize - %x pages\n", TotalPageTableSize));
TotalPageTableSize += ExtraPageTablePages;
DEBUG ((EFI_D_ERROR, "AcpiS3Save TotalPageTableSize - 0x%x pages\n", TotalPageTableSize));
// //
// By architecture only one PageMapLevel4 exists - so lets allocate storage for it. // By architecture only one PageMapLevel4 exists - so lets allocate storage for it.
// //
S3NvsPageTableAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, EFI_PAGES_TO_SIZE(TotalPageTableSize)); S3NvsPageTableAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, EFI_PAGES_TO_SIZE(TotalPageTableSize));
ASSERT (S3NvsPageTableAddress != 0); ASSERT (S3NvsPageTableAddress != 0);
PcdSet64 (PcdIdentifyMappingPageTablePtr, S3NvsPageTableAddress);
return S3NvsPageTableAddress; return S3NvsPageTableAddress;
}
} else { } else {
// //
// If DXE is running 32-bit mode, no need to establish page table. // If DXE is running 32-bit mode, no need to establish page table.
@ -457,6 +508,7 @@ S3Ready (
STATIC BOOLEAN AlreadyEntered; STATIC BOOLEAN AlreadyEntered;
IA32_DESCRIPTOR *Idtr; IA32_DESCRIPTOR *Idtr;
IA32_IDT_GATE_DESCRIPTOR *IdtGate; IA32_IDT_GATE_DESCRIPTOR *IdtGate;
EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;
DEBUG ((EFI_D_INFO, "S3Ready!\n")); DEBUG ((EFI_D_INFO, "S3Ready!\n"));
@ -476,7 +528,8 @@ S3Ready (
// //
// Get ACPI Table because we will save its position to variable // Get ACPI Table because we will save its position to variable
// //
AcpiS3Context->AcpiFacsTable = (EFI_PHYSICAL_ADDRESS)(UINTN)FindAcpiFacsTable (); Facs = (EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) FindAcpiFacsTable ();
AcpiS3Context->AcpiFacsTable = (EFI_PHYSICAL_ADDRESS) (UINTN) Facs;
ASSERT (AcpiS3Context->AcpiFacsTable != 0); ASSERT (AcpiS3Context->AcpiFacsTable != 0);
IdtGate = AllocateMemoryBelow4G (EfiReservedMemoryType, sizeof(IA32_IDT_GATE_DESCRIPTOR) * 0x100 + sizeof(IA32_DESCRIPTOR)); IdtGate = AllocateMemoryBelow4G (EfiReservedMemoryType, sizeof(IA32_IDT_GATE_DESCRIPTOR) * 0x100 + sizeof(IA32_DESCRIPTOR));
@ -498,7 +551,7 @@ S3Ready (
// //
// Allocate page table // Allocate page table
// //
AcpiS3Context->S3NvsPageTableAddress = S3CreateIdentityMappingPageTables (); AcpiS3Context->S3NvsPageTableAddress = S3AllocatePageTablesBuffer (IsLongModeWakingVectorSupport (Facs));
// //
// Allocate stack // Allocate stack

View File

@ -1,7 +1,7 @@
## @file ## @file
# AcpiS3Save module installs ACPI S3 Save protocol to prepare S3 boot data. # AcpiS3Save module installs ACPI S3 Save protocol to prepare S3 boot data.
# #
# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
# #
# This program and the accompanying materials are # This program and the accompanying materials are
# licensed and made available under the terms and conditions of the BSD License # licensed and made available under the terms and conditions of the BSD License
@ -77,9 +77,6 @@
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize ## SOMETIMES_CONSUMES gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize ## SOMETIMES_CONSUMES
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3BootScriptStackSize ## CONSUMES gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3BootScriptStackSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## CONSUMES
## SOMETIMES_CONSUMES
## SOMETIMES_PRODUCES
gEfiMdeModulePkgTokenSpaceGuid.PcdIdentifyMappingPageTablePtr
[Depex] [Depex]
# #