123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- /** @file
- Dxe ResetSystem library implementation.
- Copyright (c) 2022 Loongson Technology Corporation Limited. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <Base.h>
- #include <Library/DebugLib.h>
- #include <Library/UefiRuntimeLib.h> // EfiConvertPointer()
- #include <Library/DxeServicesTableLib.h>
- #include <Library/UefiBootServicesTableLib.h>
- #include "ResetSystemAcpiGed.h"
- #include <Library/UefiLib.h>
- /**
- Modifies the attributes to Runtime type for a page size memory region.
- @param BaseAddress Specified start address
- @retval EFI_SUCCESS The attributes were set for the memory region.
- @retval EFI_INVALID_PARAMETER Length is zero.
- @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
- resource range specified by BaseAddress and Length.
- @retval EFI_UNSUPPORTED The bit mask of attributes is not support for the memory resource
- range specified by BaseAddress and Length.
- @retval EFI_ACCESS_DEFINED The attributes for the memory resource range specified by
- BaseAddress and Length cannot be modified.
- @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
- the memory resource range.
- @retval EFI_NOT_AVAILABLE_YET The attributes cannot be set because CPU architectural protocol is
- not available yet.
- **/
- EFI_STATUS
- SetMemoryAttributesRunTime (
- UINTN Address
- )
- {
- EFI_STATUS Status;
- EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
- Address &= ~EFI_PAGE_MASK;
- Status = gDS->GetMemorySpaceDescriptor (Address, &Descriptor);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, "%a: GetMemorySpaceDescriptor failed\n", __FUNCTION__));
- return Status;
- }
- if (Descriptor.GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
- Status = gDS->AddMemorySpace (
- EfiGcdMemoryTypeMemoryMappedIo,
- Address,
- EFI_PAGE_SIZE,
- EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, "%a: AddMemorySpace failed\n", __FUNCTION__));
- return Status;
- }
- Status = gDS->SetMemorySpaceAttributes (
- Address,
- EFI_PAGE_SIZE,
- EFI_MEMORY_RUNTIME
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, "%a:%d SetMemorySpaceAttributes failed\n", __FUNCTION__, __LINE__));
- return Status;
- }
- } else if (!(Descriptor.Attributes & EFI_MEMORY_RUNTIME)) {
- Status = gDS->SetMemorySpaceAttributes (
- Address,
- EFI_PAGE_SIZE,
- Descriptor.Attributes | EFI_MEMORY_RUNTIME
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, "%a:%d SetMemorySpaceAttributes failed\n", __FUNCTION__, __LINE__));
- return Status;
- }
- }
- return EFI_SUCCESS;
- }
- /**
- Find the power manager related info from ACPI table
- @retval RETURN_SUCCESS Successfully find out all the required information.
- @retval RETURN_NOT_FOUND Failed to find the required info.
- **/
- STATIC EFI_STATUS
- GetPowerManagerByParseAcpiInfo (
- VOID
- )
- {
- EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt = NULL;
- EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp = NULL;
- EFI_ACPI_DESCRIPTION_HEADER *Xsdt = NULL;
- EFI_ACPI_DESCRIPTION_HEADER *Rsdt = NULL;
- UINT32 *Entry32 = NULL;
- UINTN Entry32Num;
- UINT32 *Signature = NULL;
- UINTN Idx;
- EFI_STATUS Status;
- Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, (VOID **)&Rsdp);
- if (EFI_ERROR (Status)) {
- Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **)&Rsdp);
- }
- if (EFI_ERROR (Status) || (Rsdp == NULL)) {
- DEBUG ((DEBUG_ERROR, "EFI_ERROR or Rsdp == NULL\n"));
- return RETURN_NOT_FOUND;
- }
- Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->RsdtAddress;
- Entry32 = (UINT32 *)(UINTN)(Rsdt + 1);
- Entry32Num = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> 2;
- for (Idx = 0; Idx < Entry32Num; Idx++) {
- Signature = (UINT32 *)(UINTN)Entry32[Idx];
- if (*Signature == EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
- Fadt = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature;
- DEBUG ((DEBUG_INFO, "Found Fadt in Rsdt\n"));
- goto Done;
- }
- }
- Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)Rsdp->XsdtAddress;
- Entry32 = (UINT32 *)(Xsdt + 1);
- Entry32Num = (Xsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> 2;
- for (Idx = 0; Idx < Entry32Num; Idx++) {
- Signature = (UINT32 *)(UINTN)Entry32[Idx];
- if (*Signature == EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
- Fadt = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature;
- DEBUG ((DEBUG_INFO, "Found Fadt in Xsdt\n"));
- goto Done;
- }
- }
- DEBUG ((DEBUG_ERROR, " Fadt Not Found\n"));
- return RETURN_NOT_FOUND;
- Done:
- mPowerManager.ResetRegAddr = Fadt->ResetReg.Address;
- mPowerManager.ResetValue = Fadt->ResetValue;
- mPowerManager.SleepControlRegAddr = Fadt->SleepControlReg.Address;
- mPowerManager.SleepStatusRegAddr = Fadt->SleepStatusReg.Address;
- return RETURN_SUCCESS;
- }
- /**
- This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
- event. It converts a pointer to a new virtual address.
- @param[in] Event Event whose notification function is being invoked.
- @param[in] Context Pointer to the notification function's context
- **/
- VOID
- EFIAPI
- ResetSystemLibAddressChangeEvent (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- EfiConvertPointer (0, (VOID **)&mPowerManager.SleepControlRegAddr);
- EfiConvertPointer (0, (VOID **)&mPowerManager.SleepStatusRegAddr);
- EfiConvertPointer (0, (VOID **)&mPowerManager.ResetRegAddr);
- }
- /**
- Notification function of ACPI Table change.
- This is a notification function registered on ACPI Table change event.
- It saves the Century address stored in ACPI FADT table.
- @param Event Event whose notification function is being invoked.
- @param Context Pointer to the notification function's context.
- **/
- STATIC VOID
- AcpiNotificationEvent (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- EFI_STATUS Status;
- Status = GetPowerManagerByParseAcpiInfo ();
- if (EFI_ERROR (Status)) {
- return ;
- }
- DEBUG ((DEBUG_INFO, "%a: sleepControl %llx\n", __FUNCTION__, mPowerManager.SleepControlRegAddr));
- ASSERT (mPowerManager.SleepControlRegAddr);
- Status = SetMemoryAttributesRunTime (mPowerManager.SleepControlRegAddr);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, "%a:%d\n", __FUNCTION__, __LINE__));
- return ;
- }
- DEBUG ((DEBUG_INFO, "%a: sleepStatus %llx\n", __FUNCTION__, mPowerManager.SleepStatusRegAddr));
- ASSERT (mPowerManager.SleepStatusRegAddr);
- Status = SetMemoryAttributesRunTime (mPowerManager.SleepStatusRegAddr);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, "%a:%d\n", __FUNCTION__, __LINE__));
- return ;
- }
- DEBUG ((DEBUG_INFO, "%a: ResetReg %llx\n", __FUNCTION__, mPowerManager.ResetRegAddr));
- ASSERT (mPowerManager.ResetRegAddr);
- Status = SetMemoryAttributesRunTime (mPowerManager.ResetRegAddr);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, "%a:%d\n", __FUNCTION__, __LINE__));
- }
- return ;
- }
- /**
- The constructor function to Register ACPI Table change event and Address Change Event.
- @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS.
- **/
- EFI_STATUS
- EFIAPI
- ResetSystemLibConstructor (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- {
- EFI_STATUS Status;
- EFI_EVENT Event;
- EFI_EVENT ResetSystemVirtualNotifyEvent;
- Status = gBS->CreateEventEx (
- EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- AcpiNotificationEvent,
- NULL,
- &gEfiAcpiTableGuid,
- &Event
- );
- //
- // Register SetVirtualAddressMap () notify function
- //
- Status = gBS->CreateEvent (
- EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
- TPL_NOTIFY,
- ResetSystemLibAddressChangeEvent,
- NULL,
- &ResetSystemVirtualNotifyEvent
- );
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
|