2 * This file is part of the coreboot project.
4 * Copyright (C) 2011 Advanced Micro Devices, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include "agesawrapper.h"
23 #include "BiosCallOuts.h"
24 #include "heapManager.h"
27 STATIC BIOS_CALLOUT_STRUCT BiosCallouts[] =
29 {AGESA_ALLOCATE_BUFFER,
33 {AGESA_DEALLOCATE_BUFFER,
49 {AGESA_READ_SPD_RECOVERY,
57 {AGESA_GNB_PCIE_SLOT_RESET,
61 {AGESA_HOOKBEFORE_DRAM_INIT,
62 BiosHookBeforeDramInit
65 {AGESA_HOOKBEFORE_DRAM_INIT_RECOVERY,
66 BiosHookBeforeDramInitRecovery
69 {AGESA_HOOKBEFORE_DQS_TRAINING,
70 BiosHookBeforeDQSTraining
73 {AGESA_HOOKBEFORE_EXIT_SELF_REF,
74 BiosHookBeforeExitSelfRefresh
78 AGESA_STATUS GetBiosCallout (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
81 AGESA_STATUS CalloutStatus;
82 UINTN CallOutCount = sizeof (BiosCallouts) / sizeof (BiosCallouts [0]);
84 CalloutStatus = AGESA_UNSUPPORTED;
86 for (i = 0; i < CallOutCount; i++)
88 if (BiosCallouts[i].CalloutName == Func)
90 CalloutStatus = BiosCallouts[i].CalloutPtr (Func, Data, ConfigPtr);
98 AGESA_STATUS BiosAllocateBuffer (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
100 UINT32 AvailableHeapSize;
101 UINT8 *BiosHeapBaseAddr;
102 UINT32 CurrNodeOffset;
103 UINT32 PrevNodeOffset;
104 UINT32 FreedNodeOffset;
105 UINT32 BestFitNodeOffset;
106 UINT32 BestFitPrevNodeOffset;
107 UINT32 NextFreeOffset;
108 BIOS_BUFFER_NODE *CurrNodePtr;
109 BIOS_BUFFER_NODE *FreedNodePtr;
110 BIOS_BUFFER_NODE *BestFitNodePtr;
111 BIOS_BUFFER_NODE *BestFitPrevNodePtr;
112 BIOS_BUFFER_NODE *NextFreePtr;
113 BIOS_HEAP_MANAGER *BiosHeapBasePtr;
114 AGESA_BUFFER_PARAMS *AllocParams;
116 AllocParams = ((AGESA_BUFFER_PARAMS *) ConfigPtr);
117 AllocParams->BufferPointer = NULL;
119 AvailableHeapSize = BIOS_HEAP_SIZE - sizeof (BIOS_HEAP_MANAGER);
120 BiosHeapBaseAddr = (UINT8 *) BIOS_HEAP_START_ADDRESS;
121 BiosHeapBasePtr = (BIOS_HEAP_MANAGER *) BIOS_HEAP_START_ADDRESS;
123 if (BiosHeapBasePtr->StartOfAllocatedNodes == 0) {
124 /* First allocation */
125 CurrNodeOffset = sizeof (BIOS_HEAP_MANAGER);
126 CurrNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + CurrNodeOffset);
127 CurrNodePtr->BufferHandle = AllocParams->BufferHandle;
128 CurrNodePtr->BufferSize = AllocParams->BufferLength;
129 CurrNodePtr->NextNodeOffset = 0;
130 AllocParams->BufferPointer = (UINT8 *) CurrNodePtr + sizeof (BIOS_BUFFER_NODE);
132 /* Update the remaining free space */
133 FreedNodeOffset = CurrNodeOffset + CurrNodePtr->BufferSize + sizeof (BIOS_BUFFER_NODE);
134 FreedNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + FreedNodeOffset);
135 FreedNodePtr->BufferSize = AvailableHeapSize - sizeof (BIOS_BUFFER_NODE) - CurrNodePtr->BufferSize;
136 FreedNodePtr->NextNodeOffset = 0;
138 /* Update the offsets for Allocated and Freed nodes */
139 BiosHeapBasePtr->StartOfAllocatedNodes = CurrNodeOffset;
140 BiosHeapBasePtr->StartOfFreedNodes = FreedNodeOffset;
142 /* Find out whether BufferHandle has been allocated on the heap. */
143 /* If it has, return AGESA_BOUNDS_CHK */
144 CurrNodeOffset = BiosHeapBasePtr->StartOfAllocatedNodes;
145 CurrNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + CurrNodeOffset);
147 while (CurrNodeOffset != 0) {
148 CurrNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + CurrNodeOffset);
149 if (CurrNodePtr->BufferHandle == AllocParams->BufferHandle) {
150 return AGESA_BOUNDS_CHK;
152 CurrNodeOffset = CurrNodePtr->NextNodeOffset;
153 /* If BufferHandle has not been allocated on the heap, CurrNodePtr here points
154 to the end of the allocated nodes list.
158 /* Find the node that best fits the requested buffer size */
159 FreedNodeOffset = BiosHeapBasePtr->StartOfFreedNodes;
160 PrevNodeOffset = FreedNodeOffset;
161 BestFitNodeOffset = 0;
162 BestFitPrevNodeOffset = 0;
163 while (FreedNodeOffset != 0) {
164 FreedNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + FreedNodeOffset);
165 if (FreedNodePtr->BufferSize >= (AllocParams->BufferLength + sizeof (BIOS_BUFFER_NODE))) {
166 if (BestFitNodeOffset == 0) {
167 /* First node that fits the requested buffer size */
168 BestFitNodeOffset = FreedNodeOffset;
169 BestFitPrevNodeOffset = PrevNodeOffset;
171 /* Find out whether current node is a better fit than the previous nodes */
172 BestFitNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + BestFitNodeOffset);
173 if (BestFitNodePtr->BufferSize > FreedNodePtr->BufferSize) {
174 BestFitNodeOffset = FreedNodeOffset;
175 BestFitPrevNodeOffset = PrevNodeOffset;
179 PrevNodeOffset = FreedNodeOffset;
180 FreedNodeOffset = FreedNodePtr->NextNodeOffset;
181 } /* end of while loop */
184 if (BestFitNodeOffset == 0) {
185 /* If we could not find a node that fits the requested buffer */
186 /* size, return AGESA_BOUNDS_CHK */
187 return AGESA_BOUNDS_CHK;
189 BestFitNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + BestFitNodeOffset);
190 BestFitPrevNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + BestFitPrevNodeOffset);
192 /* If BestFitNode is larger than the requested buffer, fragment the node further */
193 if (BestFitNodePtr->BufferSize > (AllocParams->BufferLength + sizeof (BIOS_BUFFER_NODE))) {
194 NextFreeOffset = BestFitNodeOffset + AllocParams->BufferLength + sizeof (BIOS_BUFFER_NODE);
196 NextFreePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + NextFreeOffset);
197 NextFreePtr->BufferSize = BestFitNodePtr->BufferSize - (AllocParams->BufferLength + sizeof (BIOS_BUFFER_NODE));
198 NextFreePtr->NextNodeOffset = BestFitNodePtr->NextNodeOffset;
200 /* Otherwise, next free node is NextNodeOffset of BestFitNode */
201 NextFreeOffset = BestFitNodePtr->NextNodeOffset;
204 /* If BestFitNode is the first buffer in the list, then update
205 StartOfFreedNodes to reflect the new free node
207 if (BestFitNodeOffset == BiosHeapBasePtr->StartOfFreedNodes) {
208 BiosHeapBasePtr->StartOfFreedNodes = NextFreeOffset;
210 BestFitPrevNodePtr->NextNodeOffset = NextFreeOffset;
213 /* Add BestFitNode to the list of Allocated nodes */
214 CurrNodePtr->NextNodeOffset = BestFitNodeOffset;
215 BestFitNodePtr->BufferSize = AllocParams->BufferLength;
216 BestFitNodePtr->BufferHandle = AllocParams->BufferHandle;
217 BestFitNodePtr->NextNodeOffset = 0;
219 /* Remove BestFitNode from list of Freed nodes */
220 AllocParams->BufferPointer = (UINT8 *) BestFitNodePtr + sizeof (BIOS_BUFFER_NODE);
224 return AGESA_SUCCESS;
227 AGESA_STATUS BiosDeallocateBuffer (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
230 UINT8 *BiosHeapBaseAddr;
231 UINT32 AllocNodeOffset;
232 UINT32 PrevNodeOffset;
233 UINT32 NextNodeOffset;
234 UINT32 FreedNodeOffset;
235 UINT32 EndNodeOffset;
236 BIOS_BUFFER_NODE *AllocNodePtr;
237 BIOS_BUFFER_NODE *PrevNodePtr;
238 BIOS_BUFFER_NODE *FreedNodePtr;
239 BIOS_BUFFER_NODE *NextNodePtr;
240 BIOS_HEAP_MANAGER *BiosHeapBasePtr;
241 AGESA_BUFFER_PARAMS *AllocParams;
243 BiosHeapBaseAddr = (UINT8 *) BIOS_HEAP_START_ADDRESS;
244 BiosHeapBasePtr = (BIOS_HEAP_MANAGER *) BIOS_HEAP_START_ADDRESS;
246 AllocParams = (AGESA_BUFFER_PARAMS *) ConfigPtr;
248 /* Find target node to deallocate in list of allocated nodes.
249 Return AGESA_BOUNDS_CHK if the BufferHandle is not found
251 AllocNodeOffset = BiosHeapBasePtr->StartOfAllocatedNodes;
252 AllocNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + AllocNodeOffset);
253 PrevNodeOffset = AllocNodeOffset;
255 while (AllocNodePtr->BufferHandle != AllocParams->BufferHandle) {
256 if (AllocNodePtr->NextNodeOffset == 0) {
257 return AGESA_BOUNDS_CHK;
259 PrevNodeOffset = AllocNodeOffset;
260 AllocNodeOffset = AllocNodePtr->NextNodeOffset;
261 AllocNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + AllocNodeOffset);
264 /* Remove target node from list of allocated nodes */
265 PrevNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + PrevNodeOffset);
266 PrevNodePtr->NextNodeOffset = AllocNodePtr->NextNodeOffset;
268 /* Zero out the buffer, and clear the BufferHandle */
269 LibAmdMemFill ((UINT8 *)AllocNodePtr + sizeof (BIOS_BUFFER_NODE), 0, AllocNodePtr->BufferSize, &(AllocParams->StdHeader));
270 AllocNodePtr->BufferHandle = 0;
271 AllocNodePtr->BufferSize += sizeof (BIOS_BUFFER_NODE);
273 /* Add deallocated node in order to the list of freed nodes */
274 FreedNodeOffset = BiosHeapBasePtr->StartOfFreedNodes;
275 FreedNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + FreedNodeOffset);
277 EndNodeOffset = AllocNodeOffset + AllocNodePtr->BufferSize;
279 if (AllocNodeOffset < FreedNodeOffset) {
280 /* Add to the start of the freed list */
281 if (EndNodeOffset == FreedNodeOffset) {
282 /* If the freed node is adjacent to the first node in the list, concatenate both nodes */
283 AllocNodePtr->BufferSize += FreedNodePtr->BufferSize;
284 AllocNodePtr->NextNodeOffset = FreedNodePtr->NextNodeOffset;
286 /* Clear the BufferSize and NextNodeOffset of the previous first node */
287 FreedNodePtr->BufferSize = 0;
288 FreedNodePtr->NextNodeOffset = 0;
291 /* Otherwise, add freed node to the start of the list
292 Update NextNodeOffset and BufferSize to include the
293 size of BIOS_BUFFER_NODE
295 AllocNodePtr->NextNodeOffset = FreedNodeOffset;
297 /* Update StartOfFreedNodes to the new first node */
298 BiosHeapBasePtr->StartOfFreedNodes = AllocNodeOffset;
300 /* Traverse list of freed nodes to find where the deallocated node
303 NextNodeOffset = FreedNodeOffset;
304 NextNodePtr = FreedNodePtr;
305 while (AllocNodeOffset > NextNodeOffset) {
306 PrevNodeOffset = NextNodeOffset;
307 if (NextNodePtr->NextNodeOffset == 0) {
310 NextNodeOffset = NextNodePtr->NextNodeOffset;
311 NextNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + NextNodeOffset);
314 /* If deallocated node is adjacent to the next node,
315 concatenate both nodes
317 if (NextNodeOffset == EndNodeOffset) {
318 NextNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + NextNodeOffset);
319 AllocNodePtr->BufferSize += NextNodePtr->BufferSize;
320 AllocNodePtr->NextNodeOffset = NextNodePtr->NextNodeOffset;
322 NextNodePtr->BufferSize = 0;
323 NextNodePtr->NextNodeOffset = 0;
325 /*AllocNodePtr->NextNodeOffset = FreedNodePtr->NextNodeOffset; */
326 AllocNodePtr->NextNodeOffset = NextNodeOffset;
328 /* If deallocated node is adjacent to the previous node,
329 concatenate both nodes
331 PrevNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + PrevNodeOffset);
332 EndNodeOffset = PrevNodeOffset + PrevNodePtr->BufferSize;
333 if (AllocNodeOffset == EndNodeOffset) {
334 PrevNodePtr->NextNodeOffset = AllocNodePtr->NextNodeOffset;
335 PrevNodePtr->BufferSize += AllocNodePtr->BufferSize;
337 AllocNodePtr->BufferSize = 0;
338 AllocNodePtr->NextNodeOffset = 0;
340 PrevNodePtr->NextNodeOffset = AllocNodeOffset;
343 return AGESA_SUCCESS;
346 AGESA_STATUS BiosLocateBuffer (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
348 UINT32 AllocNodeOffset;
349 UINT8 *BiosHeapBaseAddr;
350 BIOS_BUFFER_NODE *AllocNodePtr;
351 BIOS_HEAP_MANAGER *BiosHeapBasePtr;
352 AGESA_BUFFER_PARAMS *AllocParams;
354 AllocParams = (AGESA_BUFFER_PARAMS *) ConfigPtr;
356 BiosHeapBaseAddr = (UINT8 *) BIOS_HEAP_START_ADDRESS;
357 BiosHeapBasePtr = (BIOS_HEAP_MANAGER *) BIOS_HEAP_START_ADDRESS;
359 AllocNodeOffset = BiosHeapBasePtr->StartOfAllocatedNodes;
360 AllocNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + AllocNodeOffset);
362 while (AllocParams->BufferHandle != AllocNodePtr->BufferHandle) {
363 if (AllocNodePtr->NextNodeOffset == 0) {
364 AllocParams->BufferPointer = NULL;
365 AllocParams->BufferLength = 0;
366 return AGESA_BOUNDS_CHK;
368 AllocNodeOffset = AllocNodePtr->NextNodeOffset;
369 AllocNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + AllocNodeOffset);
373 AllocParams->BufferPointer = (UINT8 *) ((UINT8 *) AllocNodePtr + sizeof (BIOS_BUFFER_NODE));
374 AllocParams->BufferLength = AllocNodePtr->BufferSize;
376 return AGESA_SUCCESS;
380 AGESA_STATUS BiosRunFuncOnAp (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
384 Status = agesawrapper_amdlaterunaptask (Func, Data, ConfigPtr);
388 AGESA_STATUS BiosReset (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
393 AMD_CONFIG_PARAMS *StdHeader;
396 StdHeader = ConfigPtr;
399 // Perform the RESET based upon the ResetType. In case of
400 // WARM_RESET_WHENVER and COLD_RESET_WHENEVER, the request will go to
401 // AmdResetManager. During the critical condition, where reset is required
402 // immediately, the reset will be invoked directly by writing 0x04 to port
403 // 0xCF9 (Reset Port).
406 case WARM_RESET_WHENEVER:
407 case COLD_RESET_WHENEVER:
410 case WARM_RESET_IMMEDIATELY:
411 case COLD_RESET_IMMEDIATELY:
413 LibAmdIoWrite (AccessWidth8, 0xCf9, &Value, StdHeader);
424 AGESA_STATUS BiosReadSpd (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
427 Status = AmdMemoryReadSPD (Func, Data, (AGESA_READ_SPD_PARAMS *)ConfigPtr);
432 AGESA_STATUS BiosDefaultRet (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
434 return AGESA_UNSUPPORTED;
436 /* Call the host environment interface to provide a user hook opportunity. */
437 AGESA_STATUS BiosHookBeforeDQSTraining (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
439 return AGESA_SUCCESS;
441 /* Call the host environment interface to provide a user hook opportunity. */
442 AGESA_STATUS BiosHookBeforeDramInit (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
446 MEM_DATA_STRUCT *MemData;
456 Status = AGESA_SUCCESS;
457 /* Get SB MMIO Base (AcpiMmioAddr) */
458 WriteIo8 (0xCD6, 0x27);
459 Data8 = ReadIo8(0xCD7);
461 WriteIo8 (0xCD6, 0x26);
462 Data8 = ReadIo8(0xCD7);
464 AcpiMmioAddr = (UINT32)Data16 << 16;
465 GpioMmioAddr = AcpiMmioAddr + GPIO_BASE;
467 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG178);
469 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
472 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, TempData8);
476 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
479 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, TempData8);
481 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG179);
483 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
486 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, TempData8);
490 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
493 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, TempData8);
495 switch(MemData->ParameterListPtr->DDR3Voltage){
497 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
498 Data8 &= ~(UINT8)BIT6;
499 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
500 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
501 Data8 |= (UINT8)BIT6;
502 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
505 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
506 Data8 &= ~(UINT8)BIT6;
507 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
508 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
509 Data8 &= ~(UINT8)BIT6;
510 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
514 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
515 Data8 |= (UINT8)BIT6;
516 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
517 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
518 Data8 &= ~(UINT8)BIT6;
519 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
524 /* Call the host environment interface to provide a user hook opportunity. */
525 AGESA_STATUS BiosHookBeforeDramInitRecovery (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
527 return AGESA_SUCCESS;
530 /* Call the host environment interface to provide a user hook opportunity. */
531 AGESA_STATUS BiosHookBeforeExitSelfRefresh (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
533 return AGESA_SUCCESS;
535 /* PCIE slot reset control */
536 AGESA_STATUS BiosGnbPcieSlotReset (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
540 PCIe_SLOT_RESET_INFO *ResetInfo;
548 ResetInfo = ConfigPtr;
549 // Get SB800 MMIO Base (AcpiMmioAddr)
550 WriteIo8(0xCD6, 0x27);
551 Data8 = ReadIo8(0xCD7);
553 WriteIo8(0xCD6, 0x26);
554 Data8 = ReadIo8(0xCD7);
556 AcpiMmioAddr = (UINT32)Data16 << 16;
557 Status = AGESA_UNSUPPORTED;
558 GpioMmioAddr = AcpiMmioAddr + GPIO_BASE;
559 switch (ResetInfo->ResetId)
562 switch (ResetInfo->ResetControl)
564 case AssertSlotReset:
565 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG21);
566 Data8 &= ~(UINT8)BIT6 ;
567 Write64Mem8(GpioMmioAddr+SB_GPIO_REG21, Data8); // MXM_GPIO0. GPIO21
568 Status = AGESA_SUCCESS;
570 case DeassertSlotReset:
571 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG21);
573 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG21, Data8); // MXM_GPIO0. GPIO21
574 Status = AGESA_SUCCESS;
579 switch (ResetInfo->ResetControl)
581 case AssertSlotReset:
582 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
583 Data8 &= ~(UINT8)BIT6 ;
584 Write64Mem8(GpioMmioAddr+SB_GPIO_REG25, Data8); // PCIE_RST#_LAN, GPIO25
585 Status = AGESA_SUCCESS;
587 case DeassertSlotReset:
588 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
590 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG25, Data8); // PCIE_RST#_LAN, GPIO25
591 Status = AGESA_SUCCESS;
596 switch (ResetInfo->ResetControl)
598 case AssertSlotReset:
599 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG02);
600 Data8 &= ~(UINT8)BIT6 ;
601 Write64Mem8(GpioMmioAddr+SB_GPIO_REG02, Data8); // MPCIE_RST0, GPIO02
602 Status = AGESA_SUCCESS;
604 case DeassertSlotReset:
605 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
607 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG02, Data8); // MPCIE_RST0, GPIO02
608 Status = AGESA_SUCCESS;