/** @file
Acpi Gnvs Init Library.
Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/**
A protocol callback which updates MMIO Base and Length in SA GNVS area
@param[in] Event - The triggered event.
@param[in] Context - Context for this event.
**/
VOID
EFIAPI
UpdateSaGnvsForMmioResourceBaseLength (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
SYSTEM_AGENT_GLOBAL_NVS_AREA_PROTOCOL *SaGlobalNvsAreaProtocol;
Status = gBS->LocateProtocol (&gSaGlobalNvsAreaProtocolGuid, NULL, (VOID **) &SaGlobalNvsAreaProtocol);
if (Status != EFI_SUCCESS) {
return;
}
gBS->CloseEvent (Event);
//
// Configure MMIO Base/Length. This logic is only valid for platforms that use PciHostBridgeLibSimple.
//
DEBUG ((DEBUG_INFO, "[BoardAcpiDxe] Update SA GNVS Area.\n"));
SaGlobalNvsAreaProtocol->Area->Mmio32Base = PcdGet32 (PcdPciReservedMemBase);
if (PcdGet32 (PcdPciReservedMemLimit) != 0) {
SaGlobalNvsAreaProtocol->Area->Mmio32Length = PcdGet32 (PcdPciReservedMemLimit) - PcdGet32 (PcdPciReservedMemBase) + 1;
} else {
SaGlobalNvsAreaProtocol->Area->Mmio32Length = ((UINT32) PcdGet64 (PcdPciExpressBaseAddress)) - PcdGet32 (PcdPciReservedMemBase);
}
if (PcdGet64 (PcdPciReservedMemAbove4GBLimit) > PcdGet64 (PcdPciReservedMemAbove4GBBase)) {
SaGlobalNvsAreaProtocol->Area->Mmio64Base = PcdGet64 (PcdPciReservedMemAbove4GBBase);
SaGlobalNvsAreaProtocol->Area->Mmio64Length = PcdGet64 (PcdPciReservedMemAbove4GBLimit) - PcdGet64 (PcdPciReservedMemAbove4GBBase) + 1;
}
}
/**
@brief
Global NVS initialize.
@param[in] GlobalNvs - Pointer of Global NVS area
@retval EFI_SUCCESS - Allocate Global NVS completed.
@retval EFI_OUT_OF_RESOURCES - Failed to allocate required page for GNVS.
**/
EFI_STATUS
EFIAPI
AcpiGnvsInit (
IN OUT VOID **GlobalNvs
)
{
UINTN Pages;
EFI_PHYSICAL_ADDRESS Address;
EFI_STATUS Status;
EFI_GLOBAL_NVS_AREA_PROTOCOL *GNVS;
EFI_MP_SERVICES_PROTOCOL *MpService;
UINTN NumberOfCPUs;
UINTN NumberOfEnabledCPUs;
VOID *SaGlobalNvsRegistration;
Pages = EFI_SIZE_TO_PAGES (sizeof (EFI_GLOBAL_NVS_AREA));
Address = 0xffffffff; // allocate address below 4G.
Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiACPIMemoryNVS,
Pages,
&Address
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR(Status)) {
return Status;
}
//
// Locate the MP services protocol
// Find the MP Protocol. This is an MP platform, so MP protocol must be there.
//
Status = gBS->LocateProtocol (
&gEfiMpServiceProtocolGuid,
NULL,
(VOID **) &MpService
);
ASSERT_EFI_ERROR (Status);
//
// Determine the number of processors
//
MpService->GetNumberOfProcessors (
MpService,
&NumberOfCPUs,
&NumberOfEnabledCPUs
);
*GlobalNvs = (VOID *) (UINTN) Address;
SetMem (*GlobalNvs, sizeof (EFI_GLOBAL_NVS_AREA), 0);
//
// GNVS default value init here...
//
GNVS = (EFI_GLOBAL_NVS_AREA_PROTOCOL *) &Address;
GNVS->Area->ThreadCount = (UINT8)NumberOfEnabledCPUs;
//
// Miscellaneous
//
GNVS->Area->PL1LimitCS = 0;
GNVS->Area->PL1LimitCSValue = 4500;
//
// Update SA GNVS with MMIO Base/Length
//
EfiCreateProtocolNotifyEvent (
&gSaGlobalNvsAreaProtocolGuid,
TPL_CALLBACK,
UpdateSaGnvsForMmioResourceBaseLength,
NULL,
&SaGlobalNvsRegistration
);
return EFI_SUCCESS;
}