MemoryAllocationLib.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  1. /** @file
  2. Support routines for memory allocation routines based
  3. on boot services for Dxe phase drivers using OS malloc.
  4. OS malloc is used so OS based malloc debugging tools can be used.
  5. If a single driver links against this lib protocols from other
  6. drivers, or EFI boot services can return a buffer that needs to
  7. freed using the EFI scheme. This is why the gEmuThunk->Free ()
  8. can detect if the memory rang is for EFI so the right free can be
  9. called.
  10. Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
  11. Portions copyright (c) 2011, Apple Inc. All rights reserved.
  12. SPDX-License-Identifier: BSD-2-Clause-Patent
  13. **/
  14. #include <Uefi.h>
  15. #include <Library/MemoryAllocationLib.h>
  16. #include <Library/UefiBootServicesTableLib.h>
  17. #include <Library/BaseMemoryLib.h>
  18. #include <Library/DebugLib.h>
  19. #include <Library/EmuThunkLib.h>
  20. /**
  21. Allocates one or more 4KB pages of a certain memory type.
  22. Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
  23. buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned.
  24. If there is not enough memory remaining to satisfy the request, then NULL is returned.
  25. @param MemoryType The type of memory to allocate.
  26. @param Pages The number of 4 KB pages to allocate.
  27. @return A pointer to the allocated buffer or NULL if allocation fails.
  28. **/
  29. VOID *
  30. InternalAllocatePages (
  31. IN EFI_MEMORY_TYPE MemoryType,
  32. IN UINTN Pages
  33. )
  34. {
  35. EFI_STATUS Status;
  36. EFI_PHYSICAL_ADDRESS Memory;
  37. if (Pages == 0) {
  38. return NULL;
  39. }
  40. return gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE);
  41. }
  42. /**
  43. Allocates one or more 4KB pages of type EfiBootServicesData.
  44. Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
  45. allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
  46. is returned. If there is not enough memory remaining to satisfy the request, then NULL is
  47. returned.
  48. @param Pages The number of 4 KB pages to allocate.
  49. @return A pointer to the allocated buffer or NULL if allocation fails.
  50. **/
  51. VOID *
  52. EFIAPI
  53. AllocatePages (
  54. IN UINTN Pages
  55. )
  56. {
  57. return InternalAllocatePages (EfiBootServicesData, Pages);
  58. }
  59. /**
  60. Allocates one or more 4KB pages of type EfiRuntimeServicesData.
  61. Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
  62. allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
  63. is returned. If there is not enough memory remaining to satisfy the request, then NULL is
  64. returned.
  65. @param Pages The number of 4 KB pages to allocate.
  66. @return A pointer to the allocated buffer or NULL if allocation fails.
  67. **/
  68. VOID *
  69. EFIAPI
  70. AllocateRuntimePages (
  71. IN UINTN Pages
  72. )
  73. {
  74. return InternalAllocatePages (EfiRuntimeServicesData, Pages);
  75. }
  76. /**
  77. Allocates one or more 4KB pages of type EfiReservedMemoryType.
  78. Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
  79. allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
  80. is returned. If there is not enough memory remaining to satisfy the request, then NULL is
  81. returned.
  82. @param Pages The number of 4 KB pages to allocate.
  83. @return A pointer to the allocated buffer or NULL if allocation fails.
  84. **/
  85. VOID *
  86. EFIAPI
  87. AllocateReservedPages (
  88. IN UINTN Pages
  89. )
  90. {
  91. return InternalAllocatePages (EfiReservedMemoryType, Pages);
  92. }
  93. /**
  94. Frees one or more 4KB pages that were previously allocated with one of the page allocation
  95. functions in the Memory Allocation Library.
  96. Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
  97. must have been allocated on a previous call to the page allocation services of the Memory
  98. Allocation Library. If it is not possible to free allocated pages, then this function will
  99. perform no actions.
  100. If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
  101. then ASSERT().
  102. If Pages is zero, then ASSERT().
  103. @param Buffer The pointer to the buffer of pages to free.
  104. @param Pages The number of 4 KB pages to free.
  105. **/
  106. VOID
  107. EFIAPI
  108. FreePages (
  109. IN VOID *Buffer,
  110. IN UINTN Pages
  111. )
  112. {
  113. EFI_STATUS Status;
  114. ASSERT (Pages != 0);
  115. if (!gEmuThunk->Free (Buffer)) {
  116. // The Free thunk will not free memory allocated in emulated EFI memory.
  117. // The assmuption is this was allocated directly by EFI. We need this as some
  118. // times protocols or EFI BootServices can return dynamically allocated buffers.
  119. Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages);
  120. ASSERT_EFI_ERROR (Status);
  121. }
  122. }
  123. /**
  124. Allocates one or more 4KB pages of a certain memory type at a specified alignment.
  125. Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
  126. specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
  127. If there is not enough memory at the specified alignment remaining to satisfy the request, then
  128. NULL is returned.
  129. If Alignment is not a power of two and Alignment is not zero, then ASSERT().
  130. @param MemoryType The type of memory to allocate.
  131. @param Pages The number of 4 KB pages to allocate.
  132. @param Alignment The requested alignment of the allocation. Must be a power of two.
  133. If Alignment is zero, then byte alignment is used.
  134. @return A pointer to the allocated buffer or NULL if allocation fails.
  135. **/
  136. VOID *
  137. InternalAllocateAlignedPages (
  138. IN EFI_MEMORY_TYPE MemoryType,
  139. IN UINTN Pages,
  140. IN UINTN Alignment
  141. )
  142. {
  143. EFI_STATUS Status;
  144. VOID *Memory;
  145. UINTN AlignedMemory;
  146. UINTN AlignmentMask;
  147. UINTN UnalignedPages;
  148. UINTN RealPages;
  149. //
  150. // Alignment must be a power of two or zero.
  151. //
  152. ASSERT ((Alignment & (Alignment - 1)) == 0);
  153. if (Pages == 0) {
  154. return NULL;
  155. }
  156. if (Alignment > EFI_PAGE_SIZE) {
  157. //
  158. // Caculate the total number of pages since alignment is larger than page size.
  159. //
  160. AlignmentMask = Alignment - 1;
  161. RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);
  162. //
  163. // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
  164. //
  165. ASSERT (RealPages > Pages);
  166. Memory = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE);
  167. if (Memory != NULL) {
  168. return NULL;
  169. }
  170. AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask;
  171. UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory);
  172. if (UnalignedPages > 0) {
  173. //
  174. // Free first unaligned page(s).
  175. //
  176. FreePages (Memory, UnalignedPages);
  177. }
  178. Memory = (VOID *)(AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
  179. UnalignedPages = RealPages - Pages - UnalignedPages;
  180. if (UnalignedPages > 0) {
  181. //
  182. // Free last unaligned page(s).
  183. //
  184. FreePages (Memory, UnalignedPages);
  185. }
  186. } else {
  187. //
  188. // Do not over-allocate pages in this case.
  189. //
  190. Memory = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE);
  191. if (Memory != NULL) {
  192. return NULL;
  193. }
  194. AlignedMemory = (UINTN)Memory;
  195. }
  196. return (VOID *)AlignedMemory;
  197. }
  198. /**
  199. Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
  200. Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
  201. alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
  202. returned. If there is not enough memory at the specified alignment remaining to satisfy the
  203. request, then NULL is returned.
  204. If Alignment is not a power of two and Alignment is not zero, then ASSERT().
  205. @param Pages The number of 4 KB pages to allocate.
  206. @param Alignment The requested alignment of the allocation. Must be a power of two.
  207. If Alignment is zero, then byte alignment is used.
  208. @return A pointer to the allocated buffer or NULL if allocation fails.
  209. **/
  210. VOID *
  211. EFIAPI
  212. AllocateAlignedPages (
  213. IN UINTN Pages,
  214. IN UINTN Alignment
  215. )
  216. {
  217. return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
  218. }
  219. /**
  220. Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
  221. Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
  222. alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
  223. returned. If there is not enough memory at the specified alignment remaining to satisfy the
  224. request, then NULL is returned.
  225. If Alignment is not a power of two and Alignment is not zero, then ASSERT().
  226. @param Pages The number of 4 KB pages to allocate.
  227. @param Alignment The requested alignment of the allocation. Must be a power of two.
  228. If Alignment is zero, then byte alignment is used.
  229. @return A pointer to the allocated buffer or NULL if allocation fails.
  230. **/
  231. VOID *
  232. EFIAPI
  233. AllocateAlignedRuntimePages (
  234. IN UINTN Pages,
  235. IN UINTN Alignment
  236. )
  237. {
  238. return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
  239. }
  240. /**
  241. Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
  242. Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
  243. alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
  244. returned. If there is not enough memory at the specified alignment remaining to satisfy the
  245. request, then NULL is returned.
  246. If Alignment is not a power of two and Alignment is not zero, then ASSERT().
  247. @param Pages The number of 4 KB pages to allocate.
  248. @param Alignment The requested alignment of the allocation. Must be a power of two.
  249. If Alignment is zero, then byte alignment is used.
  250. @return A pointer to the allocated buffer or NULL if allocation fails.
  251. **/
  252. VOID *
  253. EFIAPI
  254. AllocateAlignedReservedPages (
  255. IN UINTN Pages,
  256. IN UINTN Alignment
  257. )
  258. {
  259. return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
  260. }
  261. /**
  262. Frees one or more 4KB pages that were previously allocated with one of the aligned page
  263. allocation functions in the Memory Allocation Library.
  264. Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
  265. must have been allocated on a previous call to the aligned page allocation services of the Memory
  266. Allocation Library. If it is not possible to free allocated pages, then this function will
  267. perform no actions.
  268. If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
  269. Library, then ASSERT().
  270. If Pages is zero, then ASSERT().
  271. @param Buffer The pointer to the buffer of pages to free.
  272. @param Pages The number of 4 KB pages to free.
  273. **/
  274. VOID
  275. EFIAPI
  276. FreeAlignedPages (
  277. IN VOID *Buffer,
  278. IN UINTN Pages
  279. )
  280. {
  281. FreePages (Buffer, Pages);
  282. }
  283. /**
  284. Allocates a buffer of a certain pool type.
  285. Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
  286. pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
  287. returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
  288. @param MemoryType The type of memory to allocate.
  289. @param AllocationSize The number of bytes to allocate.
  290. @return A pointer to the allocated buffer or NULL if allocation fails.
  291. **/
  292. VOID *
  293. InternalAllocatePool (
  294. IN EFI_MEMORY_TYPE MemoryType,
  295. IN UINTN AllocationSize
  296. )
  297. {
  298. return gEmuThunk->Malloc (AllocationSize);
  299. }
  300. /**
  301. Allocates a buffer of type EfiBootServicesData.
  302. Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
  303. pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
  304. returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
  305. @param AllocationSize The number of bytes to allocate.
  306. @return A pointer to the allocated buffer or NULL if allocation fails.
  307. **/
  308. VOID *
  309. EFIAPI
  310. AllocatePool (
  311. IN UINTN AllocationSize
  312. )
  313. {
  314. return InternalAllocatePool (EfiBootServicesData, AllocationSize);
  315. }
  316. /**
  317. Allocates a buffer of type EfiRuntimeServicesData.
  318. Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
  319. a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
  320. returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
  321. @param AllocationSize The number of bytes to allocate.
  322. @return A pointer to the allocated buffer or NULL if allocation fails.
  323. **/
  324. VOID *
  325. EFIAPI
  326. AllocateRuntimePool (
  327. IN UINTN AllocationSize
  328. )
  329. {
  330. return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
  331. }
  332. /**
  333. Allocates a buffer of type EfiReservedMemoryType.
  334. Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
  335. a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
  336. returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
  337. @param AllocationSize The number of bytes to allocate.
  338. @return A pointer to the allocated buffer or NULL if allocation fails.
  339. **/
  340. VOID *
  341. EFIAPI
  342. AllocateReservedPool (
  343. IN UINTN AllocationSize
  344. )
  345. {
  346. return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
  347. }
  348. /**
  349. Allocates and zeros a buffer of a certain pool type.
  350. Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
  351. with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
  352. buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
  353. then NULL is returned.
  354. @param PoolType The type of memory to allocate.
  355. @param AllocationSize The number of bytes to allocate and zero.
  356. @return A pointer to the allocated buffer or NULL if allocation fails.
  357. **/
  358. VOID *
  359. InternalAllocateZeroPool (
  360. IN EFI_MEMORY_TYPE PoolType,
  361. IN UINTN AllocationSize
  362. )
  363. {
  364. VOID *Memory;
  365. Memory = InternalAllocatePool (PoolType, AllocationSize);
  366. if (Memory != NULL) {
  367. Memory = ZeroMem (Memory, AllocationSize);
  368. }
  369. return Memory;
  370. }
  371. /**
  372. Allocates and zeros a buffer of type EfiBootServicesData.
  373. Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
  374. buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
  375. valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
  376. request, then NULL is returned.
  377. @param AllocationSize The number of bytes to allocate and zero.
  378. @return A pointer to the allocated buffer or NULL if allocation fails.
  379. **/
  380. VOID *
  381. EFIAPI
  382. AllocateZeroPool (
  383. IN UINTN AllocationSize
  384. )
  385. {
  386. return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
  387. }
  388. /**
  389. Allocates and zeros a buffer of type EfiRuntimeServicesData.
  390. Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
  391. buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
  392. valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
  393. request, then NULL is returned.
  394. @param AllocationSize The number of bytes to allocate and zero.
  395. @return A pointer to the allocated buffer or NULL if allocation fails.
  396. **/
  397. VOID *
  398. EFIAPI
  399. AllocateRuntimeZeroPool (
  400. IN UINTN AllocationSize
  401. )
  402. {
  403. return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
  404. }
  405. /**
  406. Allocates and zeros a buffer of type EfiReservedMemoryType.
  407. Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
  408. buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
  409. valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
  410. request, then NULL is returned.
  411. @param AllocationSize The number of bytes to allocate and zero.
  412. @return A pointer to the allocated buffer or NULL if allocation fails.
  413. **/
  414. VOID *
  415. EFIAPI
  416. AllocateReservedZeroPool (
  417. IN UINTN AllocationSize
  418. )
  419. {
  420. return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
  421. }
  422. /**
  423. Copies a buffer to an allocated buffer of a certain pool type.
  424. Allocates the number bytes specified by AllocationSize of a certain pool type, copies
  425. AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
  426. allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
  427. is not enough memory remaining to satisfy the request, then NULL is returned.
  428. If Buffer is NULL, then ASSERT().
  429. If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
  430. @param PoolType The type of pool to allocate.
  431. @param AllocationSize The number of bytes to allocate and zero.
  432. @param Buffer The buffer to copy to the allocated buffer.
  433. @return A pointer to the allocated buffer or NULL if allocation fails.
  434. **/
  435. VOID *
  436. InternalAllocateCopyPool (
  437. IN EFI_MEMORY_TYPE PoolType,
  438. IN UINTN AllocationSize,
  439. IN CONST VOID *Buffer
  440. )
  441. {
  442. VOID *Memory;
  443. ASSERT (Buffer != NULL);
  444. ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1));
  445. Memory = InternalAllocatePool (PoolType, AllocationSize);
  446. if (Memory != NULL) {
  447. Memory = CopyMem (Memory, Buffer, AllocationSize);
  448. }
  449. return Memory;
  450. }
  451. /**
  452. Copies a buffer to an allocated buffer of type EfiBootServicesData.
  453. Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
  454. AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
  455. allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
  456. is not enough memory remaining to satisfy the request, then NULL is returned.
  457. If Buffer is NULL, then ASSERT().
  458. If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
  459. @param AllocationSize The number of bytes to allocate and zero.
  460. @param Buffer The buffer to copy to the allocated buffer.
  461. @return A pointer to the allocated buffer or NULL if allocation fails.
  462. **/
  463. VOID *
  464. EFIAPI
  465. AllocateCopyPool (
  466. IN UINTN AllocationSize,
  467. IN CONST VOID *Buffer
  468. )
  469. {
  470. return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
  471. }
  472. /**
  473. Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
  474. Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
  475. AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
  476. allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
  477. is not enough memory remaining to satisfy the request, then NULL is returned.
  478. If Buffer is NULL, then ASSERT().
  479. If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
  480. @param AllocationSize The number of bytes to allocate and zero.
  481. @param Buffer The buffer to copy to the allocated buffer.
  482. @return A pointer to the allocated buffer or NULL if allocation fails.
  483. **/
  484. VOID *
  485. EFIAPI
  486. AllocateRuntimeCopyPool (
  487. IN UINTN AllocationSize,
  488. IN CONST VOID *Buffer
  489. )
  490. {
  491. return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
  492. }
  493. /**
  494. Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
  495. Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
  496. AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
  497. allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
  498. is not enough memory remaining to satisfy the request, then NULL is returned.
  499. If Buffer is NULL, then ASSERT().
  500. If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
  501. @param AllocationSize The number of bytes to allocate and zero.
  502. @param Buffer The buffer to copy to the allocated buffer.
  503. @return A pointer to the allocated buffer or NULL if allocation fails.
  504. **/
  505. VOID *
  506. EFIAPI
  507. AllocateReservedCopyPool (
  508. IN UINTN AllocationSize,
  509. IN CONST VOID *Buffer
  510. )
  511. {
  512. return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
  513. }
  514. /**
  515. Reallocates a buffer of a specified memory type.
  516. Allocates and zeros the number bytes specified by NewSize from memory of the type
  517. specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
  518. NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
  519. OldBuffer is freed. A pointer to the newly allocated buffer is returned.
  520. If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
  521. enough memory remaining to satisfy the request, then NULL is returned.
  522. If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
  523. is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
  524. @param PoolType The type of pool to allocate.
  525. @param OldSize The size, in bytes, of OldBuffer.
  526. @param NewSize The size, in bytes, of the buffer to reallocate.
  527. @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
  528. parameter that may be NULL.
  529. @return A pointer to the allocated buffer or NULL if allocation fails.
  530. **/
  531. VOID *
  532. InternalReallocatePool (
  533. IN EFI_MEMORY_TYPE PoolType,
  534. IN UINTN OldSize,
  535. IN UINTN NewSize,
  536. IN VOID *OldBuffer OPTIONAL
  537. )
  538. {
  539. VOID *NewBuffer;
  540. NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
  541. if ((NewBuffer != NULL) && (OldBuffer != NULL)) {
  542. CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
  543. FreePool (OldBuffer);
  544. }
  545. return NewBuffer;
  546. }
  547. /**
  548. Reallocates a buffer of type EfiBootServicesData.
  549. Allocates and zeros the number bytes specified by NewSize from memory of type
  550. EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
  551. NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
  552. OldBuffer is freed. A pointer to the newly allocated buffer is returned.
  553. If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
  554. enough memory remaining to satisfy the request, then NULL is returned.
  555. If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
  556. is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
  557. @param OldSize The size, in bytes, of OldBuffer.
  558. @param NewSize The size, in bytes, of the buffer to reallocate.
  559. @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
  560. parameter that may be NULL.
  561. @return A pointer to the allocated buffer or NULL if allocation fails.
  562. **/
  563. VOID *
  564. EFIAPI
  565. ReallocatePool (
  566. IN UINTN OldSize,
  567. IN UINTN NewSize,
  568. IN VOID *OldBuffer OPTIONAL
  569. )
  570. {
  571. return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);
  572. }
  573. /**
  574. Reallocates a buffer of type EfiRuntimeServicesData.
  575. Allocates and zeros the number bytes specified by NewSize from memory of type
  576. EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
  577. NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
  578. OldBuffer is freed. A pointer to the newly allocated buffer is returned.
  579. If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
  580. enough memory remaining to satisfy the request, then NULL is returned.
  581. If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
  582. is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
  583. @param OldSize The size, in bytes, of OldBuffer.
  584. @param NewSize The size, in bytes, of the buffer to reallocate.
  585. @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
  586. parameter that may be NULL.
  587. @return A pointer to the allocated buffer or NULL if allocation fails.
  588. **/
  589. VOID *
  590. EFIAPI
  591. ReallocateRuntimePool (
  592. IN UINTN OldSize,
  593. IN UINTN NewSize,
  594. IN VOID *OldBuffer OPTIONAL
  595. )
  596. {
  597. return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
  598. }
  599. /**
  600. Reallocates a buffer of type EfiReservedMemoryType.
  601. Allocates and zeros the number bytes specified by NewSize from memory of type
  602. EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and
  603. NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
  604. OldBuffer is freed. A pointer to the newly allocated buffer is returned.
  605. If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
  606. enough memory remaining to satisfy the request, then NULL is returned.
  607. If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
  608. is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
  609. @param OldSize The size, in bytes, of OldBuffer.
  610. @param NewSize The size, in bytes, of the buffer to reallocate.
  611. @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
  612. parameter that may be NULL.
  613. @return A pointer to the allocated buffer or NULL if allocation fails.
  614. **/
  615. VOID *
  616. EFIAPI
  617. ReallocateReservedPool (
  618. IN UINTN OldSize,
  619. IN UINTN NewSize,
  620. IN VOID *OldBuffer OPTIONAL
  621. )
  622. {
  623. return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);
  624. }
  625. /**
  626. Frees a buffer that was previously allocated with one of the pool allocation functions in the
  627. Memory Allocation Library.
  628. Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
  629. pool allocation services of the Memory Allocation Library. If it is not possible to free pool
  630. resources, then this function will perform no actions.
  631. If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
  632. then ASSERT().
  633. @param Buffer The pointer to the buffer to free.
  634. **/
  635. VOID
  636. EFIAPI
  637. FreePool (
  638. IN VOID *Buffer
  639. )
  640. {
  641. EFI_STATUS Status;
  642. if (!gEmuThunk->Free (Buffer)) {
  643. // The Free thunk will not free memory allocated in emulated EFI memory.
  644. // The assmuption is this was allocated directly by EFI. We need this as some
  645. // times protocols or EFI BootServices can return dynamically allocated buffers.
  646. Status = gBS->FreePool (Buffer);
  647. ASSERT_EFI_ERROR (Status);
  648. }
  649. }