| /** @file | |
| Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #include <Uefi.h> | |
| #include <Library/MemoryAllocationLib.h> | |
| #include <Library/UefiBootServicesTableLib.h> | |
| #include <Library/BaseMemoryLib.h> | |
| #include <Library/DebugLib.h> | |
| #include <Protocol/LockBox.h> | |
| #include <LockBoxLib.h> | |
| /** | |
| Allocate memory below 4G memory address. | |
| This function allocates memory below 4G memory address. | |
| @param MemoryType Memory type of memory to allocate. | |
| @param Size Size of memory to allocate. | |
| @return Allocated address for output. | |
| **/ | |
| STATIC | |
| VOID * | |
| AllocateMemoryBelow4G ( | |
| IN EFI_MEMORY_TYPE MemoryType, | |
| IN UINTN Size | |
| ) | |
| { | |
| UINTN Pages; | |
| EFI_PHYSICAL_ADDRESS Address; | |
| EFI_STATUS Status; | |
| VOID *Buffer; | |
| UINTN AllocRemaining; | |
| Pages = EFI_SIZE_TO_PAGES (Size); | |
| Address = 0xffffffff; | |
| // | |
| // Since we need to use gBS->AllocatePages to get a buffer below | |
| // 4GB, there is a good chance that space will be wasted for very | |
| // small allocation. We keep track of unused portions of the page | |
| // allocations, and use these to allocate memory for small buffers. | |
| // | |
| ASSERT (mLockBoxGlobal->Signature == LOCK_BOX_GLOBAL_SIGNATURE); | |
| if ((UINTN)mLockBoxGlobal->SubPageRemaining >= Size) { | |
| Buffer = (VOID *)(UINTN)mLockBoxGlobal->SubPageBuffer; | |
| mLockBoxGlobal->SubPageBuffer += (UINT32)Size; | |
| mLockBoxGlobal->SubPageRemaining -= (UINT32)Size; | |
| return Buffer; | |
| } | |
| Status = gBS->AllocatePages ( | |
| AllocateMaxAddress, | |
| MemoryType, | |
| Pages, | |
| &Address | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| return NULL; | |
| } | |
| Buffer = (VOID *)(UINTN)Address; | |
| ZeroMem (Buffer, EFI_PAGES_TO_SIZE (Pages)); | |
| AllocRemaining = EFI_PAGES_TO_SIZE (Pages) - Size; | |
| if (AllocRemaining > (UINTN)mLockBoxGlobal->SubPageRemaining) { | |
| mLockBoxGlobal->SubPageBuffer = (UINT32)(Address + Size); | |
| mLockBoxGlobal->SubPageRemaining = (UINT32)AllocRemaining; | |
| } | |
| return Buffer; | |
| } | |
| /** | |
| Allocates a buffer of type EfiACPIMemoryNVS. | |
| Allocates the number bytes specified by AllocationSize of type | |
| EfiACPIMemoryNVS and returns a pointer to the allocated buffer. | |
| If AllocationSize is 0, then a valid buffer of 0 size is | |
| returned. If there is not enough memory remaining to satisfy | |
| the request, then NULL is returned. | |
| @param AllocationSize The number of bytes to allocate. | |
| @return A pointer to the allocated buffer or NULL if allocation fails. | |
| **/ | |
| VOID * | |
| EFIAPI | |
| AllocateAcpiNvsPool ( | |
| IN UINTN AllocationSize | |
| ) | |
| { | |
| return AllocateMemoryBelow4G (EfiACPIMemoryNVS, AllocationSize); | |
| } | |
| EFI_STATUS | |
| EFIAPI | |
| LockBoxDxeLibInitialize ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| VOID *Interface; | |
| Status = LockBoxLibInitialize (); | |
| if (!EFI_ERROR (Status)) { | |
| if (PcdGetBool (PcdAcpiS3Enable)) { | |
| // | |
| // When S3 enabled, the first driver run with this library linked will | |
| // have this library constructor to install LockBox protocol on the | |
| // ImageHandle. As other drivers may have gEfiLockBoxProtocolGuid | |
| // dependency, the first driver should run before them. | |
| // | |
| Status = gBS->LocateProtocol (&gEfiLockBoxProtocolGuid, NULL, &Interface); | |
| if (EFI_ERROR (Status)) { | |
| Status = gBS->InstallProtocolInterface ( | |
| &ImageHandle, | |
| &gEfiLockBoxProtocolGuid, | |
| EFI_NATIVE_INTERFACE, | |
| NULL | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| } | |
| } | |
| } | |
| return Status; | |
| } |