1 /** @file
2 
3   Copyright (c) 2006 - 2014, 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 <LockBoxLib.h>
22 
23 /**
24   Allocate memory below 4G memory address.
25 
26   This function allocates memory below 4G memory address.
27 
28   @param  MemoryType   Memory type of memory to allocate.
29   @param  Size         Size of memory to allocate.
30 
31   @return Allocated address for output.
32 
33 **/
34 STATIC
35 VOID *
AllocateMemoryBelow4G(IN EFI_MEMORY_TYPE MemoryType,IN UINTN Size)36 AllocateMemoryBelow4G (
37   IN EFI_MEMORY_TYPE    MemoryType,
38   IN UINTN              Size
39   )
40 {
41   UINTN                 Pages;
42   EFI_PHYSICAL_ADDRESS  Address;
43   EFI_STATUS            Status;
44   VOID*                 Buffer;
45   UINTN                 AllocRemaining;
46 
47   Pages = EFI_SIZE_TO_PAGES (Size);
48   Address = 0xffffffff;
49 
50   //
51   // Since we need to use gBS->AllocatePages to get a buffer below
52   // 4GB, there is a good chance that space will be wasted for very
53   // small allocation. We keep track of unused portions of the page
54   // allocations, and use these to allocate memory for small buffers.
55   //
56   ASSERT (mLockBoxGlobal->Signature == LOCK_BOX_GLOBAL_SIGNATURE);
57   if ((UINTN) mLockBoxGlobal->SubPageRemaining >= Size) {
58     Buffer = (VOID*)(UINTN) mLockBoxGlobal->SubPageBuffer;
59     mLockBoxGlobal->SubPageBuffer += (UINT32) Size;
60     mLockBoxGlobal->SubPageRemaining -= (UINT32) Size;
61     return Buffer;
62   }
63 
64   Status  = gBS->AllocatePages (
65                    AllocateMaxAddress,
66                    MemoryType,
67                    Pages,
68                    &Address
69                    );
70   if (EFI_ERROR (Status)) {
71     return NULL;
72   }
73 
74   Buffer = (VOID *) (UINTN) Address;
75   ZeroMem (Buffer, EFI_PAGES_TO_SIZE (Pages));
76 
77   AllocRemaining = EFI_PAGES_TO_SIZE (Pages) - Size;
78   if (AllocRemaining > (UINTN) mLockBoxGlobal->SubPageRemaining) {
79     mLockBoxGlobal->SubPageBuffer = (UINT32) (Address + Size);
80     mLockBoxGlobal->SubPageRemaining = (UINT32) AllocRemaining;
81   }
82 
83   return Buffer;
84 }
85 
86 
87 /**
88   Allocates a buffer of type EfiACPIMemoryNVS.
89 
90   Allocates the number bytes specified by AllocationSize of type
91   EfiACPIMemoryNVS and returns a pointer to the allocated buffer.
92   If AllocationSize is 0, then a valid buffer of 0 size is
93   returned.  If there is not enough memory remaining to satisfy
94   the request, then NULL is returned.
95 
96   @param  AllocationSize        The number of bytes to allocate.
97 
98   @return A pointer to the allocated buffer or NULL if allocation fails.
99 
100 **/
101 VOID *
102 EFIAPI
AllocateAcpiNvsPool(IN UINTN AllocationSize)103 AllocateAcpiNvsPool (
104   IN UINTN  AllocationSize
105   )
106 {
107   return AllocateMemoryBelow4G (EfiACPIMemoryNVS, AllocationSize);
108 }
109 
110 
111 EFI_STATUS
112 EFIAPI
LockBoxDxeLibInitialize(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)113 LockBoxDxeLibInitialize (
114   IN EFI_HANDLE        ImageHandle,
115   IN EFI_SYSTEM_TABLE  *SystemTable
116   )
117 {
118   return LockBoxLibInitialize ();
119 }
120