MemoryAllocationLib.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079
  1. /** @file
  2. Support routines for memory allocation routines based
  3. on DxeCore Memory Allocation services for DxeCore,
  4. with memory profile support.
  5. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
  6. SPDX-License-Identifier: BSD-2-Clause-Patent
  7. **/
  8. #include <PiDxe.h>
  9. #include <Library/MemoryAllocationLib.h>
  10. #include <Library/BaseMemoryLib.h>
  11. #include <Library/DebugLib.h>
  12. #include "DxeCoreMemoryAllocationServices.h"
  13. #include <Library/MemoryProfileLib.h>
  14. /**
  15. Allocates one or more 4KB pages of a certain memory type.
  16. Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
  17. buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned.
  18. If there is not enough memory remaining to satisfy the request, then NULL is returned.
  19. @param MemoryType The type of memory to allocate.
  20. @param Pages The number of 4 KB pages to allocate.
  21. @return A pointer to the allocated buffer or NULL if allocation fails.
  22. **/
  23. VOID *
  24. InternalAllocatePages (
  25. IN EFI_MEMORY_TYPE MemoryType,
  26. IN UINTN Pages
  27. )
  28. {
  29. EFI_STATUS Status;
  30. EFI_PHYSICAL_ADDRESS Memory;
  31. if (Pages == 0) {
  32. return NULL;
  33. }
  34. Status = CoreAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
  35. if (EFI_ERROR (Status)) {
  36. return NULL;
  37. }
  38. return (VOID *)(UINTN)Memory;
  39. }
  40. /**
  41. Allocates one or more 4KB pages of type EfiBootServicesData.
  42. Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
  43. allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
  44. is returned. If there is not enough memory remaining to satisfy the request, then NULL is
  45. returned.
  46. @param Pages The number of 4 KB pages to allocate.
  47. @return A pointer to the allocated buffer or NULL if allocation fails.
  48. **/
  49. VOID *
  50. EFIAPI
  51. AllocatePages (
  52. IN UINTN Pages
  53. )
  54. {
  55. VOID *Buffer;
  56. Buffer = InternalAllocatePages (EfiBootServicesData, Pages);
  57. if (Buffer != NULL) {
  58. MemoryProfileLibRecord (
  59. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  60. MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES,
  61. EfiBootServicesData,
  62. Buffer,
  63. EFI_PAGES_TO_SIZE (Pages),
  64. NULL
  65. );
  66. }
  67. return Buffer;
  68. }
  69. /**
  70. Allocates one or more 4KB pages of type EfiRuntimeServicesData.
  71. Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
  72. allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
  73. is returned. If there is not enough memory remaining to satisfy the request, then NULL is
  74. returned.
  75. @param Pages The number of 4 KB pages to allocate.
  76. @return A pointer to the allocated buffer or NULL if allocation fails.
  77. **/
  78. VOID *
  79. EFIAPI
  80. AllocateRuntimePages (
  81. IN UINTN Pages
  82. )
  83. {
  84. VOID *Buffer;
  85. Buffer = InternalAllocatePages (EfiRuntimeServicesData, Pages);
  86. if (Buffer != NULL) {
  87. MemoryProfileLibRecord (
  88. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  89. MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES,
  90. EfiRuntimeServicesData,
  91. Buffer,
  92. EFI_PAGES_TO_SIZE (Pages),
  93. NULL
  94. );
  95. }
  96. return Buffer;
  97. }
  98. /**
  99. Allocates one or more 4KB pages of type EfiReservedMemoryType.
  100. Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
  101. allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
  102. is returned. If there is not enough memory remaining to satisfy the request, then NULL is
  103. returned.
  104. @param Pages The number of 4 KB pages to allocate.
  105. @return A pointer to the allocated buffer or NULL if allocation fails.
  106. **/
  107. VOID *
  108. EFIAPI
  109. AllocateReservedPages (
  110. IN UINTN Pages
  111. )
  112. {
  113. VOID *Buffer;
  114. Buffer = InternalAllocatePages (EfiReservedMemoryType, Pages);
  115. if (Buffer != NULL) {
  116. MemoryProfileLibRecord (
  117. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  118. MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES,
  119. EfiReservedMemoryType,
  120. Buffer,
  121. EFI_PAGES_TO_SIZE (Pages),
  122. NULL
  123. );
  124. }
  125. return Buffer;
  126. }
  127. /**
  128. Frees one or more 4KB pages that were previously allocated with one of the page allocation
  129. functions in the Memory Allocation Library.
  130. Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
  131. must have been allocated on a previous call to the page allocation services of the Memory
  132. Allocation Library. If it is not possible to free allocated pages, then this function will
  133. perform no actions.
  134. If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
  135. then ASSERT().
  136. If Pages is zero, then ASSERT().
  137. @param Buffer Pointer to the buffer of pages to free.
  138. @param Pages The number of 4 KB pages to free.
  139. **/
  140. VOID
  141. EFIAPI
  142. FreePages (
  143. IN VOID *Buffer,
  144. IN UINTN Pages
  145. )
  146. {
  147. EFI_STATUS Status;
  148. ASSERT (Pages != 0);
  149. Status = CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages);
  150. ASSERT_EFI_ERROR (Status);
  151. }
  152. /**
  153. Allocates one or more 4KB pages of a certain memory type at a specified alignment.
  154. Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
  155. specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
  156. If there is not enough memory at the specified alignment remaining to satisfy the request, then
  157. NULL is returned.
  158. If Alignment is not a power of two and Alignment is not zero, then ASSERT().
  159. If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
  160. @param MemoryType The type of memory to allocate.
  161. @param Pages The number of 4 KB pages to allocate.
  162. @param Alignment The requested alignment of the allocation. Must be a power of two.
  163. If Alignment is zero, then byte alignment is used.
  164. @return A pointer to the allocated buffer or NULL if allocation fails.
  165. **/
  166. VOID *
  167. InternalAllocateAlignedPages (
  168. IN EFI_MEMORY_TYPE MemoryType,
  169. IN UINTN Pages,
  170. IN UINTN Alignment
  171. )
  172. {
  173. EFI_STATUS Status;
  174. EFI_PHYSICAL_ADDRESS Memory;
  175. UINTN AlignedMemory;
  176. UINTN AlignmentMask;
  177. UINTN UnalignedPages;
  178. UINTN RealPages;
  179. //
  180. // Alignment must be a power of two or zero.
  181. //
  182. ASSERT ((Alignment & (Alignment - 1)) == 0);
  183. if (Pages == 0) {
  184. return NULL;
  185. }
  186. if (Alignment > EFI_PAGE_SIZE) {
  187. //
  188. // Calculate the total number of pages since alignment is larger than page size.
  189. //
  190. AlignmentMask = Alignment - 1;
  191. RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);
  192. //
  193. // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
  194. //
  195. ASSERT (RealPages > Pages);
  196. Status = CoreAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);
  197. if (EFI_ERROR (Status)) {
  198. return NULL;
  199. }
  200. AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask;
  201. UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory);
  202. if (UnalignedPages > 0) {
  203. //
  204. // Free first unaligned page(s).
  205. //
  206. Status = CoreFreePages (Memory, UnalignedPages);
  207. ASSERT_EFI_ERROR (Status);
  208. }
  209. Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages);
  210. UnalignedPages = RealPages - Pages - UnalignedPages;
  211. if (UnalignedPages > 0) {
  212. //
  213. // Free last unaligned page(s).
  214. //
  215. Status = CoreFreePages (Memory, UnalignedPages);
  216. ASSERT_EFI_ERROR (Status);
  217. }
  218. } else {
  219. //
  220. // Do not over-allocate pages in this case.
  221. //
  222. Status = CoreAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
  223. if (EFI_ERROR (Status)) {
  224. return NULL;
  225. }
  226. AlignedMemory = (UINTN)Memory;
  227. }
  228. return (VOID *)AlignedMemory;
  229. }
  230. /**
  231. Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
  232. Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
  233. alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
  234. returned. If there is not enough memory at the specified alignment remaining to satisfy the
  235. request, then NULL is returned.
  236. If Alignment is not a power of two and Alignment is not zero, then ASSERT().
  237. If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
  238. @param Pages The number of 4 KB pages to allocate.
  239. @param Alignment The requested alignment of the allocation. Must be a power of two.
  240. If Alignment is zero, then byte alignment is used.
  241. @return A pointer to the allocated buffer or NULL if allocation fails.
  242. **/
  243. VOID *
  244. EFIAPI
  245. AllocateAlignedPages (
  246. IN UINTN Pages,
  247. IN UINTN Alignment
  248. )
  249. {
  250. VOID *Buffer;
  251. Buffer = InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
  252. if (Buffer != NULL) {
  253. MemoryProfileLibRecord (
  254. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  255. MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES,
  256. EfiBootServicesData,
  257. Buffer,
  258. EFI_PAGES_TO_SIZE (Pages),
  259. NULL
  260. );
  261. }
  262. return Buffer;
  263. }
  264. /**
  265. Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
  266. Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
  267. alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
  268. returned. If there is not enough memory at the specified alignment remaining to satisfy the
  269. request, then NULL is returned.
  270. If Alignment is not a power of two and Alignment is not zero, then ASSERT().
  271. If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
  272. @param Pages The number of 4 KB pages to allocate.
  273. @param Alignment The requested alignment of the allocation. Must be a power of two.
  274. If Alignment is zero, then byte alignment is used.
  275. @return A pointer to the allocated buffer or NULL if allocation fails.
  276. **/
  277. VOID *
  278. EFIAPI
  279. AllocateAlignedRuntimePages (
  280. IN UINTN Pages,
  281. IN UINTN Alignment
  282. )
  283. {
  284. VOID *Buffer;
  285. Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
  286. if (Buffer != NULL) {
  287. MemoryProfileLibRecord (
  288. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  289. MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES,
  290. EfiRuntimeServicesData,
  291. Buffer,
  292. EFI_PAGES_TO_SIZE (Pages),
  293. NULL
  294. );
  295. }
  296. return Buffer;
  297. }
  298. /**
  299. Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
  300. Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
  301. alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
  302. returned. If there is not enough memory at the specified alignment remaining to satisfy the
  303. request, then NULL is returned.
  304. If Alignment is not a power of two and Alignment is not zero, then ASSERT().
  305. If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
  306. @param Pages The number of 4 KB pages to allocate.
  307. @param Alignment The requested alignment of the allocation. Must be a power of two.
  308. If Alignment is zero, then byte alignment is used.
  309. @return A pointer to the allocated buffer or NULL if allocation fails.
  310. **/
  311. VOID *
  312. EFIAPI
  313. AllocateAlignedReservedPages (
  314. IN UINTN Pages,
  315. IN UINTN Alignment
  316. )
  317. {
  318. VOID *Buffer;
  319. Buffer = InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
  320. if (Buffer != NULL) {
  321. MemoryProfileLibRecord (
  322. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  323. MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES,
  324. EfiReservedMemoryType,
  325. Buffer,
  326. EFI_PAGES_TO_SIZE (Pages),
  327. NULL
  328. );
  329. }
  330. return Buffer;
  331. }
  332. /**
  333. Frees one or more 4KB pages that were previously allocated with one of the aligned page
  334. allocation functions in the Memory Allocation Library.
  335. Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
  336. must have been allocated on a previous call to the aligned page allocation services of the Memory
  337. Allocation Library. If it is not possible to free allocated pages, then this function will
  338. perform no actions.
  339. If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
  340. Library, then ASSERT().
  341. If Pages is zero, then ASSERT().
  342. @param Buffer Pointer to the buffer of pages to free.
  343. @param Pages The number of 4 KB pages to free.
  344. **/
  345. VOID
  346. EFIAPI
  347. FreeAlignedPages (
  348. IN VOID *Buffer,
  349. IN UINTN Pages
  350. )
  351. {
  352. EFI_STATUS Status;
  353. ASSERT (Pages != 0);
  354. Status = CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages);
  355. ASSERT_EFI_ERROR (Status);
  356. }
  357. /**
  358. Allocates a buffer of a certain pool type.
  359. Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
  360. pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
  361. returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
  362. @param MemoryType The type of memory to allocate.
  363. @param AllocationSize The number of bytes to allocate.
  364. @return A pointer to the allocated buffer or NULL if allocation fails.
  365. **/
  366. VOID *
  367. InternalAllocatePool (
  368. IN EFI_MEMORY_TYPE MemoryType,
  369. IN UINTN AllocationSize
  370. )
  371. {
  372. EFI_STATUS Status;
  373. VOID *Memory;
  374. Memory = NULL;
  375. Status = CoreAllocatePool (MemoryType, AllocationSize, &Memory);
  376. if (EFI_ERROR (Status)) {
  377. Memory = NULL;
  378. }
  379. return Memory;
  380. }
  381. /**
  382. Allocates a buffer of type EfiBootServicesData.
  383. Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
  384. pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
  385. returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
  386. @param AllocationSize The number of bytes to allocate.
  387. @return A pointer to the allocated buffer or NULL if allocation fails.
  388. **/
  389. VOID *
  390. EFIAPI
  391. AllocatePool (
  392. IN UINTN AllocationSize
  393. )
  394. {
  395. VOID *Buffer;
  396. Buffer = InternalAllocatePool (EfiBootServicesData, AllocationSize);
  397. if (Buffer != NULL) {
  398. MemoryProfileLibRecord (
  399. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  400. MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL,
  401. EfiBootServicesData,
  402. Buffer,
  403. AllocationSize,
  404. NULL
  405. );
  406. }
  407. return Buffer;
  408. }
  409. /**
  410. Allocates a buffer of type EfiRuntimeServicesData.
  411. Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
  412. a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
  413. returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
  414. @param AllocationSize The number of bytes to allocate.
  415. @return A pointer to the allocated buffer or NULL if allocation fails.
  416. **/
  417. VOID *
  418. EFIAPI
  419. AllocateRuntimePool (
  420. IN UINTN AllocationSize
  421. )
  422. {
  423. VOID *Buffer;
  424. Buffer = InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
  425. if (Buffer != NULL) {
  426. MemoryProfileLibRecord (
  427. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  428. MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL,
  429. EfiRuntimeServicesData,
  430. Buffer,
  431. AllocationSize,
  432. NULL
  433. );
  434. }
  435. return Buffer;
  436. }
  437. /**
  438. Allocates a buffer of type EfiReservedMemoryType.
  439. Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
  440. a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
  441. returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
  442. @param AllocationSize The number of bytes to allocate.
  443. @return A pointer to the allocated buffer or NULL if allocation fails.
  444. **/
  445. VOID *
  446. EFIAPI
  447. AllocateReservedPool (
  448. IN UINTN AllocationSize
  449. )
  450. {
  451. VOID *Buffer;
  452. Buffer = InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
  453. if (Buffer != NULL) {
  454. MemoryProfileLibRecord (
  455. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  456. MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL,
  457. EfiReservedMemoryType,
  458. Buffer,
  459. AllocationSize,
  460. NULL
  461. );
  462. }
  463. return Buffer;
  464. }
  465. /**
  466. Allocates and zeros a buffer of a certain pool type.
  467. Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
  468. with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
  469. buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
  470. then NULL is returned.
  471. @param PoolType The type of memory to allocate.
  472. @param AllocationSize The number of bytes to allocate and zero.
  473. @return A pointer to the allocated buffer or NULL if allocation fails.
  474. **/
  475. VOID *
  476. InternalAllocateZeroPool (
  477. IN EFI_MEMORY_TYPE PoolType,
  478. IN UINTN AllocationSize
  479. )
  480. {
  481. VOID *Memory;
  482. Memory = InternalAllocatePool (PoolType, AllocationSize);
  483. if (Memory != NULL) {
  484. Memory = ZeroMem (Memory, AllocationSize);
  485. }
  486. return Memory;
  487. }
  488. /**
  489. Allocates and zeros a buffer of type EfiBootServicesData.
  490. Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
  491. buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
  492. valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
  493. request, then NULL is returned.
  494. @param AllocationSize The number of bytes to allocate and zero.
  495. @return A pointer to the allocated buffer or NULL if allocation fails.
  496. **/
  497. VOID *
  498. EFIAPI
  499. AllocateZeroPool (
  500. IN UINTN AllocationSize
  501. )
  502. {
  503. VOID *Buffer;
  504. Buffer = InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
  505. if (Buffer != NULL) {
  506. MemoryProfileLibRecord (
  507. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  508. MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL,
  509. EfiBootServicesData,
  510. Buffer,
  511. AllocationSize,
  512. NULL
  513. );
  514. }
  515. return Buffer;
  516. }
  517. /**
  518. Allocates and zeros a buffer of type EfiRuntimeServicesData.
  519. Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
  520. buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
  521. valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
  522. request, then NULL is returned.
  523. @param AllocationSize The number of bytes to allocate and zero.
  524. @return A pointer to the allocated buffer or NULL if allocation fails.
  525. **/
  526. VOID *
  527. EFIAPI
  528. AllocateRuntimeZeroPool (
  529. IN UINTN AllocationSize
  530. )
  531. {
  532. VOID *Buffer;
  533. Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
  534. if (Buffer != NULL) {
  535. MemoryProfileLibRecord (
  536. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  537. MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL,
  538. EfiRuntimeServicesData,
  539. Buffer,
  540. AllocationSize,
  541. NULL
  542. );
  543. }
  544. return Buffer;
  545. }
  546. /**
  547. Allocates and zeros a buffer of type EfiReservedMemoryType.
  548. Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
  549. buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
  550. valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
  551. request, then NULL is returned.
  552. @param AllocationSize The number of bytes to allocate and zero.
  553. @return A pointer to the allocated buffer or NULL if allocation fails.
  554. **/
  555. VOID *
  556. EFIAPI
  557. AllocateReservedZeroPool (
  558. IN UINTN AllocationSize
  559. )
  560. {
  561. VOID *Buffer;
  562. Buffer = InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
  563. if (Buffer != NULL) {
  564. MemoryProfileLibRecord (
  565. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  566. MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL,
  567. EfiReservedMemoryType,
  568. Buffer,
  569. AllocationSize,
  570. NULL
  571. );
  572. }
  573. return Buffer;
  574. }
  575. /**
  576. Copies a buffer to an allocated buffer of a certain pool type.
  577. Allocates the number bytes specified by AllocationSize of a certain pool type, copies
  578. AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
  579. allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
  580. is not enough memory remaining to satisfy the request, then NULL is returned.
  581. If Buffer is NULL, then ASSERT().
  582. If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
  583. @param PoolType The type of pool to allocate.
  584. @param AllocationSize The number of bytes to allocate and zero.
  585. @param Buffer The buffer to copy to the allocated buffer.
  586. @return A pointer to the allocated buffer or NULL if allocation fails.
  587. **/
  588. VOID *
  589. InternalAllocateCopyPool (
  590. IN EFI_MEMORY_TYPE PoolType,
  591. IN UINTN AllocationSize,
  592. IN CONST VOID *Buffer
  593. )
  594. {
  595. VOID *Memory;
  596. ASSERT (Buffer != NULL);
  597. ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1));
  598. Memory = InternalAllocatePool (PoolType, AllocationSize);
  599. if (Memory != NULL) {
  600. Memory = CopyMem (Memory, Buffer, AllocationSize);
  601. }
  602. return Memory;
  603. }
  604. /**
  605. Copies a buffer to an allocated buffer of type EfiBootServicesData.
  606. Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
  607. AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
  608. allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
  609. is not enough memory remaining to satisfy the request, then NULL is returned.
  610. If Buffer is NULL, then ASSERT().
  611. If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
  612. @param AllocationSize The number of bytes to allocate and zero.
  613. @param Buffer The buffer to copy to the allocated buffer.
  614. @return A pointer to the allocated buffer or NULL if allocation fails.
  615. **/
  616. VOID *
  617. EFIAPI
  618. AllocateCopyPool (
  619. IN UINTN AllocationSize,
  620. IN CONST VOID *Buffer
  621. )
  622. {
  623. VOID *NewBuffer;
  624. NewBuffer = InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
  625. if (NewBuffer != NULL) {
  626. MemoryProfileLibRecord (
  627. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  628. MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL,
  629. EfiBootServicesData,
  630. NewBuffer,
  631. AllocationSize,
  632. NULL
  633. );
  634. }
  635. return NewBuffer;
  636. }
  637. /**
  638. Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
  639. Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
  640. AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
  641. allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
  642. is not enough memory remaining to satisfy the request, then NULL is returned.
  643. If Buffer is NULL, then ASSERT().
  644. If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
  645. @param AllocationSize The number of bytes to allocate and zero.
  646. @param Buffer The buffer to copy to the allocated buffer.
  647. @return A pointer to the allocated buffer or NULL if allocation fails.
  648. **/
  649. VOID *
  650. EFIAPI
  651. AllocateRuntimeCopyPool (
  652. IN UINTN AllocationSize,
  653. IN CONST VOID *Buffer
  654. )
  655. {
  656. VOID *NewBuffer;
  657. NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
  658. if (NewBuffer != NULL) {
  659. MemoryProfileLibRecord (
  660. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  661. MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL,
  662. EfiRuntimeServicesData,
  663. NewBuffer,
  664. AllocationSize,
  665. NULL
  666. );
  667. }
  668. return NewBuffer;
  669. }
  670. /**
  671. Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
  672. Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
  673. AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
  674. allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
  675. is not enough memory remaining to satisfy the request, then NULL is returned.
  676. If Buffer is NULL, then ASSERT().
  677. If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
  678. @param AllocationSize The number of bytes to allocate and zero.
  679. @param Buffer The buffer to copy to the allocated buffer.
  680. @return A pointer to the allocated buffer or NULL if allocation fails.
  681. **/
  682. VOID *
  683. EFIAPI
  684. AllocateReservedCopyPool (
  685. IN UINTN AllocationSize,
  686. IN CONST VOID *Buffer
  687. )
  688. {
  689. VOID *NewBuffer;
  690. NewBuffer = InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
  691. if (NewBuffer != NULL) {
  692. MemoryProfileLibRecord (
  693. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  694. MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL,
  695. EfiRuntimeServicesData,
  696. NewBuffer,
  697. AllocationSize,
  698. NULL
  699. );
  700. }
  701. return NewBuffer;
  702. }
  703. /**
  704. Reallocates a buffer of a specified memory type.
  705. Allocates and zeros the number bytes specified by NewSize from memory of the type
  706. specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
  707. NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
  708. OldBuffer is freed. A pointer to the newly allocated buffer is returned.
  709. If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
  710. enough memory remaining to satisfy the request, then NULL is returned.
  711. If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
  712. is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
  713. @param PoolType The type of pool to allocate.
  714. @param OldSize The size, in bytes, of OldBuffer.
  715. @param NewSize The size, in bytes, of the buffer to reallocate.
  716. @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
  717. parameter that may be NULL.
  718. @return A pointer to the allocated buffer or NULL if allocation fails.
  719. **/
  720. VOID *
  721. InternalReallocatePool (
  722. IN EFI_MEMORY_TYPE PoolType,
  723. IN UINTN OldSize,
  724. IN UINTN NewSize,
  725. IN VOID *OldBuffer OPTIONAL
  726. )
  727. {
  728. VOID *NewBuffer;
  729. NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
  730. if ((NewBuffer != NULL) && (OldBuffer != NULL)) {
  731. CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
  732. FreePool (OldBuffer);
  733. }
  734. return NewBuffer;
  735. }
  736. /**
  737. Reallocates a buffer of type EfiBootServicesData.
  738. Allocates and zeros the number bytes specified by NewSize from memory of type
  739. EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
  740. NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
  741. OldBuffer is freed. A pointer to the newly allocated buffer is returned.
  742. If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
  743. enough memory remaining to satisfy the request, then NULL is returned.
  744. If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
  745. is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
  746. @param OldSize The size, in bytes, of OldBuffer.
  747. @param NewSize The size, in bytes, of the buffer to reallocate.
  748. @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
  749. parameter that may be NULL.
  750. @return A pointer to the allocated buffer or NULL if allocation fails.
  751. **/
  752. VOID *
  753. EFIAPI
  754. ReallocatePool (
  755. IN UINTN OldSize,
  756. IN UINTN NewSize,
  757. IN VOID *OldBuffer OPTIONAL
  758. )
  759. {
  760. VOID *Buffer;
  761. Buffer = InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);
  762. if (Buffer != NULL) {
  763. MemoryProfileLibRecord (
  764. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  765. MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL,
  766. EfiBootServicesData,
  767. Buffer,
  768. NewSize,
  769. NULL
  770. );
  771. }
  772. return Buffer;
  773. }
  774. /**
  775. Reallocates a buffer of type EfiRuntimeServicesData.
  776. Allocates and zeros the number bytes specified by NewSize from memory of type
  777. EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
  778. NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
  779. OldBuffer is freed. A pointer to the newly allocated buffer is returned.
  780. If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
  781. enough memory remaining to satisfy the request, then NULL is returned.
  782. If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
  783. is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
  784. @param OldSize The size, in bytes, of OldBuffer.
  785. @param NewSize The size, in bytes, of the buffer to reallocate.
  786. @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
  787. parameter that may be NULL.
  788. @return A pointer to the allocated buffer or NULL if allocation fails.
  789. **/
  790. VOID *
  791. EFIAPI
  792. ReallocateRuntimePool (
  793. IN UINTN OldSize,
  794. IN UINTN NewSize,
  795. IN VOID *OldBuffer OPTIONAL
  796. )
  797. {
  798. VOID *Buffer;
  799. Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
  800. if (Buffer != NULL) {
  801. MemoryProfileLibRecord (
  802. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  803. MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL,
  804. EfiRuntimeServicesData,
  805. Buffer,
  806. NewSize,
  807. NULL
  808. );
  809. }
  810. return Buffer;
  811. }
  812. /**
  813. Reallocates a buffer of type EfiReservedMemoryType.
  814. Allocates and zeros the number bytes specified by NewSize from memory of type
  815. EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and
  816. NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
  817. OldBuffer is freed. A pointer to the newly allocated buffer is returned.
  818. If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
  819. enough memory remaining to satisfy the request, then NULL is returned.
  820. If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
  821. is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
  822. @param OldSize The size, in bytes, of OldBuffer.
  823. @param NewSize The size, in bytes, of the buffer to reallocate.
  824. @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
  825. parameter that may be NULL.
  826. @return A pointer to the allocated buffer or NULL if allocation fails.
  827. **/
  828. VOID *
  829. EFIAPI
  830. ReallocateReservedPool (
  831. IN UINTN OldSize,
  832. IN UINTN NewSize,
  833. IN VOID *OldBuffer OPTIONAL
  834. )
  835. {
  836. VOID *Buffer;
  837. Buffer = InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);
  838. if (Buffer != NULL) {
  839. MemoryProfileLibRecord (
  840. (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
  841. MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL,
  842. EfiReservedMemoryType,
  843. Buffer,
  844. NewSize,
  845. NULL
  846. );
  847. }
  848. return Buffer;
  849. }
  850. /**
  851. Frees a buffer that was previously allocated with one of the pool allocation functions in the
  852. Memory Allocation Library.
  853. Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
  854. pool allocation services of the Memory Allocation Library. If it is not possible to free pool
  855. resources, then this function will perform no actions.
  856. If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
  857. then ASSERT().
  858. @param Buffer Pointer to the buffer to free.
  859. **/
  860. VOID
  861. EFIAPI
  862. FreePool (
  863. IN VOID *Buffer
  864. )
  865. {
  866. EFI_STATUS Status;
  867. Status = CoreFreePool (Buffer);
  868. ASSERT_EFI_ERROR (Status);
  869. }