blob: 26947f185797230e1f180b8a944afb063abef7f9 [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Damien Rothbedbd672016-01-18 13:59:26 -07002
Arthur Heymanse6a60fd2022-05-16 09:28:18 +02003#pragma pack(push)
Elyes HAOUAS19f5ba82018-10-14 14:52:06 +02004#include <AGESA.h>
Arthur Heymanse6a60fd2022-05-16 09:28:18 +02005#pragma pack(pop)
6
Elyes HAOUAS19f5ba82018-10-14 14:52:06 +02007#include <amdlib.h>
Kyösti Mälkkief9343c2014-05-04 11:42:55 +03008
9#include <cbmem.h>
Kyösti Mälkkida740412017-03-05 18:57:03 +020010#include <northbridge/amd/agesa/agesa_helper.h>
Kyösti Mälkkif7284082015-05-26 10:12:45 +030011#include <northbridge/amd/agesa/BiosCallOuts.h>
12
Furquan Shaikh76cedd22020-05-02 10:24:23 -070013#include <acpi/acpi.h>
Elyes HAOUAS20eaef02019-03-29 17:45:28 +010014#include <console/console.h>
Kyösti Mälkkief9343c2014-05-04 11:42:55 +030015#include <string.h>
16
Kyösti Mälkkib1fcbf32015-05-26 11:25:13 +030017/* BIOS_HEAP_START_ADDRESS is only for cold boots. */
18#define BIOS_HEAP_SIZE 0x30000
19#define BIOS_HEAP_START_ADDRESS 0x010000000
20
Julius Wernercd49cce2019-03-05 16:53:33 -080021#if CONFIG(HAVE_ACPI_RESUME) && (HIGH_MEMORY_SCRATCH < BIOS_HEAP_SIZE)
Kyösti Mälkkif7284082015-05-26 10:12:45 +030022#error Increase HIGH_MEMORY_SCRATCH allocation
23#endif
24
Kyösti Mälkkib1fcbf32015-05-26 11:25:13 +030025void *GetHeapBase(void)
Kyösti Mälkkief9343c2014-05-04 11:42:55 +030026{
Kyösti Mälkkib1fcbf32015-05-26 11:25:13 +030027 void *heap = (void *)BIOS_HEAP_START_ADDRESS;
Kyösti Mälkkief9343c2014-05-04 11:42:55 +030028
Kyösti Mälkki42402772017-03-29 15:55:23 +030029 if (acpi_is_wakeup_s3()) {
30 /* FIXME: For S3 resume path, buffer is in CBMEM
31 * with some arbitrary header. */
Kyösti Mälkkib1fcbf32015-05-26 11:25:13 +030032 heap = cbmem_find(CBMEM_ID_RESUME_SCRATCH);
Kyösti Mälkki42402772017-03-29 15:55:23 +030033 heap += 0x10;
34 }
Kyösti Mälkki78c5d582015-01-09 23:48:47 +020035
Kyösti Mälkkief9343c2014-05-04 11:42:55 +030036 return heap;
37}
38
39void EmptyHeap(void)
40{
Kyösti Mälkkib1fcbf32015-05-26 11:25:13 +030041 void *base = GetHeapBase();
42 memset(base, 0, BIOS_HEAP_SIZE);
Kyösti Mälkki50e6daf2016-11-27 06:37:52 +020043
44 printk(BIOS_DEBUG, "Wiped HEAP at [%08x - %08x]\n",
Elyes Haouas76c63232022-07-16 09:47:00 +020045 (unsigned int)(uintptr_t)base, (unsigned int)(uintptr_t) base + BIOS_HEAP_SIZE - 1);
Kyösti Mälkkib1fcbf32015-05-26 11:25:13 +030046}
47
Kyösti Mälkkibceccec2017-03-29 10:59:21 +030048#if defined(HEAP_CALLOUT_RUNTIME) && ENV_RAMSTAGE
Kyösti Mälkkief9343c2014-05-04 11:42:55 +030049
50#define AGESA_RUNTIME_SIZE 4096
Kyösti Mälkkibceccec2017-03-29 10:59:21 +030051static AGESA_STATUS alloc_cbmem(AGESA_BUFFER_PARAMS *AllocParams)
52{
Kyösti Mälkkief9343c2014-05-04 11:42:55 +030053 static unsigned int used = 0;
54 void *p = cbmem_find(CBMEM_ID_AGESA_RUNTIME);
55
56 if ((AGESA_RUNTIME_SIZE - used) < AllocParams->BufferLength) {
57 return AGESA_BOUNDS_CHK;
58 }
59
60 /* first time allocation */
61 if (!p) {
62 p = cbmem_add(CBMEM_ID_AGESA_RUNTIME, AGESA_RUNTIME_SIZE);
63 if (!p)
64 return AGESA_BOUNDS_CHK;
65 }
66
67 AllocParams->BufferPointer = p + used;
68 used += AllocParams->BufferLength;
69 return AGESA_SUCCESS;
70}
71#endif
72
Kyösti Mälkki82fbda72015-01-02 22:46:32 +020073typedef struct _BIOS_HEAP_MANAGER {
74 UINT32 StartOfAllocatedNodes;
75 UINT32 StartOfFreedNodes;
76} BIOS_HEAP_MANAGER;
77
78typedef struct _BIOS_BUFFER_NODE {
79 UINT32 BufferHandle;
80 UINT32 BufferSize;
81 UINT32 NextNodeOffset;
82} BIOS_BUFFER_NODE;
83
Kyösti Mälkki45ff9cb2017-03-29 10:59:45 +030084static AGESA_STATUS agesa_AllocateBuffer(BIOS_HEAP_MANAGER *BiosHeapBasePtr,
85 AGESA_BUFFER_PARAMS *AllocParams)
Kyösti Mälkkief9343c2014-05-04 11:42:55 +030086{
87 UINT32 AvailableHeapSize;
Kyösti Mälkki45ff9cb2017-03-29 10:59:45 +030088 UINT8 *BiosHeapBaseAddr = (void *)BiosHeapBasePtr;
Kyösti Mälkkief9343c2014-05-04 11:42:55 +030089 UINT32 CurrNodeOffset;
90 UINT32 PrevNodeOffset;
91 UINT32 FreedNodeOffset;
92 UINT32 BestFitNodeOffset;
93 UINT32 BestFitPrevNodeOffset;
94 UINT32 NextFreeOffset;
95 BIOS_BUFFER_NODE *CurrNodePtr;
96 BIOS_BUFFER_NODE *FreedNodePtr;
97 BIOS_BUFFER_NODE *BestFitNodePtr;
98 BIOS_BUFFER_NODE *BestFitPrevNodePtr;
99 BIOS_BUFFER_NODE *NextFreePtr;
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300100
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300101 AllocParams->BufferPointer = NULL;
Elyes HAOUAS5e0242b2016-10-03 22:06:08 +0200102 AvailableHeapSize = BIOS_HEAP_SIZE - sizeof(BIOS_HEAP_MANAGER);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300103
104 if (BiosHeapBasePtr->StartOfAllocatedNodes == 0) {
105 /* First allocation */
Elyes HAOUAS5e0242b2016-10-03 22:06:08 +0200106 CurrNodeOffset = sizeof(BIOS_HEAP_MANAGER);
Elyes Haouas76c63232022-07-16 09:47:00 +0200107 CurrNodePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + CurrNodeOffset);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300108 CurrNodePtr->BufferHandle = AllocParams->BufferHandle;
109 CurrNodePtr->BufferSize = AllocParams->BufferLength;
110 CurrNodePtr->NextNodeOffset = 0;
Elyes Haouas76c63232022-07-16 09:47:00 +0200111 AllocParams->BufferPointer = (UINT8 *)CurrNodePtr + sizeof(BIOS_BUFFER_NODE);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300112
113 /* Update the remaining free space */
Elyes HAOUAS5e0242b2016-10-03 22:06:08 +0200114 FreedNodeOffset = CurrNodeOffset + CurrNodePtr->BufferSize + sizeof(BIOS_BUFFER_NODE);
Elyes Haouas76c63232022-07-16 09:47:00 +0200115 FreedNodePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + FreedNodeOffset);
Marc Jones9826d1b2018-01-17 11:33:56 -0700116 FreedNodePtr->BufferSize = AvailableHeapSize
117 - (FreedNodeOffset - CurrNodeOffset)
118 - sizeof(BIOS_BUFFER_NODE);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300119 FreedNodePtr->NextNodeOffset = 0;
120
121 /* Update the offsets for Allocated and Freed nodes */
122 BiosHeapBasePtr->StartOfAllocatedNodes = CurrNodeOffset;
123 BiosHeapBasePtr->StartOfFreedNodes = FreedNodeOffset;
124 } else {
125 /* Find out whether BufferHandle has been allocated on the heap.
126 * If it has, return AGESA_BOUNDS_CHK.
127 */
128 CurrNodeOffset = BiosHeapBasePtr->StartOfAllocatedNodes;
Elyes Haouas76c63232022-07-16 09:47:00 +0200129 CurrNodePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + CurrNodeOffset);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300130
131 while (CurrNodeOffset != 0) {
Elyes Haouas76c63232022-07-16 09:47:00 +0200132 CurrNodePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + CurrNodeOffset);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300133 if (CurrNodePtr->BufferHandle == AllocParams->BufferHandle) {
134 return AGESA_BOUNDS_CHK;
135 }
136 CurrNodeOffset = CurrNodePtr->NextNodeOffset;
137 /* If BufferHandle has not been allocated on the heap, CurrNodePtr here points
138 * to the end of the allocated nodes list.
139 */
140 }
141 /* Find the node that best fits the requested buffer size */
142 FreedNodeOffset = BiosHeapBasePtr->StartOfFreedNodes;
143 PrevNodeOffset = FreedNodeOffset;
144 BestFitNodeOffset = 0;
145 BestFitPrevNodeOffset = 0;
146 while (FreedNodeOffset != 0) {
Elyes Haouas76c63232022-07-16 09:47:00 +0200147 FreedNodePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + FreedNodeOffset);
Elyes HAOUAS5e0242b2016-10-03 22:06:08 +0200148 if (FreedNodePtr->BufferSize >= (AllocParams->BufferLength + sizeof(BIOS_BUFFER_NODE))) {
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300149 if (BestFitNodeOffset == 0) {
150 /* First node that fits the requested buffer size */
151 BestFitNodeOffset = FreedNodeOffset;
152 BestFitPrevNodeOffset = PrevNodeOffset;
153 } else {
154 /* Find out whether current node is a better fit than the previous nodes */
Elyes Haouas76c63232022-07-16 09:47:00 +0200155 BestFitNodePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + BestFitNodeOffset);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300156 if (BestFitNodePtr->BufferSize > FreedNodePtr->BufferSize) {
157 BestFitNodeOffset = FreedNodeOffset;
158 BestFitPrevNodeOffset = PrevNodeOffset;
159 }
160 }
161 }
162 PrevNodeOffset = FreedNodeOffset;
163 FreedNodeOffset = FreedNodePtr->NextNodeOffset;
164 } /* end of while loop */
165
166 if (BestFitNodeOffset == 0) {
167 /* If we could not find a node that fits the requested buffer
168 * size, return AGESA_BOUNDS_CHK.
169 */
170 return AGESA_BOUNDS_CHK;
171 } else {
Elyes Haouas76c63232022-07-16 09:47:00 +0200172 BestFitNodePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + BestFitNodeOffset);
173 BestFitPrevNodePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + BestFitPrevNodeOffset);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300174
175 /* If BestFitNode is larger than the requested buffer, fragment the node further */
Elyes HAOUAS5e0242b2016-10-03 22:06:08 +0200176 if (BestFitNodePtr->BufferSize > (AllocParams->BufferLength + sizeof(BIOS_BUFFER_NODE))) {
177 NextFreeOffset = BestFitNodeOffset + AllocParams->BufferLength + sizeof(BIOS_BUFFER_NODE);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300178
Elyes Haouas76c63232022-07-16 09:47:00 +0200179 NextFreePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + NextFreeOffset);
Elyes HAOUAS5e0242b2016-10-03 22:06:08 +0200180 NextFreePtr->BufferSize = BestFitNodePtr->BufferSize - (AllocParams->BufferLength + sizeof(BIOS_BUFFER_NODE));
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300181 NextFreePtr->NextNodeOffset = BestFitNodePtr->NextNodeOffset;
182 } else {
183 /* Otherwise, next free node is NextNodeOffset of BestFitNode */
184 NextFreeOffset = BestFitNodePtr->NextNodeOffset;
185 }
186
187 /* If BestFitNode is the first buffer in the list, then update
188 * StartOfFreedNodes to reflect the new free node.
189 */
190 if (BestFitNodeOffset == BiosHeapBasePtr->StartOfFreedNodes) {
191 BiosHeapBasePtr->StartOfFreedNodes = NextFreeOffset;
192 } else {
193 BestFitPrevNodePtr->NextNodeOffset = NextFreeOffset;
194 }
195
196 /* Add BestFitNode to the list of Allocated nodes */
197 CurrNodePtr->NextNodeOffset = BestFitNodeOffset;
198 BestFitNodePtr->BufferSize = AllocParams->BufferLength;
199 BestFitNodePtr->BufferHandle = AllocParams->BufferHandle;
200 BestFitNodePtr->NextNodeOffset = 0;
201
202 /* Remove BestFitNode from list of Freed nodes */
Elyes Haouas76c63232022-07-16 09:47:00 +0200203 AllocParams->BufferPointer = (UINT8 *)BestFitNodePtr + sizeof(BIOS_BUFFER_NODE);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300204 }
205 }
206
207 return AGESA_SUCCESS;
208}
209
Kyösti Mälkki45ff9cb2017-03-29 10:59:45 +0300210static AGESA_STATUS agesa_DeallocateBuffer(BIOS_HEAP_MANAGER *BiosHeapBasePtr,
211 AGESA_BUFFER_PARAMS *AllocParams)
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300212{
Kyösti Mälkki45ff9cb2017-03-29 10:59:45 +0300213 UINT8 *BiosHeapBaseAddr = (void *)BiosHeapBasePtr;
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300214 UINT32 AllocNodeOffset;
215 UINT32 PrevNodeOffset;
216 UINT32 NextNodeOffset;
217 UINT32 FreedNodeOffset;
218 UINT32 EndNodeOffset;
219 BIOS_BUFFER_NODE *AllocNodePtr;
220 BIOS_BUFFER_NODE *PrevNodePtr;
221 BIOS_BUFFER_NODE *FreedNodePtr;
222 BIOS_BUFFER_NODE *NextNodePtr;
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300223
224 /* Find target node to deallocate in list of allocated nodes.
225 * Return AGESA_BOUNDS_CHK if the BufferHandle is not found.
226 */
227 AllocNodeOffset = BiosHeapBasePtr->StartOfAllocatedNodes;
Elyes Haouas76c63232022-07-16 09:47:00 +0200228 AllocNodePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + AllocNodeOffset);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300229 PrevNodeOffset = AllocNodeOffset;
230
231 while (AllocNodePtr->BufferHandle != AllocParams->BufferHandle) {
232 if (AllocNodePtr->NextNodeOffset == 0) {
233 return AGESA_BOUNDS_CHK;
234 }
235 PrevNodeOffset = AllocNodeOffset;
236 AllocNodeOffset = AllocNodePtr->NextNodeOffset;
Elyes Haouas76c63232022-07-16 09:47:00 +0200237 AllocNodePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + AllocNodeOffset);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300238 }
239
240 /* Remove target node from list of allocated nodes */
Elyes Haouas76c63232022-07-16 09:47:00 +0200241 PrevNodePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + PrevNodeOffset);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300242 PrevNodePtr->NextNodeOffset = AllocNodePtr->NextNodeOffset;
243
244 /* Zero out the buffer, and clear the BufferHandle */
Elyes Haouas76c63232022-07-16 09:47:00 +0200245 LibAmdMemFill((UINT8 *)AllocNodePtr + sizeof(BIOS_BUFFER_NODE), 0, AllocNodePtr->BufferSize, &(AllocParams->StdHeader));
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300246 AllocNodePtr->BufferHandle = 0;
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300247
248 /* Add deallocated node in order to the list of freed nodes */
249 FreedNodeOffset = BiosHeapBasePtr->StartOfFreedNodes;
Elyes Haouas76c63232022-07-16 09:47:00 +0200250 FreedNodePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + FreedNodeOffset);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300251
Marc Jones9826d1b2018-01-17 11:33:56 -0700252 EndNodeOffset = AllocNodeOffset + AllocNodePtr->BufferSize +
253 sizeof(BIOS_BUFFER_NODE);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300254
255 if (AllocNodeOffset < FreedNodeOffset) {
256 /* Add to the start of the freed list */
257 if (EndNodeOffset == FreedNodeOffset) {
258 /* If the freed node is adjacent to the first node in the list, concatenate both nodes */
Marc Jones9826d1b2018-01-17 11:33:56 -0700259 AllocNodePtr->BufferSize += FreedNodePtr->BufferSize +
260 sizeof(BIOS_BUFFER_NODE);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300261 AllocNodePtr->NextNodeOffset = FreedNodePtr->NextNodeOffset;
262
Marc Jones9826d1b2018-01-17 11:33:56 -0700263 /* Zero out the FreedNode header */
264 memset((UINT8 *)FreedNodePtr, 0,
265 sizeof(BIOS_BUFFER_NODE));
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300266 } else {
267 /* Otherwise, add freed node to the start of the list
268 * Update NextNodeOffset and BufferSize to include the
269 * size of BIOS_BUFFER_NODE.
270 */
271 AllocNodePtr->NextNodeOffset = FreedNodeOffset;
272 }
273 /* Update StartOfFreedNodes to the new first node */
274 BiosHeapBasePtr->StartOfFreedNodes = AllocNodeOffset;
275 } else {
276 /* Traverse list of freed nodes to find where the deallocated node
277 * should be placed.
278 */
279 NextNodeOffset = FreedNodeOffset;
280 NextNodePtr = FreedNodePtr;
281 while (AllocNodeOffset > NextNodeOffset) {
282 PrevNodeOffset = NextNodeOffset;
283 if (NextNodePtr->NextNodeOffset == 0) {
284 break;
285 }
286 NextNodeOffset = NextNodePtr->NextNodeOffset;
Elyes Haouas76c63232022-07-16 09:47:00 +0200287 NextNodePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + NextNodeOffset);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300288 }
289
290 /* If deallocated node is adjacent to the next node,
291 * concatenate both nodes.
292 */
293 if (NextNodeOffset == EndNodeOffset) {
Elyes Haouas76c63232022-07-16 09:47:00 +0200294 NextNodePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + NextNodeOffset);
Marc Jones9826d1b2018-01-17 11:33:56 -0700295 AllocNodePtr->BufferSize += NextNodePtr->BufferSize +
296 sizeof(BIOS_BUFFER_NODE);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300297 AllocNodePtr->NextNodeOffset = NextNodePtr->NextNodeOffset;
298
Marc Jones9826d1b2018-01-17 11:33:56 -0700299 /* Zero out the NextNode header */
300 memset((UINT8 *)NextNodePtr, 0,
301 sizeof(BIOS_BUFFER_NODE));
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300302 } else {
303 /*AllocNodePtr->NextNodeOffset = FreedNodePtr->NextNodeOffset; */
304 AllocNodePtr->NextNodeOffset = NextNodeOffset;
305 }
306 /* If deallocated node is adjacent to the previous node,
307 * concatenate both nodes.
308 */
Elyes Haouas76c63232022-07-16 09:47:00 +0200309 PrevNodePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + PrevNodeOffset);
Marc Jones9826d1b2018-01-17 11:33:56 -0700310 EndNodeOffset = PrevNodeOffset + PrevNodePtr->BufferSize +
311 sizeof(BIOS_BUFFER_NODE);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300312 if (AllocNodeOffset == EndNodeOffset) {
313 PrevNodePtr->NextNodeOffset = AllocNodePtr->NextNodeOffset;
Marc Jones9826d1b2018-01-17 11:33:56 -0700314 PrevNodePtr->BufferSize += AllocNodePtr->BufferSize +
315 sizeof(BIOS_BUFFER_NODE);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300316
Marc Jones9826d1b2018-01-17 11:33:56 -0700317 /* Zero out the AllocNode header */
318 memset((UINT8 *)AllocNodePtr, 0,
319 sizeof(BIOS_BUFFER_NODE));
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300320 } else {
321 PrevNodePtr->NextNodeOffset = AllocNodeOffset;
322 }
323 }
324 return AGESA_SUCCESS;
325}
326
Kyösti Mälkki45ff9cb2017-03-29 10:59:45 +0300327static AGESA_STATUS agesa_LocateBuffer(BIOS_HEAP_MANAGER *BiosHeapBasePtr,
328 AGESA_BUFFER_PARAMS *AllocParams)
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300329{
330 UINT32 AllocNodeOffset;
Kyösti Mälkki45ff9cb2017-03-29 10:59:45 +0300331 UINT8 *BiosHeapBaseAddr = (void *)BiosHeapBasePtr;
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300332 BIOS_BUFFER_NODE *AllocNodePtr;
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300333
334 AllocNodeOffset = BiosHeapBasePtr->StartOfAllocatedNodes;
Elyes Haouas76c63232022-07-16 09:47:00 +0200335 AllocNodePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + AllocNodeOffset);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300336
337 while (AllocParams->BufferHandle != AllocNodePtr->BufferHandle) {
338 if (AllocNodePtr->NextNodeOffset == 0) {
339 AllocParams->BufferPointer = NULL;
340 AllocParams->BufferLength = 0;
341 return AGESA_BOUNDS_CHK;
342 } else {
343 AllocNodeOffset = AllocNodePtr->NextNodeOffset;
Elyes Haouas76c63232022-07-16 09:47:00 +0200344 AllocNodePtr = (BIOS_BUFFER_NODE *)(BiosHeapBaseAddr + AllocNodeOffset);
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300345 }
346 }
347
Elyes Haouas76c63232022-07-16 09:47:00 +0200348 AllocParams->BufferPointer = (UINT8 *)((UINT8 *) AllocNodePtr + sizeof(BIOS_BUFFER_NODE));
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300349 AllocParams->BufferLength = AllocNodePtr->BufferSize;
350
351 return AGESA_SUCCESS;
Kyösti Mälkkief9343c2014-05-04 11:42:55 +0300352}
Kyösti Mälkki82fbda72015-01-02 22:46:32 +0200353
Stefan Reinauerdd132a52015-07-30 11:16:37 -0700354AGESA_STATUS HeapManagerCallout(UINT32 Func, UINTN Data, VOID *ConfigPtr)
Kyösti Mälkki82fbda72015-01-02 22:46:32 +0200355{
Kyösti Mälkkibceccec2017-03-29 10:59:21 +0300356 AGESA_BUFFER_PARAMS *AllocParams = ConfigPtr;
357
Kyösti Mälkki45ff9cb2017-03-29 10:59:45 +0300358#if defined(HEAP_CALLOUT_RUNTIME) && ENV_RAMSTAGE
Kyösti Mälkkibceccec2017-03-29 10:59:21 +0300359 if (Func == AGESA_ALLOCATE_BUFFER && Data == HEAP_CALLOUT_RUNTIME)
360 return alloc_cbmem(AllocParams);
361#endif
362
Kyösti Mälkki45ff9cb2017-03-29 10:59:45 +0300363 /* Must not call GetHeapBase() in AGESA_UNSUPPORTED path. */
Kyösti Mälkki82fbda72015-01-02 22:46:32 +0200364 if (Func == AGESA_LOCATE_BUFFER)
Kyösti Mälkki45ff9cb2017-03-29 10:59:45 +0300365 return agesa_LocateBuffer(GetHeapBase(), AllocParams);
Kyösti Mälkki82fbda72015-01-02 22:46:32 +0200366 else if (Func == AGESA_ALLOCATE_BUFFER)
Kyösti Mälkki45ff9cb2017-03-29 10:59:45 +0300367 return agesa_AllocateBuffer(GetHeapBase(), AllocParams);
Kyösti Mälkki82fbda72015-01-02 22:46:32 +0200368 else if (Func == AGESA_DEALLOCATE_BUFFER)
Kyösti Mälkki45ff9cb2017-03-29 10:59:45 +0300369 return agesa_DeallocateBuffer(GetHeapBase(), AllocParams);
370
371 return AGESA_UNSUPPORTED;
Kyösti Mälkki82fbda72015-01-02 22:46:32 +0200372}