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