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"
22 #include "BiosCallOuts.h"
24 #include "OptionsIds.h"
25 #include "heapManager.h"
28 STATIC BIOS_CALLOUT_STRUCT BiosCallouts[REQUIRED_CALLOUTS] =
30 {AGESA_ALLOCATE_BUFFER,
34 {AGESA_DEALLOCATE_BUFFER,
50 {AGESA_READ_SPD_RECOVERY,
58 {AGESA_GET_IDS_INIT_DATA,
62 {AGESA_HOOKBEFORE_DQS_TRAINING,
63 BiosHookBeforeDQSTraining
66 {AGESA_HOOKBEFORE_DRAM_INIT,
67 BiosHookBeforeDramInit
69 {AGESA_HOOKBEFORE_EXIT_SELF_REF,
70 BiosHookBeforeExitSelfRefresh
72 {AGESA_GNB_PCIE_SLOT_RESET,
77 AGESA_STATUS GetBiosCallout (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
80 AGESA_STATUS CalloutStatus;
82 for (i = 0; i < REQUIRED_CALLOUTS; i++)
84 if (BiosCallouts[i].CalloutName == Func)
90 if(i >= REQUIRED_CALLOUTS)
92 return AGESA_UNSUPPORTED;
95 CalloutStatus = BiosCallouts[i].CalloutPtr (Func, Data, ConfigPtr);
101 CONST IDS_NV_ITEM IdsData[] =
104 AGESA_IDS_NV_MAIN_PLL_CON,
108 AGESA_IDS_NV_MAIN_PLL_FID_EN,
112 AGESA_IDS_NV_MAIN_PLL_FID,
117 AGESA_IDS_NV_CUSTOM_NB_PSTATE,
120 AGESA_IDS_NV_CUSTOM_NB_P0_DIV_CTRL,
123 AGESA_IDS_NV_CUSTOM_NB_P1_DIV_CTRL,
126 AGESA_IDS_NV_FORCE_NB_PSTATE,
135 #define NUM_IDS_ENTRIES (sizeof (IdsData) / sizeof (IDS_NV_ITEM))
138 AGESA_STATUS BiosGetIdsInitData (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
143 IdsPtr = ((IDS_CALLOUT_STRUCT *) ConfigPtr)->IdsNvPtr;
145 if (Data == IDS_CALLOUT_INIT) {
146 for (i = 0; i < NUM_IDS_ENTRIES; i++) {
147 IdsPtr[i].IdsNvValue = IdsData[i].IdsNvValue;
148 IdsPtr[i].IdsNvId = IdsData[i].IdsNvId;
151 return AGESA_SUCCESS;
155 AGESA_STATUS BiosAllocateBuffer (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
157 UINT32 AvailableHeapSize;
158 UINT8 *BiosHeapBaseAddr;
159 UINT32 CurrNodeOffset;
160 UINT32 PrevNodeOffset;
161 UINT32 FreedNodeOffset;
162 UINT32 BestFitNodeOffset;
163 UINT32 BestFitPrevNodeOffset;
164 UINT32 NextFreeOffset;
165 BIOS_BUFFER_NODE *CurrNodePtr;
166 BIOS_BUFFER_NODE *FreedNodePtr;
167 BIOS_BUFFER_NODE *BestFitNodePtr;
168 BIOS_BUFFER_NODE *BestFitPrevNodePtr;
169 BIOS_BUFFER_NODE *NextFreePtr;
170 BIOS_HEAP_MANAGER *BiosHeapBasePtr;
171 AGESA_BUFFER_PARAMS *AllocParams;
173 AllocParams = ((AGESA_BUFFER_PARAMS *) ConfigPtr);
174 AllocParams->BufferPointer = NULL;
176 AvailableHeapSize = BIOS_HEAP_SIZE - sizeof (BIOS_HEAP_MANAGER);
177 BiosHeapBaseAddr = (UINT8 *) BIOS_HEAP_START_ADDRESS;
178 BiosHeapBasePtr = (BIOS_HEAP_MANAGER *) BIOS_HEAP_START_ADDRESS;
180 if (BiosHeapBasePtr->StartOfAllocatedNodes == 0) {
181 /* First allocation */
182 CurrNodeOffset = sizeof (BIOS_HEAP_MANAGER);
183 CurrNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + CurrNodeOffset);
184 CurrNodePtr->BufferHandle = AllocParams->BufferHandle;
185 CurrNodePtr->BufferSize = AllocParams->BufferLength;
186 CurrNodePtr->NextNodeOffset = 0;
187 AllocParams->BufferPointer = (UINT8 *) CurrNodePtr + sizeof (BIOS_BUFFER_NODE);
189 /* Update the remaining free space */
190 FreedNodeOffset = CurrNodeOffset + CurrNodePtr->BufferSize + sizeof (BIOS_BUFFER_NODE);
191 FreedNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + FreedNodeOffset);
192 FreedNodePtr->BufferSize = AvailableHeapSize - sizeof (BIOS_BUFFER_NODE) - CurrNodePtr->BufferSize;
193 FreedNodePtr->NextNodeOffset = 0;
195 /* Update the offsets for Allocated and Freed nodes */
196 BiosHeapBasePtr->StartOfAllocatedNodes = CurrNodeOffset;
197 BiosHeapBasePtr->StartOfFreedNodes = FreedNodeOffset;
199 /* Find out whether BufferHandle has been allocated on the heap. */
200 /* If it has, return AGESA_BOUNDS_CHK */
201 CurrNodeOffset = BiosHeapBasePtr->StartOfAllocatedNodes;
202 CurrNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + CurrNodeOffset);
204 while (CurrNodeOffset != 0) {
205 CurrNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + CurrNodeOffset);
206 if (CurrNodePtr->BufferHandle == AllocParams->BufferHandle) {
207 return AGESA_BOUNDS_CHK;
209 CurrNodeOffset = CurrNodePtr->NextNodeOffset;
210 /* If BufferHandle has not been allocated on the heap, CurrNodePtr here points
211 to the end of the allocated nodes list.
215 /* Find the node that best fits the requested buffer size */
216 FreedNodeOffset = BiosHeapBasePtr->StartOfFreedNodes;
217 PrevNodeOffset = FreedNodeOffset;
218 BestFitNodeOffset = 0;
219 BestFitPrevNodeOffset = 0;
220 while (FreedNodeOffset != 0) {
221 FreedNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + FreedNodeOffset);
222 if (FreedNodePtr->BufferSize >= (AllocParams->BufferLength + sizeof (BIOS_BUFFER_NODE))) {
223 if (BestFitNodeOffset == 0) {
224 /* First node that fits the requested buffer size */
225 BestFitNodeOffset = FreedNodeOffset;
226 BestFitPrevNodeOffset = PrevNodeOffset;
228 /* Find out whether current node is a better fit than the previous nodes */
229 BestFitNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + BestFitNodeOffset);
230 if (BestFitNodePtr->BufferSize > FreedNodePtr->BufferSize) {
231 BestFitNodeOffset = FreedNodeOffset;
232 BestFitPrevNodeOffset = PrevNodeOffset;
236 PrevNodeOffset = FreedNodeOffset;
237 FreedNodeOffset = FreedNodePtr->NextNodeOffset;
238 } /* end of while loop */
241 if (BestFitNodeOffset == 0) {
242 /* If we could not find a node that fits the requested buffer */
243 /* size, return AGESA_BOUNDS_CHK */
244 return AGESA_BOUNDS_CHK;
246 BestFitNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + BestFitNodeOffset);
247 BestFitPrevNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + BestFitPrevNodeOffset);
249 /* If BestFitNode is larger than the requested buffer, fragment the node further */
250 if (BestFitNodePtr->BufferSize > (AllocParams->BufferLength + sizeof (BIOS_BUFFER_NODE))) {
251 NextFreeOffset = BestFitNodeOffset + AllocParams->BufferLength + sizeof (BIOS_BUFFER_NODE);
253 NextFreePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + NextFreeOffset);
254 NextFreePtr->BufferSize = BestFitNodePtr->BufferSize - (AllocParams->BufferLength + sizeof (BIOS_BUFFER_NODE));
255 NextFreePtr->NextNodeOffset = BestFitNodePtr->NextNodeOffset;
257 /* Otherwise, next free node is NextNodeOffset of BestFitNode */
258 NextFreeOffset = BestFitNodePtr->NextNodeOffset;
261 /* If BestFitNode is the first buffer in the list, then update
262 StartOfFreedNodes to reflect the new free node
264 if (BestFitNodeOffset == BiosHeapBasePtr->StartOfFreedNodes) {
265 BiosHeapBasePtr->StartOfFreedNodes = NextFreeOffset;
267 BestFitPrevNodePtr->NextNodeOffset = NextFreeOffset;
270 /* Add BestFitNode to the list of Allocated nodes */
271 CurrNodePtr->NextNodeOffset = BestFitNodeOffset;
272 BestFitNodePtr->BufferSize = AllocParams->BufferLength;
273 BestFitNodePtr->BufferHandle = AllocParams->BufferHandle;
274 BestFitNodePtr->NextNodeOffset = 0;
276 /* Remove BestFitNode from list of Freed nodes */
277 AllocParams->BufferPointer = (UINT8 *) BestFitNodePtr + sizeof (BIOS_BUFFER_NODE);
281 return AGESA_SUCCESS;
284 AGESA_STATUS BiosDeallocateBuffer (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
287 UINT8 *BiosHeapBaseAddr;
288 UINT32 AllocNodeOffset;
289 UINT32 PrevNodeOffset;
290 UINT32 NextNodeOffset;
291 UINT32 FreedNodeOffset;
292 UINT32 EndNodeOffset;
293 BIOS_BUFFER_NODE *AllocNodePtr;
294 BIOS_BUFFER_NODE *PrevNodePtr;
295 BIOS_BUFFER_NODE *FreedNodePtr;
296 BIOS_BUFFER_NODE *NextNodePtr;
297 BIOS_HEAP_MANAGER *BiosHeapBasePtr;
298 AGESA_BUFFER_PARAMS *AllocParams;
300 BiosHeapBaseAddr = (UINT8 *) BIOS_HEAP_START_ADDRESS;
301 BiosHeapBasePtr = (BIOS_HEAP_MANAGER *) BIOS_HEAP_START_ADDRESS;
303 AllocParams = (AGESA_BUFFER_PARAMS *) ConfigPtr;
305 /* Find target node to deallocate in list of allocated nodes.
306 Return AGESA_BOUNDS_CHK if the BufferHandle is not found
308 AllocNodeOffset = BiosHeapBasePtr->StartOfAllocatedNodes;
309 AllocNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + AllocNodeOffset);
310 PrevNodeOffset = AllocNodeOffset;
312 while (AllocNodePtr->BufferHandle != AllocParams->BufferHandle) {
313 if (AllocNodePtr->NextNodeOffset == 0) {
314 return AGESA_BOUNDS_CHK;
316 PrevNodeOffset = AllocNodeOffset;
317 AllocNodeOffset = AllocNodePtr->NextNodeOffset;
318 AllocNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + AllocNodeOffset);
321 /* Remove target node from list of allocated nodes */
322 PrevNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + PrevNodeOffset);
323 PrevNodePtr->NextNodeOffset = AllocNodePtr->NextNodeOffset;
325 /* Zero out the buffer, and clear the BufferHandle */
326 LibAmdMemFill ((UINT8 *)AllocNodePtr + sizeof (BIOS_BUFFER_NODE), 0, AllocNodePtr->BufferSize, &(AllocParams->StdHeader));
327 AllocNodePtr->BufferHandle = 0;
328 AllocNodePtr->BufferSize += sizeof (BIOS_BUFFER_NODE);
330 /* Add deallocated node in order to the list of freed nodes */
331 FreedNodeOffset = BiosHeapBasePtr->StartOfFreedNodes;
332 FreedNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + FreedNodeOffset);
334 EndNodeOffset = AllocNodeOffset + AllocNodePtr->BufferSize;
336 if (AllocNodeOffset < FreedNodeOffset) {
337 /* Add to the start of the freed list */
338 if (EndNodeOffset == FreedNodeOffset) {
339 /* If the freed node is adjacent to the first node in the list, concatenate both nodes */
340 AllocNodePtr->BufferSize += FreedNodePtr->BufferSize;
341 AllocNodePtr->NextNodeOffset = FreedNodePtr->NextNodeOffset;
343 /* Clear the BufferSize and NextNodeOffset of the previous first node */
344 FreedNodePtr->BufferSize = 0;
345 FreedNodePtr->NextNodeOffset = 0;
348 /* Otherwise, add freed node to the start of the list
349 Update NextNodeOffset and BufferSize to include the
350 size of BIOS_BUFFER_NODE
352 AllocNodePtr->NextNodeOffset = FreedNodeOffset;
354 /* Update StartOfFreedNodes to the new first node */
355 BiosHeapBasePtr->StartOfFreedNodes = AllocNodeOffset;
357 /* Traverse list of freed nodes to find where the deallocated node
360 NextNodeOffset = FreedNodeOffset;
361 NextNodePtr = FreedNodePtr;
362 while (AllocNodeOffset > NextNodeOffset) {
363 PrevNodeOffset = NextNodeOffset;
364 if (NextNodePtr->NextNodeOffset == 0) {
367 NextNodeOffset = NextNodePtr->NextNodeOffset;
368 NextNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + NextNodeOffset);
371 /* If deallocated node is adjacent to the next node,
372 concatenate both nodes
374 if (NextNodeOffset == EndNodeOffset) {
375 NextNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + NextNodeOffset);
376 AllocNodePtr->BufferSize += NextNodePtr->BufferSize;
377 AllocNodePtr->NextNodeOffset = NextNodePtr->NextNodeOffset;
379 NextNodePtr->BufferSize = 0;
380 NextNodePtr->NextNodeOffset = 0;
382 /*AllocNodePtr->NextNodeOffset = FreedNodePtr->NextNodeOffset; */
383 AllocNodePtr->NextNodeOffset = NextNodeOffset;
385 /* If deallocated node is adjacent to the previous node,
386 concatenate both nodes
388 PrevNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + PrevNodeOffset);
389 EndNodeOffset = PrevNodeOffset + PrevNodePtr->BufferSize;
390 if (AllocNodeOffset == EndNodeOffset) {
391 PrevNodePtr->NextNodeOffset = AllocNodePtr->NextNodeOffset;
392 PrevNodePtr->BufferSize += AllocNodePtr->BufferSize;
394 AllocNodePtr->BufferSize = 0;
395 AllocNodePtr->NextNodeOffset = 0;
397 PrevNodePtr->NextNodeOffset = AllocNodeOffset;
400 return AGESA_SUCCESS;
403 AGESA_STATUS BiosLocateBuffer (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
405 UINT32 AllocNodeOffset;
406 UINT8 *BiosHeapBaseAddr;
407 BIOS_BUFFER_NODE *AllocNodePtr;
408 BIOS_HEAP_MANAGER *BiosHeapBasePtr;
409 AGESA_BUFFER_PARAMS *AllocParams;
411 AllocParams = (AGESA_BUFFER_PARAMS *) ConfigPtr;
413 BiosHeapBaseAddr = (UINT8 *) BIOS_HEAP_START_ADDRESS;
414 BiosHeapBasePtr = (BIOS_HEAP_MANAGER *) BIOS_HEAP_START_ADDRESS;
416 AllocNodeOffset = BiosHeapBasePtr->StartOfAllocatedNodes;
417 AllocNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + AllocNodeOffset);
419 while (AllocParams->BufferHandle != AllocNodePtr->BufferHandle) {
420 if (AllocNodePtr->NextNodeOffset == 0) {
421 AllocParams->BufferPointer = NULL;
422 AllocParams->BufferLength = 0;
423 return AGESA_BOUNDS_CHK;
425 AllocNodeOffset = AllocNodePtr->NextNodeOffset;
426 AllocNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + AllocNodeOffset);
430 AllocParams->BufferPointer = (UINT8 *) ((UINT8 *) AllocNodePtr + sizeof (BIOS_BUFFER_NODE));
431 AllocParams->BufferLength = AllocNodePtr->BufferSize;
433 return AGESA_SUCCESS;
437 AGESA_STATUS BiosRunFuncOnAp (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
441 Status = agesawrapper_amdlaterunaptask (Data, ConfigPtr);
445 AGESA_STATUS BiosReset (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
450 AMD_CONFIG_PARAMS *StdHeader;
453 StdHeader = ConfigPtr;
456 // Perform the RESET based upon the ResetType. In case of
457 // WARM_RESET_WHENVER and COLD_RESET_WHENEVER, the request will go to
458 // AmdResetManager. During the critical condition, where reset is required
459 // immediately, the reset will be invoked directly by writing 0x04 to port
460 // 0xCF9 (Reset Port).
463 case WARM_RESET_WHENEVER:
464 case COLD_RESET_WHENEVER:
467 case WARM_RESET_IMMEDIATELY:
468 case COLD_RESET_IMMEDIATELY:
470 LibAmdIoWrite (AccessWidth8, 0xCf9, &Value, StdHeader);
481 AGESA_STATUS BiosReadSpd (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
484 Status = AmdMemoryReadSPD (Func, Data, ConfigPtr);
489 AGESA_STATUS BiosDefaultRet (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
491 return AGESA_UNSUPPORTED;
493 /* Call the host environment interface to provide a user hook opportunity. */
494 AGESA_STATUS BiosHookBeforeDQSTraining (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
496 return AGESA_SUCCESS;
498 /* Call the host environment interface to provide a user hook opportunity. */
499 AGESA_STATUS BiosHookBeforeDramInit (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
503 MEM_DATA_STRUCT *MemData;
513 Status = AGESA_SUCCESS;
514 /* Get SB800 MMIO Base (AcpiMmioAddr) */
515 WriteIo8 (0xCD6, 0x27);
516 Data8 = ReadIo8(0xCD7);
518 WriteIo8 (0xCD6, 0x26);
519 Data8 = ReadIo8(0xCD7);
521 AcpiMmioAddr = (UINT32)Data16 << 16;
522 GpioMmioAddr = AcpiMmioAddr + GPIO_BASE;
524 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG178);
526 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
529 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, TempData8);
533 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
536 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, TempData8);
537 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG179);
539 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
542 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, TempData8);
545 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
548 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, TempData8);
550 switch(MemData->ParameterListPtr->DDR3Voltage){
552 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
553 Data8 &= ~(UINT8)BIT6;
554 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
555 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
556 Data8 |= (UINT8)BIT6;
557 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
560 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
561 Data8 &= ~(UINT8)BIT6;
562 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
563 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
564 Data8 &= ~(UINT8)BIT6;
565 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
569 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
570 Data8 |= (UINT8)BIT6;
571 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
572 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
573 Data8 &= ~(UINT8)BIT6;
574 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
578 /* Call the host environment interface to provide a user hook opportunity. */
579 AGESA_STATUS BiosHookBeforeExitSelfRefresh (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
581 return AGESA_SUCCESS;
583 /* PCIE slot reset control */
584 AGESA_STATUS BiosGnbPcieSlotReset (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
588 PCIe_SLOT_RESET_INFO *ResetInfo;
596 ResetInfo = ConfigPtr;
597 // Get SB800 MMIO Base (AcpiMmioAddr)
598 WriteIo8(0xCD6, 0x27);
599 Data8 = ReadIo8(0xCD7);
601 WriteIo8(0xCD6, 0x26);
602 Data8 = ReadIo8(0xCD7);
604 AcpiMmioAddr = (UINT32)Data16 << 16;
605 Status = AGESA_UNSUPPORTED;
606 GpioMmioAddr = AcpiMmioAddr + GPIO_BASE;
607 switch (ResetInfo->ResetId)
610 switch (ResetInfo->ResetControl)
612 case AssertSlotReset:
613 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG21);
614 Data8 &= ~(UINT8)BIT6 ;
615 Write64Mem8(GpioMmioAddr+SB_GPIO_REG21, Data8); // MXM_GPIO0. GPIO21
616 Status = AGESA_SUCCESS;
618 case DeassertSlotReset:
619 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG21);
621 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG21, Data8); // MXM_GPIO0. GPIO21
622 Status = AGESA_SUCCESS;
627 switch (ResetInfo->ResetControl)
629 case AssertSlotReset:
630 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
631 Data8 &= ~(UINT8)BIT6 ;
632 Write64Mem8(GpioMmioAddr+SB_GPIO_REG25, Data8); // PCIE_RST#_LAN, GPIO25
633 Status = AGESA_SUCCESS;
635 case DeassertSlotReset:
636 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
638 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG25, Data8); // PCIE_RST#_LAN, GPIO25
639 Status = AGESA_SUCCESS;
644 switch (ResetInfo->ResetControl)
646 case AssertSlotReset:
647 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG02);
648 Data8 &= ~(UINT8)BIT6 ;
649 Write64Mem8(GpioMmioAddr+SB_GPIO_REG02, Data8); // MPCIE_RST0, GPIO02
650 Status = AGESA_SUCCESS;
652 case DeassertSlotReset:
653 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
655 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG02, Data8); // MPCIE_RST0, GPIO02
656 Status = AGESA_SUCCESS;