mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-26 23:24:03 +02:00
UefiCpuPkg/RegisterCpuFeaturesLib: Combine implementation.
V1 changes: > Current code logic can't confirm CpuS3DataDxe driver start before > CpuFeaturesDxe driver. So the assumption in CpuFeaturesDxe not valid. > Add implementation for AllocateAcpiCpuData function to remove this > assumption. V2 changes: > Because CpuS3Data memory will be copy to smram at SmmReadToLock point, > so the memory type no need to be ACPI NVS type, also the address not > limit to below 4G. > This change remove the limit of ACPI NVS memory type and below 4G. V3 changes: > Remove function definition in header file. > Add STATIC in function implementation. Pass OS boot and resume from S3 test. Bugz: https://bugzilla.tianocore.org/show_bug.cgi?id=959 Reported-by: Marvin Häuser <Marvin.Haeuser@outlook.com> Suggested-by: Fan Jeff <vanjeff_919@hotmail.com> Cc: Marvin Häuser <Marvin.Haeuser@outlook.com> Cc: Fan Jeff <vanjeff_919@hotmail.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Eric Dong <eric.dong@intel.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
This commit is contained in:
parent
6eab8b4368
commit
a6daab1f6c
@ -197,70 +197,3 @@ GetNumberOfProcessor (
|
|||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Allocates ACPI NVS memory to save ACPI_CPU_DATA.
|
|
||||||
|
|
||||||
@return Pointer to allocated ACPI_CPU_DATA.
|
|
||||||
**/
|
|
||||||
ACPI_CPU_DATA *
|
|
||||||
AllocateAcpiCpuData (
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// CpuS3DataDxe will do it.
|
|
||||||
//
|
|
||||||
ASSERT (FALSE);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Enlarges CPU register table for each processor.
|
|
||||||
|
|
||||||
@param[in, out] RegisterTable Pointer processor's CPU register table
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
EnlargeRegisterTable (
|
|
||||||
IN OUT CPU_REGISTER_TABLE *RegisterTable
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_PHYSICAL_ADDRESS Address;
|
|
||||||
UINTN AllocatePages;
|
|
||||||
|
|
||||||
Address = BASE_4GB - 1;
|
|
||||||
AllocatePages = RegisterTable->AllocatedSize / EFI_PAGE_SIZE;
|
|
||||||
Status = gBS->AllocatePages (
|
|
||||||
AllocateMaxAddress,
|
|
||||||
EfiACPIMemoryNVS,
|
|
||||||
AllocatePages + 1,
|
|
||||||
&Address
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
//
|
|
||||||
// If there are records existing in the register table, then copy its contents
|
|
||||||
// to new region and free the old one.
|
|
||||||
//
|
|
||||||
if (RegisterTable->AllocatedSize > 0) {
|
|
||||||
CopyMem (
|
|
||||||
(VOID *) (UINTN) Address,
|
|
||||||
(VOID *) (UINTN) RegisterTable->RegisterTableEntry,
|
|
||||||
RegisterTable->AllocatedSize
|
|
||||||
);
|
|
||||||
//
|
|
||||||
// RegisterTableEntry is allocated by gBS->AllocatePages() service.
|
|
||||||
// So, gBS->FreePages() service is used to free it.
|
|
||||||
//
|
|
||||||
gBS->FreePages (
|
|
||||||
RegisterTable->RegisterTableEntry,
|
|
||||||
AllocatePages
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Adjust the allocated size and register table base address.
|
|
||||||
//
|
|
||||||
RegisterTable->AllocatedSize += EFI_PAGE_SIZE;
|
|
||||||
RegisterTable->RegisterTableEntry = Address;
|
|
||||||
}
|
|
||||||
|
@ -257,134 +257,3 @@ GetNumberOfProcessor (
|
|||||||
);
|
);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Allocates ACPI NVS memory to save ACPI_CPU_DATA.
|
|
||||||
|
|
||||||
@return Pointer to allocated ACPI_CPU_DATA.
|
|
||||||
**/
|
|
||||||
ACPI_CPU_DATA *
|
|
||||||
AllocateAcpiCpuData (
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_PEI_MP_SERVICES_PPI *CpuMpPpi;
|
|
||||||
UINTN NumberOfCpus;
|
|
||||||
UINTN NumberOfEnabledProcessors;
|
|
||||||
ACPI_CPU_DATA *AcpiCpuData;
|
|
||||||
EFI_PHYSICAL_ADDRESS Address;
|
|
||||||
UINTN TableSize;
|
|
||||||
CPU_REGISTER_TABLE *RegisterTable;
|
|
||||||
UINTN Index;
|
|
||||||
EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;
|
|
||||||
|
|
||||||
Status = PeiServicesAllocatePages (
|
|
||||||
EfiACPIMemoryNVS,
|
|
||||||
EFI_SIZE_TO_PAGES (sizeof (ACPI_CPU_DATA)),
|
|
||||||
&Address
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
AcpiCpuData = (ACPI_CPU_DATA *) (UINTN) Address;
|
|
||||||
ASSERT (AcpiCpuData != NULL);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get MP Services Protocol
|
|
||||||
//
|
|
||||||
Status = PeiServicesLocatePpi (
|
|
||||||
&gEfiPeiMpServicesPpiGuid,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
(VOID **)&CpuMpPpi
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get the number of CPUs
|
|
||||||
//
|
|
||||||
Status = CpuMpPpi->GetNumberOfProcessors (
|
|
||||||
GetPeiServicesTablePointer (),
|
|
||||||
CpuMpPpi,
|
|
||||||
&NumberOfCpus,
|
|
||||||
&NumberOfEnabledProcessors
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
AcpiCpuData->NumberOfCpus = (UINT32)NumberOfCpus;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs
|
|
||||||
//
|
|
||||||
TableSize = 2 * NumberOfCpus * sizeof (CPU_REGISTER_TABLE);
|
|
||||||
Status = PeiServicesAllocatePages (
|
|
||||||
EfiACPIMemoryNVS,
|
|
||||||
EFI_SIZE_TO_PAGES (TableSize),
|
|
||||||
&Address
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
RegisterTable = (CPU_REGISTER_TABLE *) (UINTN) Address;
|
|
||||||
|
|
||||||
for (Index = 0; Index < NumberOfCpus; Index++) {
|
|
||||||
Status = CpuMpPpi->GetProcessorInfo (
|
|
||||||
GetPeiServicesTablePointer (),
|
|
||||||
CpuMpPpi,
|
|
||||||
Index,
|
|
||||||
&ProcessorInfoBuffer
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
RegisterTable[Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;
|
|
||||||
RegisterTable[Index].TableLength = 0;
|
|
||||||
RegisterTable[Index].AllocatedSize = 0;
|
|
||||||
RegisterTable[Index].RegisterTableEntry = 0;
|
|
||||||
|
|
||||||
RegisterTable[NumberOfCpus + Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;
|
|
||||||
RegisterTable[NumberOfCpus + Index].TableLength = 0;
|
|
||||||
RegisterTable[NumberOfCpus + Index].AllocatedSize = 0;
|
|
||||||
RegisterTable[NumberOfCpus + Index].RegisterTableEntry = 0;
|
|
||||||
}
|
|
||||||
AcpiCpuData->RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTable;
|
|
||||||
AcpiCpuData->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)(RegisterTable + NumberOfCpus);
|
|
||||||
|
|
||||||
return AcpiCpuData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Enlarges CPU register table for each processor.
|
|
||||||
|
|
||||||
@param[in, out] RegisterTable Pointer processor's CPU register table
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
EnlargeRegisterTable (
|
|
||||||
IN OUT CPU_REGISTER_TABLE *RegisterTable
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_PHYSICAL_ADDRESS Address;
|
|
||||||
UINTN AllocatePages;
|
|
||||||
|
|
||||||
AllocatePages = RegisterTable->AllocatedSize / EFI_PAGE_SIZE;
|
|
||||||
Status = PeiServicesAllocatePages (
|
|
||||||
EfiACPIMemoryNVS,
|
|
||||||
AllocatePages + 1,
|
|
||||||
&Address
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
//
|
|
||||||
// If there are records existing in the register table, then copy its contents
|
|
||||||
// to new region and free the old one.
|
|
||||||
//
|
|
||||||
if (RegisterTable->AllocatedSize > 0) {
|
|
||||||
CopyMem (
|
|
||||||
(VOID *) (UINTN) Address,
|
|
||||||
(VOID *) (UINTN) RegisterTable->RegisterTableEntry,
|
|
||||||
RegisterTable->AllocatedSize
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Adjust the allocated size and register table base address.
|
|
||||||
//
|
|
||||||
RegisterTable->AllocatedSize += EFI_PAGE_SIZE;
|
|
||||||
RegisterTable->RegisterTableEntry = Address;
|
|
||||||
}
|
|
||||||
|
@ -87,26 +87,6 @@ GetCpuFeaturesData (
|
|||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
Enlarges CPU register table for each processor.
|
|
||||||
|
|
||||||
@param[in, out] RegisterTable Pointer processor's CPU register table
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
EnlargeRegisterTable (
|
|
||||||
IN OUT CPU_REGISTER_TABLE *RegisterTable
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Allocates ACPI NVS memory to save ACPI_CPU_DATA.
|
|
||||||
|
|
||||||
@return Pointer to allocated ACPI_CPU_DATA.
|
|
||||||
**/
|
|
||||||
ACPI_CPU_DATA *
|
|
||||||
AllocateAcpiCpuData (
|
|
||||||
VOID
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Worker function to return processor index.
|
Worker function to return processor index.
|
||||||
|
|
||||||
|
@ -488,6 +488,98 @@ RegisterCpuFeature (
|
|||||||
return RETURN_SUCCESS;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Allocates boot service data to save ACPI_CPU_DATA.
|
||||||
|
|
||||||
|
@return Pointer to allocated ACPI_CPU_DATA.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
ACPI_CPU_DATA *
|
||||||
|
AllocateAcpiCpuData (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN NumberOfCpus;
|
||||||
|
UINTN NumberOfEnabledProcessors;
|
||||||
|
ACPI_CPU_DATA *AcpiCpuData;
|
||||||
|
UINTN TableSize;
|
||||||
|
CPU_REGISTER_TABLE *RegisterTable;
|
||||||
|
UINTN Index;
|
||||||
|
EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;
|
||||||
|
|
||||||
|
AcpiCpuData = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ACPI_CPU_DATA)));
|
||||||
|
ASSERT (AcpiCpuData != NULL);
|
||||||
|
|
||||||
|
GetNumberOfProcessor (&NumberOfCpus, &NumberOfEnabledProcessors);
|
||||||
|
AcpiCpuData->NumberOfCpus = (UINT32)NumberOfCpus;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs
|
||||||
|
//
|
||||||
|
TableSize = 2 * NumberOfCpus * sizeof (CPU_REGISTER_TABLE);
|
||||||
|
RegisterTable = AllocatePages (EFI_SIZE_TO_PAGES (TableSize));
|
||||||
|
ASSERT (RegisterTable != NULL);
|
||||||
|
|
||||||
|
for (Index = 0; Index < NumberOfCpus; Index++) {
|
||||||
|
Status = GetProcessorInformation (Index, &ProcessorInfoBuffer);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
RegisterTable[Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;
|
||||||
|
RegisterTable[Index].TableLength = 0;
|
||||||
|
RegisterTable[Index].AllocatedSize = 0;
|
||||||
|
RegisterTable[Index].RegisterTableEntry = 0;
|
||||||
|
|
||||||
|
RegisterTable[NumberOfCpus + Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;
|
||||||
|
RegisterTable[NumberOfCpus + Index].TableLength = 0;
|
||||||
|
RegisterTable[NumberOfCpus + Index].AllocatedSize = 0;
|
||||||
|
RegisterTable[NumberOfCpus + Index].RegisterTableEntry = 0;
|
||||||
|
}
|
||||||
|
AcpiCpuData->RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTable;
|
||||||
|
AcpiCpuData->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)(RegisterTable + NumberOfCpus);
|
||||||
|
|
||||||
|
return AcpiCpuData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enlarges CPU register table for each processor.
|
||||||
|
|
||||||
|
@param[in, out] RegisterTable Pointer processor's CPU register table
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
EnlargeRegisterTable (
|
||||||
|
IN OUT CPU_REGISTER_TABLE *RegisterTable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_PHYSICAL_ADDRESS Address;
|
||||||
|
UINTN UsedPages;
|
||||||
|
|
||||||
|
UsedPages = RegisterTable->AllocatedSize / EFI_PAGE_SIZE;
|
||||||
|
Address = (UINTN)AllocatePages (UsedPages + 1);
|
||||||
|
ASSERT (Address != 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// If there are records existing in the register table, then copy its contents
|
||||||
|
// to new region and free the old one.
|
||||||
|
//
|
||||||
|
if (RegisterTable->AllocatedSize > 0) {
|
||||||
|
CopyMem (
|
||||||
|
(VOID *) (UINTN) Address,
|
||||||
|
(VOID *) (UINTN) RegisterTable->RegisterTableEntry,
|
||||||
|
RegisterTable->AllocatedSize
|
||||||
|
);
|
||||||
|
|
||||||
|
FreePages ((VOID *)(UINTN)RegisterTable->RegisterTableEntry, UsedPages);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Adjust the allocated size and register table base address.
|
||||||
|
//
|
||||||
|
RegisterTable->AllocatedSize += EFI_PAGE_SIZE;
|
||||||
|
RegisterTable->RegisterTableEntry = Address;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Add an entry in specified register table.
|
Add an entry in specified register table.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user