Home | History | Annotate | Download | only in LockBoxLib
      1 /** @file
      2 
      3   Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
      4 
      5   This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php.
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include <Uefi.h>
     16 
     17 #include <Library/MemoryAllocationLib.h>
     18 #include <Library/UefiBootServicesTableLib.h>
     19 #include <Library/BaseMemoryLib.h>
     20 #include <Library/DebugLib.h>
     21 #include <Library/QemuFwCfgLib.h>
     22 #include <Protocol/LockBox.h>
     23 #include <LockBoxLib.h>
     24 
     25 /**
     26   Allocate memory below 4G memory address.
     27 
     28   This function allocates memory below 4G memory address.
     29 
     30   @param  MemoryType   Memory type of memory to allocate.
     31   @param  Size         Size of memory to allocate.
     32 
     33   @return Allocated address for output.
     34 
     35 **/
     36 STATIC
     37 VOID *
     38 AllocateMemoryBelow4G (
     39   IN EFI_MEMORY_TYPE    MemoryType,
     40   IN UINTN              Size
     41   )
     42 {
     43   UINTN                 Pages;
     44   EFI_PHYSICAL_ADDRESS  Address;
     45   EFI_STATUS            Status;
     46   VOID*                 Buffer;
     47   UINTN                 AllocRemaining;
     48 
     49   Pages = EFI_SIZE_TO_PAGES (Size);
     50   Address = 0xffffffff;
     51 
     52   //
     53   // Since we need to use gBS->AllocatePages to get a buffer below
     54   // 4GB, there is a good chance that space will be wasted for very
     55   // small allocation. We keep track of unused portions of the page
     56   // allocations, and use these to allocate memory for small buffers.
     57   //
     58   ASSERT (mLockBoxGlobal->Signature == LOCK_BOX_GLOBAL_SIGNATURE);
     59   if ((UINTN) mLockBoxGlobal->SubPageRemaining >= Size) {
     60     Buffer = (VOID*)(UINTN) mLockBoxGlobal->SubPageBuffer;
     61     mLockBoxGlobal->SubPageBuffer += (UINT32) Size;
     62     mLockBoxGlobal->SubPageRemaining -= (UINT32) Size;
     63     return Buffer;
     64   }
     65 
     66   Status  = gBS->AllocatePages (
     67                    AllocateMaxAddress,
     68                    MemoryType,
     69                    Pages,
     70                    &Address
     71                    );
     72   if (EFI_ERROR (Status)) {
     73     return NULL;
     74   }
     75 
     76   Buffer = (VOID *) (UINTN) Address;
     77   ZeroMem (Buffer, EFI_PAGES_TO_SIZE (Pages));
     78 
     79   AllocRemaining = EFI_PAGES_TO_SIZE (Pages) - Size;
     80   if (AllocRemaining > (UINTN) mLockBoxGlobal->SubPageRemaining) {
     81     mLockBoxGlobal->SubPageBuffer = (UINT32) (Address + Size);
     82     mLockBoxGlobal->SubPageRemaining = (UINT32) AllocRemaining;
     83   }
     84 
     85   return Buffer;
     86 }
     87 
     88 
     89 /**
     90   Allocates a buffer of type EfiACPIMemoryNVS.
     91 
     92   Allocates the number bytes specified by AllocationSize of type
     93   EfiACPIMemoryNVS and returns a pointer to the allocated buffer.
     94   If AllocationSize is 0, then a valid buffer of 0 size is
     95   returned.  If there is not enough memory remaining to satisfy
     96   the request, then NULL is returned.
     97 
     98   @param  AllocationSize        The number of bytes to allocate.
     99 
    100   @return A pointer to the allocated buffer or NULL if allocation fails.
    101 
    102 **/
    103 VOID *
    104 EFIAPI
    105 AllocateAcpiNvsPool (
    106   IN UINTN  AllocationSize
    107   )
    108 {
    109   return AllocateMemoryBelow4G (EfiACPIMemoryNVS, AllocationSize);
    110 }
    111 
    112 
    113 EFI_STATUS
    114 EFIAPI
    115 LockBoxDxeLibInitialize (
    116   IN EFI_HANDLE        ImageHandle,
    117   IN EFI_SYSTEM_TABLE  *SystemTable
    118   )
    119 {
    120   EFI_STATUS    Status;
    121   VOID          *Interface;
    122 
    123   Status = LockBoxLibInitialize ();
    124   if (!EFI_ERROR (Status)) {
    125     if (QemuFwCfgS3Enabled ()) {
    126       //
    127       // When S3 enabled, the first driver run with this library linked will
    128       // have this library constructor to install LockBox protocol on the
    129       // ImageHandle. As other drivers may have gEfiLockBoxProtocolGuid
    130       // dependency, the first driver should run before them.
    131       //
    132       Status = gBS->LocateProtocol (&gEfiLockBoxProtocolGuid, NULL, &Interface);
    133       if (EFI_ERROR (Status)) {
    134         Status = gBS->InstallProtocolInterface (
    135                         &ImageHandle,
    136                         &gEfiLockBoxProtocolGuid,
    137                         EFI_NATIVE_INTERFACE,
    138                         NULL
    139                         );
    140         ASSERT_EFI_ERROR (Status);
    141       }
    142     }
    143   }
    144 
    145   return Status;
    146 }
    147