-\r
-/**\r
- Allocates ACPI NVS memory to save ACPI_CPU_DATA.\r
-\r
- @return Pointer to allocated ACPI_CPU_DATA.\r
-**/\r
-ACPI_CPU_DATA *\r
-AllocateAcpiCpuData (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_PEI_MP_SERVICES_PPI *CpuMpPpi;\r
- UINTN NumberOfCpus;\r
- UINTN NumberOfEnabledProcessors;\r
- ACPI_CPU_DATA *AcpiCpuData;\r
- EFI_PHYSICAL_ADDRESS Address;\r
- UINTN TableSize;\r
- CPU_REGISTER_TABLE *RegisterTable;\r
- UINTN Index;\r
- EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;\r
-\r
- Status = PeiServicesAllocatePages (\r
- EfiACPIMemoryNVS,\r
- EFI_SIZE_TO_PAGES (sizeof (ACPI_CPU_DATA)),\r
- &Address\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- AcpiCpuData = (ACPI_CPU_DATA *) (UINTN) Address;\r
- ASSERT (AcpiCpuData != NULL);\r
-\r
- //\r
- // Get MP Services Protocol\r
- //\r
- Status = PeiServicesLocatePpi (\r
- &gEfiPeiMpServicesPpiGuid,\r
- 0,\r
- NULL,\r
- (VOID **)&CpuMpPpi\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Get the number of CPUs\r
- //\r
- Status = CpuMpPpi->GetNumberOfProcessors (\r
- GetPeiServicesTablePointer (),\r
- CpuMpPpi,\r
- &NumberOfCpus,\r
- &NumberOfEnabledProcessors\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- AcpiCpuData->NumberOfCpus = (UINT32)NumberOfCpus;\r
-\r
- //\r
- // Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs\r
- //\r
- TableSize = 2 * NumberOfCpus * sizeof (CPU_REGISTER_TABLE);\r
- Status = PeiServicesAllocatePages (\r
- EfiACPIMemoryNVS,\r
- EFI_SIZE_TO_PAGES (TableSize),\r
- &Address\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- RegisterTable = (CPU_REGISTER_TABLE *) (UINTN) Address;\r
-\r
- for (Index = 0; Index < NumberOfCpus; Index++) {\r
- Status = CpuMpPpi->GetProcessorInfo (\r
- GetPeiServicesTablePointer (),\r
- CpuMpPpi,\r
- Index,\r
- &ProcessorInfoBuffer\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- RegisterTable[Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;\r
- RegisterTable[Index].TableLength = 0;\r
- RegisterTable[Index].AllocatedSize = 0;\r
- RegisterTable[Index].RegisterTableEntry = 0;\r
-\r
- RegisterTable[NumberOfCpus + Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;\r
- RegisterTable[NumberOfCpus + Index].TableLength = 0;\r
- RegisterTable[NumberOfCpus + Index].AllocatedSize = 0;\r
- RegisterTable[NumberOfCpus + Index].RegisterTableEntry = 0;\r
- }\r
- AcpiCpuData->RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTable;\r
- AcpiCpuData->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)(RegisterTable + NumberOfCpus);\r
-\r
- return AcpiCpuData;\r
-}\r
-\r
-/**\r
- Enlarges CPU register table for each processor.\r
-\r
- @param[in, out] RegisterTable Pointer processor's CPU register table\r
-**/\r
-VOID\r
-EnlargeRegisterTable (\r
- IN OUT CPU_REGISTER_TABLE *RegisterTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_PHYSICAL_ADDRESS Address;\r
- UINTN AllocatePages;\r
-\r
- AllocatePages = RegisterTable->AllocatedSize / EFI_PAGE_SIZE;\r
- Status = PeiServicesAllocatePages (\r
- EfiACPIMemoryNVS,\r
- AllocatePages + 1,\r
- &Address\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // If there are records existing in the register table, then copy its contents\r
- // to new region and free the old one.\r
- //\r
- if (RegisterTable->AllocatedSize > 0) {\r
- CopyMem (\r
- (VOID *) (UINTN) Address,\r
- (VOID *) (UINTN) RegisterTable->RegisterTableEntry,\r
- RegisterTable->AllocatedSize\r
- );\r
- }\r
-\r
- //\r
- // Adjust the allocated size and register table base address.\r
- //\r
- RegisterTable->AllocatedSize += EFI_PAGE_SIZE;\r
- RegisterTable->RegisterTableEntry = Address;\r
-}\r