diff options
Diffstat (limited to 'src/vendorcode/amd/agesa/f12/Legacy/Proc/arch2008.asm')
-rwxr-xr-x | src/vendorcode/amd/agesa/f12/Legacy/Proc/arch2008.asm | 2674 |
1 files changed, 2674 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f12/Legacy/Proc/arch2008.asm b/src/vendorcode/amd/agesa/f12/Legacy/Proc/arch2008.asm new file mode 100755 index 0000000000..1c56b86d76 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Legacy/Proc/arch2008.asm @@ -0,0 +1,2674 @@ +;***************************************************************************** +; AMD Generic Encapsulated Software Architecture +; +; Workfile: arch2008.asm $Revision: 44324 $ $Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 2010) $ +; +; Description: ARCH2008.ASM - AGESA Architecture 2008 Wrapper Template +; +;***************************************************************************** +; +; Copyright (c) 2011, Advanced Micro Devices, Inc. +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of Advanced Micro Devices, Inc. nor the names of +; its contributors may be used to endorse or promote products derived +; from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;***************************************************************************** + + .XLIST + INCLUDE agesa.inc + INCLUDE acwrapg.inc ; Necessary support file as part of wrapper, including but not limited to segment start/end macros. + INCLUDE acwrap.inc ; IBVs may specify host BIOS-specific include files required when building. + INCLUDE cpcarmac.inc + INCLUDE bridge32.inc + .LIST + .586p + .mmx + + +;---------------------------------------------------------------------------- +; Local definitions +;---------------------------------------------------------------------------- + +sOemCallout STRUCT + FuncName DD ? ; Call out function name + FuncPtr DW ? ; Call out function pointer +sOemCallout ENDS + +sOemEventHandler STRUCT + ClassCode DD ? ; AGESA event log sub-class code + FuncPtr DW ? ; Event handler function pointer +sOemEventHandler ENDS + +;; A typical legacy BIOS implementation may require the E000 and F000 segments +;; to be cached. +EXE_CACHE_REGION_BASE_0 EQU 0E0000h +EXE_CACHE_REGION_SIZE_0 EQU 20000h + +;; In this sample implementation, the B1 and B2 images are placed next to each +;; other in the BIOS ROM to help with the maximization of cached code. +EXE_CACHE_REGION_BASE_1 EQU AGESA_B1_ADDRESS +EXE_CACHE_REGION_SIZE_1 EQU 40000h + +;; The third region is not needed in our example. +EXE_CACHE_REGION_BASE_2 EQU 0 +EXE_CACHE_REGION_SIZE_2 EQU 0 + + +;---------------------------------------------------------------------------- +; PERSISTENT SEGMENT +; This segment is required to be present throughout all BIOS execution. +;---------------------------------------------------------------------------- + +AMD_PERSISTENT_START + + +;---------------------------------------------------------------------------- +; Instantiate the global descriptor table +;---------------------------------------------------------------------------- + +AMD_BRIDGE_32_GDT AMD_GDT ; Instantiate the global descriptor table + ; required by the push-high mechanism. + + +;---------------------------------------------------------------------------- +; Declare the external routines required in the persistent segment +;---------------------------------------------------------------------------- + +;+------------------------------------------------------------------------- +; +; AmdDfltRet +; +; Entry: +; None +; +; Exit: +; None +; +; Modified: +; None +; +; Purpose: +; Near stub procedure. Simply perform a retn instruction. +; +EXTERN AmdDfltRet:NEAR + + +;+------------------------------------------------------------------------- +; +; AmdDfltRetFar +; +; Entry: +; None +; +; Exit: +; None +; +; Modified: +; None +; +; Purpose: +; Far stub procedure. Simply perform a retf instruction. +; +EXTERN AmdDfltRetFar:FAR + + +;---------------------------------------------------------------------------- +; Declare the optional external routines in the persistent segment +;---------------------------------------------------------------------------- + +;+--------------------------------------------------------------------------- +; +; myModuleTypeMismatchHandler (Example) +; +; Entry: +; ESI - Pointer to the EVENT_PARAMS structure of the failure. +; [ESI].DataParam1 - Socket +; [ESI].DataParam2 - DCT +; [ESI].DataParam3 - Channel +; [ESI].DataParam4 - 0x00000000 +; +; Exit: +; None +; +; Modified: +; None +; +; Purpose: +; This procedure can be used to react to a memory module type +; mismatch error discovered by the AGESA code. Actions taken +; may include, but are not limited to: +; Logging the event to NV for display later +; Reset, excluding the mismatch on subsequent reboot +; Do nothing +; +; Dependencies: +; None +; +EXTERN myModuleTypeMismatchHandler(AmdDfltRet):NEAR + +;+--------------------------------------------------------------------------- +; +; oemPlatformConfigInit (Optional) +; +; Entry: +; EDI - 32-bit flat pointer to the PLATFORM_CONFIGURATION to be +; passed in to the next AGESA entry point. +; +; typedef struct { +; IN PERFORMANCE_PROFILE PlatformProfile; +; IN CPU_HT_DEEMPHASIS_LEVEL *PlatformDeemphasisList; +; IN UINT8 CoreLevelingMode; +; IN PLATFORM_C1E_MODES C1eMode; +; IN UINT32 C1ePlatformData; +; IN UINT32 C1ePlatformData1; +; IN UINT32 C1ePlatformData2; +; IN UINT32 C1ePlatformData3; +; IN BOOLEAN UserOptionDmi; +; IN BOOLEAN UserOptionPState; +; IN BOOLEAN UserOptionSrat; +; IN BOOLEAN UserOptionSlit; +; IN BOOLEAN UserOptionWhea; +; IN UINT32 PowerCeiling; +; IN BOOLEAN PstateIndependent; +; } PLATFORM_CONFIGURATION; +; +; typedef struct { +; IN UINT8 Socket; +; IN UINT8 Link; +; IN UINT8 LoFreq; +; IN UINT8 HighFreq; +; IN PLATFORM_DEEMPHASIS_LEVEL ReceiverDeemphasis; +; IN PLATFORM_DEEMPHASIS_LEVEL DcvDeemphasis; +; } CPU_HT_DEEMPHASIS_LEVEL; +; +; typedef struct { +; IN PLATFORM_CONTROL_FLOW PlatformControlFlowMode; +; IN BOOLEAN UseHtAssist; +; IN BOOLEAN UseAtmMode; +; IN BOOLEAN Use32ByteRefresh; +; IN BOOLEAN UseVariableMctIsocPriority; +; } PERFORMANCE_PROFILE; +; +; Exit: +; None +; +; Modified: +; None +; +; Purpose: +; Provide a single hook routine to modify the parameters of a +; PLATFORM_CONFIGURATION structure before any entry point that +; has such a structure as an input. +; +; Dependencies: +; None +; +; Example: +; If your platform is running in UMA mode, the following code +; may be added: +; mov (PLATFORM_CONFIGURATION PTR [edi]).PlatformProfile.PlatformControlFlowMode, UmaDr +; +EXTERN oemPlatformConfigInit(AmdDfltRetFar):FAR + +;+--------------------------------------------------------------------------- +; +; oemCallout (Optional) +; +; Entry: +; ECX - Callout function number +; EDX - Function-specific UINTN +; ESI - Pointer to function specific data +; +; Exit: +; EAX - Contains the AGESA_STATUS return code. +; +; Modified: +; None +; +; Purpose: +; The default call out router function which resides in the same +; segment as the push-high bridge code. +; +; Dependencies: +; None +; +EXTERN oemCallout(AmdDfltRet):NEAR + + +;---------------------------------------------------------------------------- +; Define the sample wrapper routines for the persistent segment +;---------------------------------------------------------------------------- + +;+--------------------------------------------------------------------------- +; +; AmdBridge32 +; +; Entry: +; EDX - A Real Mode FAR pointer using seg16:Offset16 format that +; points to a local host environment call-out router. If +; this pointer is not equal to zero, then this pointer is +; used as the call-out router instead of the standard +; OemCallout. This may be useful when the call-out router +; is not located in the same segment as the AmdBridge32 and +; AmdCallout16 routines. +; ESI - A Flat Mode pointer (32-bit address) that points to the +; configuration block (AMD_CONFIG_PARAMS) for the AGESA +; software function. +; +; Exit: +; EAX - Contains the AGESA_STATUS return code. +; +; Modified: +; None +; +; Purpose: +; Execute an AGESA software function through the Push-High interface. +; +; Dependencies: +; This procedure requires a stack. The host environment must use the +; provided service function to establish the stack environment prior +; to making the call to this procedure. +; +AmdBridge32 PROC FAR PUBLIC + AMD_BRIDGE_32 AMD_GDT ; use the macro for the body + ret +AmdBridge32 ENDP + + +;+--------------------------------------------------------------------------- +; +; AmdEnableStack +; +; Entry: +; BX - Return address +; +; Exit: +; EAX - Contains the AGESA_STATUS return code. +; SS:ESP - Points to the private stack location for this processor core. +; ECX - Upon success, contains this processor core's stack size in bytes. +; +; Modified: +; EAX, ECX, EDX, EDI, ESI, ESP, DS, ES +; +; Purpose: +; This procedure is used to establish the stack within the host environment. +; +; Dependencies: +; The host environment must use this procedure and not rely on any other +; sources to create the stack region. +; +AmdEnableStack PROC NEAR PUBLIC + AMD_ENABLE_STACK + ;; EAX = AGESA_SUCCESS, The stack space has been allocated for this core. + ;; EAX = AGESA_WARNING, The stack has already been set up. SS:ESP is set + ;; to stack top, and ECX is the stack size in bytes. + jmp bx +AmdEnableStack ENDP + + +;+--------------------------------------------------------------------------- +; +; AmdDisableStack +; +; Entry: +; BX - Return address +; +; Exit: +; EAX - Contains the AGESA_STATUS return code. +; +; Modified: +; EAX, ECX, EDX, ESI, ESP +; +; Purpose: +; This procedure is used to remove the pre-memory stack from within the +; host environment. +; The exit state for the BSP is described as follows: +; Memory region 00000-9FFFF MTRRS are set as WB memory. +; Processor Cache is enabled (CD bit is cleared). +; MTRRs used for execution cache are kept. +; Cache content is flushed (invalidated without write-back). +; Any family-specific clean-up done. +; The exit state for the APs is described as follows: +; Memory region 00000-9FFFF MTRRS are set as WB memory. +; Memory region A0000-DFFFF MTRRS are set as UC IO. +; Memory region E0000-FFFFF MTRRS are set as UC memory. +; MTRRs used for execution cache are cleared. +; Processor Cache is disabled (CD bit is set). +; Top-of-Memory (TOM) set to the system top of memory as determined +; by the memory initialization routines. +; System lock command is enabled. +; Any family-specific clean-up done. +; +; Dependencies: +; The host environment must use this procedure and not rely on any other +; sources to break down the stack region. +; If executing in 16-bit code, the host environment must establish the +; "Big Real" mode of 32-bit addressing of data. +; +AmdDisableStack PROC NEAR PUBLIC + AMD_DISABLE_STACK + ;; EAX = AGESA_SUCCESS, The stack space has been disabled for this core. + jmp bx +AmdDisableStack ENDP + + +;+--------------------------------------------------------------------------- +; +; AmdCallout16 +; +; Entry: +; [esp+8] - Func +; [esp+12] - Data +; [esp+16] - Configuration Block +; [esp+4] - Return address to AGESA +; +; Exit: +; EAX - Contains the AGESA_STATUS return code. +; +; Modified: +; None +; +; Purpose: +; Execute callback from the push-high interface. +; +; Dependencies: +; None +; +AmdCallout16 PROC FAR PUBLIC ; declare the procedure + AMD_CALLOUT_16 oemCallout ; use the macro for the body + ret +AmdCallout16 ENDP + + +;+--------------------------------------------------------------------------- +; +; AmdProcessAgesaErrors (Optional) +; +; Entry: +; AL - Heap status of the AGESA entry point that was just invoked. +; EBX - AGESA image base address. +; EDX - Segment / Offset of the appropriate callout router function. +; +; Exit: +; None +; +; Modified: +; None +; +; Purpose: +; This procedure is used to handle any errors that may have occurred +; during an AGESA entry point. +; +; Dependencies: +; None +; +AmdProcessAgesaErrors PROC FAR PUBLIC + LOCAL localCpuInterfaceBlock:EVENT_PARAMS + + pushad + xor edi, edi + mov di, ss + shl edi, 4 + lea esi, localCpuInterfaceBlock + add esi, edi + + ; Fill default config block + mov (EVENT_PARAMS PTR [esi]).StdHeader.Func, AMD_READ_EVENT_LOG + mov (EVENT_PARAMS PTR [esi]).StdHeader.ImageBasePtr, ebx + mov (EVENT_PARAMS PTR [esi]).StdHeader.AltImageBasePtr, 0 + mov (EVENT_PARAMS PTR [esi]).StdHeader.HeapStatus, al + mov edi, SEG AmdCallout16 + shl edi, 4 + add edi, OFFSET AmdCallout16 + mov (EVENT_PARAMS PTR [esi]).StdHeader.CalloutPtr, edi + + ; Flush the event log searching for, and handling all monitored events + xor eax, eax + .while (eax == 0) + push edx + call AmdBridge32 + pop edx + .if (eax == AGESA_SUCCESS) + mov eax, (EVENT_PARAMS PTR [esi]).EventInfo + .if (eax != 0) + lea di, cs:AgesaEventTable + +loopThruTable: + cmp di, OFFSET cs:AgesaEventTableEnd + jae unhandledEvent + + cmp eax, cs:[di].sOemEventHandler.ClassCode + je FoundMatch + add di, SIZEOF sOemEventHandler + jmp loopThruTable + +FoundMatch: + mov bx, cs:[di].sOemEventHandler.FuncPtr + call bx + +unhandledEvent: + xor eax, eax + .else + mov al, 1 + .endif + .endif + .endw + popad + ret + +AmdProcessAgesaErrors ENDP + + +;---------------------------------------------------------------------------- +; Define the error handler table +;---------------------------------------------------------------------------- + +AgesaEventTable LABEL BYTE + ;; Add entries as desired + ;;--------- + ;; EXAMPLE + ;;--------- + sOemEventHandler <MEM_ERROR_MODULE_TYPE_MISMATCH_DIMM, OFFSET myModuleTypeMismatchHandler> +AgesaEventTableEnd LABEL BYTE + + +AMD_PERSISTENT_END + + + + +;---------------------------------------------------------------------------- +; RECOVERY SEGMENT +; This segment resides in the classic 'boot-block,' and is used +; for recovery. +;---------------------------------------------------------------------------- + +AMD_RECOVERY_START + + +;---------------------------------------------------------------------------- +; Declare the external routines required in the recovery segment +;---------------------------------------------------------------------------- + +;+--------------------------------------------------------------------------- +; +; myReadSPDRecovery (Required for proper recovery mode operation) +; +; Entry: +; ESI - Pointer to an AGESA_READ_SPD_PARAMS structure. +; +; typedef struct { +; IN OUT AMD_CONFIG_PARAMS StdHeader; +; IN UINT8 SocketId; +; IN UINT8 MemChannelId; +; IN UINT8 DimmId; +; IN OUT UINT8 *Buffer; +; IN OUT MEM_DATA_STRUCT *MemData; +; } AGESA_READ_SPD_PARAMS; +; +; Exit: +; EAX - Contains the AGESA_STATUS return code. +; AGESA_SUCCESS Indicates the SPD block for the indicated +; DIMM was read successfully. +; AGESA_BOUNDS_CHK The specified DIMM is not present. +; AGESA_UNSUPPORTED This is a required function, so this +; value being returned causes a critical +; error response value from the AGESA +; software function and no memory initialized. +; AGESA_ERROR The DIMM SPD read process has generated +; communication errors. +; +; Modified: +; None +; +; Purpose: +; This call out reads a block of memory SPD data and places it +; into the provided buffer. +; +; Dependencies: +; None +; +EXTERN myReadSPDRecovery:NEAR + + +;---------------------------------------------------------------------------- +; Define the sample wrapper routines for the recovery segment +;---------------------------------------------------------------------------- + +;+--------------------------------------------------------------------------- +; +; AmdInitResetWrapper +; +; Entry: +; DS - 0000 with 4 gigabyte access +; ES - 0000 with 4 gigabyte access +; +; Exit: +; None +; +; Modified: +; None +; +; Purpose: +; A minimal initialization of the processor core is performed. This +; procedure must be called by all processor cores. The code path +; separates the BSP from the APs and performs a separate and appropriate +; list of tasks for each class of core. +; For the BSP, the following actions are performed: +; Internal heap sub-system initialization +; Primary non-coherent HyperTransportT link initialization +; Return to the host environment to test for Recovery Mode. +; The AP processor cores do not participate in the recovery process. +; However, they execute this routine after being released to execute +; by the BSP during the main boot process. Their actions include the +; following: +; Internal heap sub-system initialization +; Proceed to a wait loop waiting for commands from the BSP +; +; For the cache regions, up to three regions of execution cache can be +; allocated following the following rules: +; 1. Once a region is allocated, it cannot be de-allocated. However, it +; can be expanded. +; 2. At most, two of the three regions can be located above 1 MByte. A +; region failing this rule is ignored. +; 3. All region addresses must be at or above the 0x000D0000 linear +; address. A region failing this rule is ignored. +; 4. The address is aligned on a 32-KByte boundary. Starting addresses +; is rounded down to the nearest 32-Kbyte boundary. +; 5. The execution cache size must be a multiple of 32 KByte. Size is +; rounded up to the next multiple of 32 KByte. +; 6. A region must not span either the 1-MByte boundary or the 4-GByte +; boundary. Allocated size is truncated to not span the boundary. +; 7. The granted cached execution regions, address, and size are calculated +; based on the available cache resources of the processor core. +; Allocations are made up to the limit of cache available on the +; installed processor. +; Warning: Enabling instruction cache outside of this interface can cause +; data corruption. +; +; Dependencies: +; This procedure is expected to be executed soon after a system reset +; for the main boot path or resume path of execution. +; +; This procedure requires a stack. +; +; Because the heap system is not yet operational at the point of the +; interface call, the host environment must allocate the storage for +; the AMD_RESET_PARAMS structure before making the first call to +; AmdCreateStruct. This is the ByHost method of allocation. +; +AmdInitResetWrapper PROC NEAR PUBLIC + local localCfgBlock:AMD_INTERFACE_PARAMS + local localResetParams:AMD_RESET_PARAMS + + pushad + + ; Prepare for the call to initialize the input parameters for AmdInitReset + xor eax, eax + mov ax, ss + shl eax, 4 + lea esi, localCfgBlock + add esi, eax + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B1_ADDRESS + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0 + mov edx, SEG AmdCallout16 + shl edx, 4 + add edx, OFFSET AmdCallout16 + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx + + ; Use the 'ByHost' allocation method because the heap has not been initialized as of yet. + mov (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_INIT_RESET + mov (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, ByHost + mov (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, sizeof AMD_RESET_PARAMS + lea edx, localResetParams + add edx, eax + push edx + mov (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr, edx + mov dx, SEG AmdCalloutRouterRecovery + shl edx, 16 + mov dx, OFFSET AmdCalloutRouterRecovery + push edx + call AmdBridge32 + pop edx + pop esi + + ; The structure has been initialized. Now modify the default settings as desired. + + ; Allocate the execution cache to maximize the amount of code in ROM that is cached. + ; Placing the B1 and B2 images near one another is a good way to ensure the AGESA code + ; is cached. + mov (AMD_RESET_PARAMS ptr [esi]).CacheRegion.ExeCacheStartAddr, EXE_CACHE_REGION_BASE_0 + mov (AMD_RESET_PARAMS ptr [esi]).CacheRegion.ExeCacheSize, EXE_CACHE_REGION_SIZE_0 + mov (AMD_RESET_PARAMS ptr [esi + sizeof EXECUTION_CACHE_REGION]).CacheRegion.ExeCacheStartAddr, EXE_CACHE_REGION_BASE_1 + mov (AMD_RESET_PARAMS ptr [esi + sizeof EXECUTION_CACHE_REGION]).CacheRegion.ExeCacheSize, EXE_CACHE_REGION_SIZE_1 + mov (AMD_RESET_PARAMS ptr [esi + (2 * sizeof EXECUTION_CACHE_REGION)]).CacheRegion.ExeCacheStartAddr, EXE_CACHE_REGION_BASE_2 + mov (AMD_RESET_PARAMS ptr [esi + (2 * sizeof EXECUTION_CACHE_REGION)]).CacheRegion.ExeCacheSize, EXE_CACHE_REGION_SIZE_2 + + ; Call in to the AmdInitReset entry point + push edx + call AmdBridge32 + pop edx + + ;; EAX = AGESA_STATUS + ;; AGESA_SUCCESS Early initialization completed successfully. + ;; AGESA_WARNING One or more of the execution cache allocation + ;; rules were violated, but an adjustment was made + ;; and space was allocated. + ;; AGESA_ERROR One or more of the execution cache allocation rules + ;; were violated, which resulted in a requested cache + ;; region to not be allocated. + ;; The storage space allocated for the AMD_RESET_PARAMS + ;; structure is insufficient. + + .if (eax != AGESA_SUCCESS) + mov al, (AMD_RESET_PARAMS ptr [esi]).StdHeader.HeapStatus + mov ebx, AGESA_B1_ADDRESS + call AmdProcessAgesaErrors + .endif + + + ;; Here are what the MTRRs should look like based off of the CacheRegions specified above: + + ;; Fixed-Range MTRRs + ;; Name Address Value + ;; ---------------- -------- ---------------- + ;; MTRRfix4k_E0000 0000026C 0505050505050505 + ;; MTRRfix4k_E8000 0000026D 0505050505050505 + ;; MTRRfix4k_F0000 0000026E 0505050505050505 + ;; MTRRfix4k_F8000 0000026F 0505050505050505 + ;; MTRRdefType 000002FF 0000000000000C00 + ;; + ;; Variable-Range MTRRs and IO Range + ;; MTRRphysBase(n) MTRRphysMask(n) + ;; ----------------- ----------------- + ;; n=0 0000000000000000 0000000000000000 + ;; n=1 0000000000000000 0000000000000000 + ;; n=2 0000000000000000 0000000000000000 + ;; n=3 0000000000000000 0000000000000000 + ;; n=4 0000000000000000 0000000000000000 + ;; n=5 Heap Base (Varies by core) 0000FFFFFFFF0800 + ;; n=6 AGESA_B1_ADDRESS | 6 0000FFFFFFFC0800 + ;; n=7 0000000000000000 0000000000000000 + + + ;; Because the allocation method is 'ByHost,' the call to AMD_RELEASE_STRUCT is + ;; not necessary. Stack space reclamation is left up to the host BIOS. + + popad + ret + + +AmdInitResetWrapper ENDP + + +;+--------------------------------------------------------------------------- +; +; AmdInitRecoveryWrapper +; +; Entry: +; DS - 0000 with 4 gigabyte access +; ES - 0000 with 4 gigabyte access +; +; Exit: +; None +; +; Modified: +; None +; +; Purpose: +; Perform a minimum initialization of the processor and memory to +; support a recovery mode flash ROM update. +; For the BSP, the following actions are performed: +; Configuration of CPU core for recovery process +; Minimal initialization of some memory +; The AP processor cores do not participate in the recovery process. +; No actions or tasks are performed by the AP cores for this time point. +; +; Dependencies: +; This procedure requires a stack. The host environment must use one of +; the provided service functions to establish the stack environment prior +; to making the call to this procedure. +; +AmdInitRecoveryWrapper PROC NEAR PUBLIC + local localCfgBlock:AMD_INTERFACE_PARAMS + + pushad + + ; Prepare for the call to create and initialize the input parameters for AmdInitRecovery + xor eax, eax + mov ax, ss + shl eax, 4 + lea esi, localCfgBlock + add esi, eax + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B1_ADDRESS + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0 + mov edx, SEG AmdCallout16 + shl edx, 4 + add edx, OFFSET AmdCallout16 + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx + + mov (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_INIT_RECOVERY + mov (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PreMemHeap + mov (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0 + push esi + mov dx, SEG AmdCalloutRouterRecovery + shl edx, 16 + mov dx, OFFSET AmdCalloutRouterRecovery + push edx + call AmdBridge32 + pop edx + + mov esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr + + ; The structure has been initialized. Now modify the default settings as desired. + + + ; Call in to the AmdInitRecovery entry point + push edx + call AmdBridge32 + pop edx + + ;; EAX = AGESA_STATUS + ;; AGESA_SUCCESS The function has completed successfully. + ;; AGESA_WARNING One or more of the allocation rules were violated, + ;; but an adjustment was made and space was allocated. + ;; AGESA_ERROR One or more of the allocation rules were violated, + ;; which resulted in a requested cache region to not be + ;; allocated. + ;; AGESA_FATAL No memory was found in the system. + + .if (eax != AGESA_SUCCESS) + mov al, (AMD_RECOVERY_PARAMS ptr [esi]).StdHeader.HeapStatus + mov ebx, AGESA_B1_ADDRESS + call AmdProcessAgesaErrors + .endif + + ; Allow AGESA to free the space used by AmdInitRecovery + pop esi + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT + call AmdBridge32 + + popad + ret +AmdInitRecoveryWrapper ENDP + + +;+--------------------------------------------------------------------------- +; +; AmdCalloutRouterRecovery +; +; Entry: +; ECX - Callout function number +; EDX - Function-specific UINTN +; ESI - Pointer to function specific data +; +; Exit: +; EAX - Contains the AGESA_STATUS return code. +; +; Modified: +; None +; +; Purpose: +; The call out router function for AmdInitReset and +; AmdInitRecovery. +; +; Dependencies: +; None +; +AmdCalloutRouterRecovery PROC FAR PUBLIC USES ECX EBX ESI BX DI DS ES + xor ax, ax + mov ds, ax + mov es, ax + lea di, cs:CalloutRouterTableRecovery + mov eax, AGESA_UNSUPPORTED + +loopThruTable: + cmp di, OFFSET cs:CalloutRouterTableRecoveryEnd + jae amdCpuCalloutExit ; exit with AGESA_UNSUPPORTED + cmp ecx, cs:[di].sOemCallout.FuncName + je FoundMatch + add di, SIZEOF sOemCallout + jmp loopThruTable + +FoundMatch: + mov bx, cs:[di].sOemCallout.FuncPtr + call bx + +amdCpuCalloutExit: + ret +AmdCalloutRouterRecovery ENDP + + +;---------------------------------------------------------------------------- +; Define the callout dispatch table for the recovery segment +;---------------------------------------------------------------------------- + +CalloutRouterTableRecovery LABEL BYTE + ;; Standard B1 implementations only need the SPD reader call out function to be implemented. + sOemCallout <AGESA_READ_SPD, OFFSET myReadSPDRecovery> +CalloutRouterTableRecoveryEnd LABEL BYTE + + +AMD_RECOVERY_END + + + +;---------------------------------------------------------------------------- +; PRE-MEMORY SEGMENT +; This segment must be uncompressed in the ROM image. +;---------------------------------------------------------------------------- + +AMD_PREMEM_START + + +;---------------------------------------------------------------------------- +; Declare the external routines required in the recovery segment +;---------------------------------------------------------------------------- + +;+--------------------------------------------------------------------------- +; +; myReadSPDPremem (Required) +; +; Entry: +; ESI - Pointer to an AGESA_READ_SPD_PARAMS structure +; +; typedef struct { +; IN OUT AMD_CONFIG_PARAMS StdHeader; +; IN UINT8 SocketId; +; IN UINT8 MemChannelId; +; IN UINT8 DimmId; +; IN OUT UINT8 *Buffer; +; IN OUT MEM_DATA_STRUCT *MemData; +; } AGESA_READ_SPD_PARAMS; +; +; Exit: +; EAX - Contains the AGESA_STATUS return code. +; AGESA_SUCCESS Indicates the SPD block for the indicated +; DIMM was read successfully. +; AGESA_BOUNDS_CHK The specified DIMM is not present. +; AGESA_UNSUPPORTED This is a required function, so this +; value being returned causes a critical +; error response value from the AGESA +; software function and no memory initialized. +; AGESA_ERROR The DIMM SPD read process has generated +; communication errors. +; +; Modified: +; None +; +; Purpose: +; This call out reads a block of memory SPD data and places it +; into the provided buffer. +; +; Dependencies: +; None +; +EXTERN myReadSPDPremem:NEAR + +;+------------------------------------------------------------------------- +; +; AmdDfltRetPremem +; +; Entry: +; None +; +; Exit: +; None +; +; Modified: +; None +; +; Purpose: +; Near stub procedure in the prememory segment. Simply perform a +; retn instruction. +; +EXTERN AmdDfltRetPremem:NEAR + +;+--------------------------------------------------------------------------- +; +; myDoReset (Required) +; +; Entry: +; EDX - Reset type +; 1 - Warm reset whenever +; 2 - Cold reset whenever +; 3 - Warm reset immediately +; 4 - Cold reset immediately +; ESI - Pointer to an AMD_CONFIG_PARAMS structure. +; +; Exit: +; EAX - Contains the AGESA_STATUS return code. +; AGESA_SUCCESS The function has completed successfully. +; AGESA_UNSUPPORTED This is a required function, so this +; value being returned causes a critical +; error response value from the AGESA +; software function. +; +; Modified: +; None +; +; Purpose: +; This host environment function must initiate the specified type +; of system reset. +; +; Implementation of this function by the host environment is +; REQUIRED. Some host environments may record this as a request +; allowing other elements in the system to perform some additional +; tasks before the actual reset is issued. +; +; Dependencies: +; The AMD processor contains 3 bits (BiosRstDet[2:0]) in a PCI +; register (F0x6C Link Initialization Control Register) that +; indicate the reset status. These bits are reserved for use by +; the AGESA software and should not be modified by the host +; environment. +; +EXTERN myDoReset:NEAR + + +;+--------------------------------------------------------------------------- +; +; myGetNonVolatileS3Context (Required for proper S3 operation) +; +; Entry: +; None +; +; Exit: +; EBX - Pointer to the non-volatile S3 context block +; ECX - Size in bytes of the non-volatile S3 context block +; +; Modified: +; None +; +; Purpose: +; The host environment must return the pointer to the data +; saved during the mySaveNonVolatileS3Context routine. +; +; Dependencies: +; None +; +EXTERN myGetNonVolatileS3Context:NEAR + + +;---------------------------------------------------------------------------- +; Declare the optional external routines in the prememory segment +;---------------------------------------------------------------------------- + +;+--------------------------------------------------------------------------- +; +; myAgesaHookBeforeExitSelfRefresh (Optional) +; +; Entry: +; Prior to this hook, AGESA will display - AGESA_TESTPOINT - 44h +; ESI - Pointer to a data structure containing the memory information +; +; Exit: +; After returning control to AGESA, AGESA will display: - AGESA_TESTPOINT - 45h +; EAX - Contains the AGESA_STATUS return code +; AGESA_SUCCESS The function has completed successfully +; AGESA_UNSUPPORTED This function is not implemented by the host environment +; AGESA_WARNING A non-critical issue has occued in the host environment +; +; Modified: +; None +; +; Purpose: +; General purpose hook called before the exiting self refresh +; This procedure is called once per channel +; +; Implementation of this function is optional for the host environment +; This call-out is an opportunity for the host environment to make dynamic +; modifications to the memory timing settings specific to the board or host +; environment before exiting self refresh on S3 resume +; +; Dependencies: +; This procedure is called before the exit self refresh bit is set in the resume +; sequence. The host environment must initiate the OS restart process. This procedure +; requires a stack. The host environment must establish the stack environment prior +; to making the call to this procedure +; +EXTERN myAgesaHookBeforeExitSelfRefresh(AmdDfltRetPremem):NEAR + + +;+--------------------------------------------------------------------------- +; +; myHookBeforeDramInit (Optional) +; +; Entry: +; Prior to this hook, AGESA will display - AGESA_TESTPOINT - 40h +; ESI - Pointer to a data structure containing the memory information +; +; Exit: +; After returning control to AGESA, AGESA will display - AGESA_TESTPOINT - 41h +; EAX - Contains the AGESA_STATUS return code. +; AGESA_SUCCESS The function has completed successfully. +; AGESA_UNSUPPORTED This function is not implemented by the host environment +; +; Modified: +; None +; +; Purpose: +; General-purpose hook called before the DRAM_Init bit is set. Called +; once per MCT +; +; Implementation of this function is optional for the host environment +; This call-out is an opportunity for the host environment to make +; dynamic modifications to the memory timing settings specific to the +; board or host environment +; +; Dependencies: +; None +; +EXTERN myHookBeforeDramInit(AmdDfltRetPremem):NEAR + + +;+--------------------------------------------------------------------------- +; +; myHookBeforeDQSTraining (Optional) +; +; Entry: +; Prior to this hook, AGESA will display - AGESA_TESTPOINT - 42h +; ESI - Pointer to a data structure containing the memory information. +; +; Exit: +; After returning control to AGESA, AGESA will display - AGESA_TESTPOINT - 43h +; EAX - Contains the AGESA_STATUS return code. +; AGESA_SUCCESS The function has completed successfully. +; AGESA_UNSUPPORTED This function is not implemented by the +; host environment. +; +; Modified: +; None +; +; Purpose: +; General-purpose hook called just before the memory training processes +; begin. Called once per MCT. +; +; Implementation of this function is optional for the host environment. +; This call-out is an opportunity for the host environment to make +; dynamic modifications to the memory timing settings specific to the +; board or host environment. +; +; The host environment may also use this call-out for some board- +; specific features that should be activated at this time point, +; such as: +; Low voltage DIMMs-the host environment should set the recommended +; voltages found in the memory data structure for each memory +; channel. This needs to occur before training begins. +; +; Dependencies: +; None +; +EXTERN myHookBeforeDQSTraining(AmdDfltRetPremem):NEAR + + +;---------------------------------------------------------------------------- +; Define the sample wrapper routines for the prememory segment +;---------------------------------------------------------------------------- + +;+--------------------------------------------------------------------------- +; +; AmdInitEarlyWrapper +; +; Entry: +; On Entry to "AmdInitEarly" AGESA will display AGESA_TESTPOINT - C4h +; DS - 0000 with 4 gigabyte access +; ES - 0000 with 4 gigabyte access +; +; Exit: +; On Exit from "AmdInitEarly" AGESA will display AGESA_TESTPOINT - C5h +; None +; +; Modified: +; None +; +; Purpose: +; A full initialization of the processor is performed. Action details +; differ for the BSP and AP processor cores. +; For the BSP, the following actions are performed: +; Full HyperTransportT link initialization, coherent and non-coherent +; Processor register loading +; Microcode patch load +; Errata workaround processing +; Launch all processor cores +; Configure the processor power management capabilities +; Request a warm reset if needed +; For the AP, the following actions are performed: +; Processor register loading +; Microcode patch load +; Errata workaround processing +; Configure the processor power management capabilities +; +; Dependencies: +; This procedure is expected to be called before main memory initialization +; and before the system warm reset. Prior to this, the basic configuration +; done by the AmdInitReset routine must be completed. +; +; This procedure requires a stack. The host environment must use one of the +; provided service functions to establish the stack environment prior to +; making the call to this procedure. +; +; The processes performed at this time point require communication between +; processor cores. +; +; The host environment must recognize that all processor cores are running +; in parallel and avoid activities that might interfere with the core-to-core +; communication, such as modifying the MTRR settings or writing to the APIC +; registers. +; +AmdInitEarlyWrapper PROC NEAR PUBLIC + local localCfgBlock:AMD_INTERFACE_PARAMS + + pushad + + ; Prepare for the call to create and initialize the input parameters for AmdInitEarly + xor eax, eax + mov ax, ss + shl eax, 4 + lea esi, localCfgBlock + add esi, eax + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0 + mov edx, SEG AmdCallout16 + shl edx, 4 + add edx, OFFSET AmdCallout16 + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx + + mov (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_INIT_EARLY + mov (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PreMemHeap + mov (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0 + push esi + mov dx, SEG AmdCalloutRouterPremem + shl edx, 16 + mov dx, OFFSET AmdCalloutRouterPremem + push edx + call AmdBridge32 + pop edx + + mov esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr + + ; The structure has been initialized. Now modify the default settings as desired. + + mov edi, esi + add edi, (SIZEOF AMD_CONFIG_PARAMS + (3 * (SIZEOF EXECUTION_CACHE_REGION))) + call oemPlatformConfigInit + + ; Call in to the AmdInitEarly entry point + push edx + call AmdBridge32 + pop edx + + ;; EAX = AGESA_STATUS + ;; AGESA_SUCCESS The function has completed successfully. + ;; AGESA_ALERT An HyperTransportT link CRC error was observed. + ;; AGESA_WARNING One of more of the allocation rules were violated, + ;; but an adjustment was made and space was allocated. + ;; Or a HyperTransport device does not have the expected + ;; capabilities, or unusable redundant HyperTransport + ;; links were found. + ;; AGESA_ERROR One or more of the allocation rules were violated, which + ;; resulted in a requested cache region to not be allocated. + ;; Or, a HyperTransport device failed to initialize. + ;; AGESA_CRITICAL An illegal or unsupported mixture of processor types was + ;; found, or the processors installed were found to have an + ;; insufficient MP capability rating for this platform. + + .if (eax != AGESA_SUCCESS) + mov al, (AMD_EARLY_PARAMS ptr [esi]).StdHeader.HeapStatus + mov ebx, AGESA_B2_ADDRESS + call AmdProcessAgesaErrors + .endif + + ; Allow AGESA to free the space used by AmdInitEarly + pop esi + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT + call AmdBridge32 + + + popad + ret +AmdInitEarlyWrapper ENDP + + +;+--------------------------------------------------------------------------- +; +; AmdInitPostWrapper +; +; Entry: +; On Entry to "AmdInitPost" AGESA will display AGESA_TESTPOINT - C6h +; DS - 0000 with 4 gigabyte access +; ES - 0000 with 4 gigabyte access +; +; Exit: +; On Exit from "AmdInitPost" AGESA will display AGESA_TESTPOINT - C7h +; None +; +; Modified: +; None +; +; Purpose: +; The main system memory is located, initialized, and brought on-line. +; The processor(s) are prepared for full operation and control by the +; host environment. Action details differ for the BSP and AP processor +; cores. +; For the BSP, the following actions are performed: +; Full memory initialization and configuration. BSP is the master for +; this process and may delegate some tasks to APs. +; AP collection of data for use later. +; Transfer the HOBs including the artifact data out of the pre-memory +; cache storage into a temporary holding buffer in the main memory. +; Check the BIST status of the BSP +; Shut down the APs. +; Prepare for the host environment to begin main boot activity. +; Disable the pre-memory stack. +; For the APs, the following actions are performed: +; Report core identity information. +; Execute indicated memory initialization processes as directed. +; Check the BIST status of the AP +; Disable the pre-memory stack. +; Prepare to halt, giving control to host environment. +; The entire range of system memory is enabled for Write-Back cache. +; The fixed MTRRs and the variable MTRRs[7:6] are not changed in order +; to leave in place any flash ROM region currently set for Write-Protect +; execution cache. +; +; Dependencies: +; This procedure is called after the host environment has determined that +; a normal boot to operating system should be performed after any system +; warm reset is completed and after the configuration done by AmdInitEarly +; has completed. +; +; This procedure requires a stack. The host environment must use one of the +; provided service functions to establish the stack environment prior to +; making the call to this procedure. +; +; The processes performed at this time point require communication between +; processor cores. The host environment must recognize that all processor +; cores are running in parallel and avoid activities that might interfere +; with the core-to-core communication, such as modifying the MTRR settings +; or writing to the APIC registers. +; +AmdInitPostWrapper PROC NEAR PUBLIC + local localCfgBlock:AMD_INTERFACE_PARAMS + + pushad + + ; Prepare for the call to create and initialize the input parameters for AmdInitPost + xor eax, eax + mov ax, ss + shl eax, 4 + lea esi, localCfgBlock + add esi, eax + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0 + mov edx, SEG AmdCallout16 + shl edx, 4 + add edx, OFFSET AmdCallout16 + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx + + mov (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_INIT_POST + mov (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PreMemHeap + mov (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0 + push esi + mov dx, SEG AmdCalloutRouterPremem + shl edx, 16 + mov dx, OFFSET AmdCalloutRouterPremem + push edx + call AmdBridge32 + pop edx + + mov esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr + + ; The structure has been initialized. Now modify the default settings as desired. + + mov edi, esi + add edi, SIZEOF AMD_CONFIG_PARAMS + call oemPlatformConfigInit + + ; Call in to the AmdInitPost entry point + push edx + call AmdBridge32 + pop edx + + ;; EAX = AGESA_STATUS + ;; AGESA_SUCCESS The function has completed successfully. + ;; AGESA_ALERT A BIST error was found on one of the cores. + ;; AGESA_WARNING HT Assist feature is running sub-optimally. + ;; AGESA_FATAL Memory initialization failed. + + .if (eax != AGESA_SUCCESS) + mov al, (AMD_POST_PARAMS ptr [esi]).StdHeader.HeapStatus + mov ebx, AGESA_B2_ADDRESS + call AmdProcessAgesaErrors + .endif + + ; Allow AGESA to free the space used by AmdInitPost + pop esi + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT + call AmdBridge32 + + + popad + ret +AmdInitPostWrapper ENDP + + +;+--------------------------------------------------------------------------- +; +; AmdInitResumeWrapper +; +; Entry: +; On Entry to "AmdInitResume" AGESA will display AGESA_TESTPOINT - D0h +; DS - 0000 with 4 gigabyte access +; ES - 0000 with 4 gigabyte access +; +; Exit: +; On Exit from "AmdInitResume" AGESA will display AGESA_TESTPOINT - D1h +; None +; +; Modified: +; None +; +; Purpose: +; This procedure initializes or re-initializes the silicon components +; for the resume boot path. For the processor, main memory is brought +; out of self-refresh mode. This procedure will use the context data +; in the NvStorage area of the input structure to re-start the main +; memory. The host environment must fill the AMD_S3_PARAMS NvStorage +; and VolatileStorage pointers and related size elements to describe +; the location of the context data. Note that for this procedure, the +; two data areas do not need to be contained in one buffer zone, they +; can be anywhere in the accessible memory address space. If the host +; environment uses a non-volatile storage device accessed on the system +; address bus such as flashROM, then the context data does not need to +; be moved prior to this call. If the host environment uses a non- +; volatile storage device not located on the system address bus (e.g. +; CMOS or SSEPROM) then the host environment must transfer the context +; data to a buffer in main memory prior to calling this procedure. +; +; Dependencies: +; The host environment must have determined that the system should take +; the resume path prior to calling this procedure. The configuration +; done by AmdInitEarly and any necessary warm reset must be complete. +; After this procedure, execution proceeds to general system restoration. +; +; This procedure requires a stack. The host environment must use one of +; the provided service functions to establish the stack environment prior +; to making the call to this procedure. +; +AmdInitResumeWrapper PROC NEAR PUBLIC + local localCfgBlock:AMD_INTERFACE_PARAMS + + pushad + + ; Prepare for the call to create and initialize the input parameters for AmdInitResume + xor eax, eax + mov ax, ss + shl eax, 4 + lea esi, localCfgBlock + add esi, eax + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0 + mov edx, SEG AmdCallout16 + shl edx, 4 + add edx, OFFSET AmdCallout16 + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx + + mov (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_INIT_RESUME + mov (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PreMemHeap + mov (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0 + push esi + mov dx, SEG AmdCalloutRouterPremem + shl edx, 16 + mov dx, OFFSET AmdCalloutRouterPremem + push edx + call AmdBridge32 + pop edx + + mov esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr + + ; The structure has been initialized. Now modify the default settings as desired. + + mov edi, esi + add edi, (SIZEOF AMD_CONFIG_PARAMS + SIZEOF AMD_S3_PARAMS) + call oemPlatformConfigInit + + call myGetNonVolatileS3Context + mov (AMD_RESUME_PARAMS ptr [esi]).S3DataBlock.NvStorage, ebx + mov (AMD_RESUME_PARAMS ptr [esi]).S3DataBlock.NvStorageSize, ecx + + ; Call in to the AmdInitResume entry point + push edx + call AmdBridge32 + pop edx + + ;; EAX = AGESA_STATUS + ;; AGESA_SUCCESS Re-initialization has been completed successfully. + .if (eax != AGESA_SUCCESS) + mov al, (AMD_RESUME_PARAMS ptr [esi]).StdHeader.HeapStatus + mov ebx, AGESA_B2_ADDRESS + call AmdProcessAgesaErrors + .endif + + + ; Allow AGESA to free the space used by AmdInitResume + pop esi + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT + call AmdBridge32 + + + popad + ret +AmdInitResumeWrapper ENDP + + +;+--------------------------------------------------------------------------- +; +; AmdCalloutRouterPremem +; +; Entry: +; ECX - Callout function number +; EDX - Function-specific UINTN +; ESI - Pointer to function specific data +; +; Exit: +; EAX - Contains the AGESA_STATUS return code. +; +; Modified: +; None +; +; Purpose: +; The call out router function for AmdInitEarly, +; AmdInitPost, and AmdInitResume. +; +; Dependencies: +; None +; +AmdCalloutRouterPremem PROC FAR PUBLIC USES ECX EBX ESI BX DI DS ES + xor ax, ax + mov ds, ax + mov es, ax + lea di, cs:CalloutRouterTablePremem + mov eax, AGESA_UNSUPPORTED + +loopThruTable: + cmp di, OFFSET cs:CalloutRouterTablePrememEnd + jae amdCpuCalloutExit ; exit with AGESA_UNSUPPORTED + cmp ecx, cs:[di].sOemCallout.FuncName + je FoundMatch + add di, SIZEOF sOemCallout + jmp loopThruTable + +FoundMatch: + mov bx, cs:[di].sOemCallout.FuncPtr + call bx + +amdCpuCalloutExit: + ret +AmdCalloutRouterPremem ENDP + + +;---------------------------------------------------------------------------- +; Define the callout dispatch table for the prememory segment +;---------------------------------------------------------------------------- + +CalloutRouterTablePremem LABEL BYTE + ;; Add entries as desired. + sOemCallout <AGESA_READ_SPD, OFFSET myReadSPDPremem> + sOemCallout <AGESA_HOOKBEFORE_DRAM_INIT, OFFSET myHookBeforeDramInit> + sOemCallout <AGESA_HOOKBEFORE_DQS_TRAINING, OFFSET myHookBeforeDQSTraining> + sOemCallout <AGESA_HOOKBEFORE_EXIT_SELF_REF, OFFSET myAgesaHookBeforeExitSelfRefresh> + sOemCallout <AGESA_DO_RESET, OFFSET myDoReset> +CalloutRouterTablePrememEnd LABEL BYTE + + + +AMD_PREMEM_END + + +;---------------------------------------------------------------------------- +; POST SEGMENT +; This segment may be decompressed and run from system RAM. +;---------------------------------------------------------------------------- + +AMD_POST_START + + +;---------------------------------------------------------------------------- +; Declare the external routines required in the POST segment +;---------------------------------------------------------------------------- + +;+--------------------------------------------------------------------------- +; +; myAllocateBuffer (Required) +; +; Entry: +; Prior to this hook, AGESA will display - AGESA_TESTPOINT - E2h +; ESI - Pointer to an AGESA_BUFFER_PARAMS structure. +; +; typedef struct { +; IN OUT AMD_CONFIG_PARAMS StdHeader; +; IN UINT32 BufferLength; +; IN UINT32 BufferHandle; +; OUT VOID *BufferPointer; +; } AGESA_BUFFER_PARAMS; +; +; Exit: +; After this hook, AGESA will display - AGESA_TESTPOINT - E3h +; EAX - Contains the AGESA_STATUS return code. +; AGESA_SUCCESS The requested size of memory has been +; successfully allocated. +; AGESA_UNSUPPORTED This is a required function, so this +; value being returned causes a critical +; error response value from the AGESA +; software function. +; AGESA_ERROR Less than the requested amount of memory +; was allocated. +; +; Modified: +; EAX +; +; Purpose: +; This function is used after main memory has been initialized +; and the host environment has taken control of memory allocation. +; This function must allocate a buffer of the requested size or +; larger. This function is required to be implemented by the host +; environment. +; +; Dependencies: +; The following call-outs must work together in the host system. +; Parameters of the same name have the same function and must be +; treated the same in each function: +; AgesaAllocateBuffer +; AgesaDeallocateBuffer +; AgesaLocateBuffer +; AgesaRunFcnOnAp +; The host environment may need to reserve a location in the buffer +; to store any host environment specific value(s). The returned +; pointer must not include this reserved space. The host environment +; on the AgesaDeallocateBuffer call needs to account for the reserved +; space. This reserved space may be an identifier or the "handle" +; used to identify the specific memory block. +; +EXTERN myAllocateBuffer:NEAR + +;+--------------------------------------------------------------------------- +; +; myDeallocateBuffer (Required) +; +; Entry: +; Prior to this hook, AGESA will display - AGESA_TESTPOINT - E4h +; ESI - Pointer to an AGESA_BUFFER_PARAMS structure. +; +; typedef struct { +; IN OUT AMD_CONFIG_PARAMS StdHeader; +; IN UINT32 BufferLength; +; IN UINT32 BufferHandle; +; OUT VOID *BufferPointer; +; } AGESA_BUFFER_PARAMS; +; +; Exit: +; After this hook, AGESA will display - AGESA_TESTPOINT - E5h +; EAX - Contains the AGESA_STATUS return code. +; AGESA_SUCCESS The function has completed successfully. +; AGESA_BOUNDS_CHK The BufferHandle is invalid. The AGESA +; software continues with its function. +; AGESA_UNSUPPORTED This is a required function, so this +; value being returned causes a critical +; error response value from the AGESA +; software function. +; +; Modified: +; EAX +; +; Purpose: +; This function is used after main memory has been initialized +; and the host environment has taken control of memory allocation. +; This function releases a valid working buffer. This function is +; required for the host environment to implement. +; +; Dependencies: +; The following call-outs must work together in the host system. +; Parameters of the same name have the same function and must be +; treated the same in each function: +; AgesaAllocateBuffer +; AgesaDeallocateBuffer +; AgesaLocateBuffer +; AgesaRunFcnOnAp +; +EXTERN myDeallocateBuffer:NEAR + +;+--------------------------------------------------------------------------- +; +; myLocateBuffer (Required) +; +; Entry: +; Prior to this hook, AGESA will display - AGESA_TESTPOINT - E6h +; ESI - Pointer to an AGESA_BUFFER_PARAMS structure. +; +; typedef struct { +; IN OUT AMD_CONFIG_PARAMS StdHeader; +; IN UINT32 BufferLength; +; IN UINT32 BufferHandle; +; OUT VOID *BufferPointer; +; } AGESA_BUFFER_PARAMS; +; +; Exit: +; After this hook, AGESA will display - AGESA_TESTPOINT - E7h +; EAX - Contains the AGESA_STATUS return code. +; AGESA_SUCCESS The function has completed successfully. +; AGESA_BOUNDS_CHK The presented handle is invalid or the +; buffer could not be located. +; +; Modified: +; EAX +; +; Purpose: +; This function is used after main memory has been initialized +; and the host environment has taken control of memory allocation. +; This function must locate the buffer related to the indicated +; handle and return the address of the buffer and its length. +; This function is required to be implemented in the host +; environment. +; +; Dependencies: +; The following call-outs must work together in the host system. +; Parameters of the same name have the same function and must be +; treated the same in each function: +; AgesaAllocateBuffer +; AgesaDeallocateBuffer +; AgesaLocateBuffer +; AgesaRunFcnOnAp +; +EXTERN myLocateBuffer:NEAR + + +;+--------------------------------------------------------------------------- +; +; myRunFuncOnAp (Required) +; +; Entry: +; EDX - Local APIC ID of the target core. +; +; Exit: +; None +; +; Modified: +; None +; +; Purpose: +; The host environment must route execution to the target AP and +; have that AP call the AmdLateRunApTaskWrapper routine defined +; above. +; +; Dependencies: +; None +; +EXTERN myRunFuncOnAp:NEAR + +;+--------------------------------------------------------------------------- +; +; mySaveNonVolatileS3Context (Required for proper S3 operation) +; +; Entry: +; EBX - Pointer to the non-volatile S3 context block +; ECX - Size in bytes of the non-volatile S3 context block +; +; Exit: +; None +; +; Modified: +; None +; +; Purpose: +; The host environment must save the non-volatile data to an area +; that will not lose context while in the ACPI S3 sleep state, but +; cannot be placed in system RAM. This data will need to be +; available during the call to AmdInitResume. +; +; Dependencies: +; None +; +EXTERN mySaveNonVolatileS3Context:NEAR + +;+--------------------------------------------------------------------------- +; +; mySaveVolatileS3Context (Required for proper S3 operation) +; +; Entry: +; EBX - Pointer to the volatile S3 context block +; ECX - Size in bytes of the volatile S3 context block +; +; Exit: +; None +; +; Modified: +; None +; +; Purpose: +; The host environment must save the volatile data to an area +; that will not lose context while in the ACPI S3 sleep state. +; This data will need to be available during the call to +; AmdS3LateRestore. +; +; Dependencies: +; None +; +EXTERN mySaveVolatileS3Context:NEAR + +;+--------------------------------------------------------------------------- +; +; myGetVolatileS3Context (Required for proper S3 operation) +; +; Entry: +; None +; +; Exit: +; EBX - Pointer to the volatile S3 context block +; ECX - Size in bytes of the volatile S3 context block +; +; Modified: +; None +; +; Purpose: +; The host environment must return the pointer to the data +; saved during the mySaveVolatileS3Context routine. +; +; Dependencies: +; None +; +EXTERN myGetVolatileS3Context:NEAR + + +;---------------------------------------------------------------------------- +; Define the sample wrapper routines for the POST segment +;---------------------------------------------------------------------------- + +;+--------------------------------------------------------------------------- +; +; AmdInitEnvWrapper +; +; Entry: +; On Entry to "AmdInitEnv" AGESA will display AGESA_TESTPOINT - C8h +; DS - 0000 with 4 gigabyte access +; ES - 0000 with 4 gigabyte access +; +; Exit: +; On Exit from "AmdInitEnv" AGESA will display AGESA_TESTPOINT - C9h +; None +; +; Modified: +; None +; +; Purpose: +; This procedure uses the AgesaAllocateBuffer call-out to acquire +; permanent buffer space for the UEFI Hand-Off Blocks (HOBs). This +; is also known as, or includes, artifact data being used by the +; AGESA software. Upon entry to this procedure, the data is being +; held in a temporary memory location and it must be moved to a +; location controlled and protected by the host environment. +; +; These actions are performed by the BSP. The APs are not assigned +; any tasks at this time point. +; +; Dependencies: +; This procedure must be called after full memory is initialized and +; the host environment has taken control of main memory allocation. +; This procedure should be called before the PCI enumeration takes +; place and as soon as possible after the host environment memory +; allocation sub-system has started. +; +; This procedure requires a stack. The host environment must use one +; of the provided service functions to establish the stack environment +; prior to making the call to this procedure. +; +AmdInitEnvWrapper PROC NEAR PUBLIC + local localCfgBlock:AMD_INTERFACE_PARAMS + + pushad + + ; Prepare for the call to create and initialize the input parameters for AmdInitEnv + xor eax, eax + mov ax, ss + shl eax, 4 + lea esi, localCfgBlock + add esi, eax + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0 + mov edx, SEG AmdCallout16 + shl edx, 4 + add edx, OFFSET AmdCallout16 + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx + + mov (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_INIT_ENV + mov (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PostMemDram + mov (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0 + push esi + mov dx, SEG AmdCalloutRouterPost + shl edx, 16 + mov dx, OFFSET AmdCalloutRouterPost + push edx + call AmdBridge32 + pop edx + + mov esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr + + ; The structure has been initialized. Now modify the default settings as desired. + + mov edi, esi + add edi, SIZEOF AMD_CONFIG_PARAMS + call oemPlatformConfigInit + + ; Call in to the AmdInitEnv entry point + push edx + call AmdBridge32 + pop edx + + ;; EAX = AGESA_STATUS + ;; AGESA_SUCCESS The function has completed successfully. + ;; AGESA_ERROR The artifact data could not be found or the host + ;; environment failed to allocate sufficient buffer space. + + .if (eax != AGESA_SUCCESS) + mov al, (AMD_ENV_PARAMS ptr [esi]).StdHeader.HeapStatus + mov ebx, AGESA_B2_ADDRESS + call AmdProcessAgesaErrors + .endif + + ; Allow AGESA to free the space used by AmdInitEnv + pop esi + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT + call AmdBridge32 + + + popad + ret +AmdInitEnvWrapper ENDP + + +;+--------------------------------------------------------------------------- +; +; AmdInitMidWrapper +; +; Entry: +; On Entry to "AmdInitMid" AGESA will display AGESA_TESTPOINT - CAh +; DS - 0000 with 4 gigabyte access +; ES - 0000 with 4 gigabyte access +; +; Exit: +; On Exit from "AmdInitMid" AGESA will display AGESA_TESTPOINT - CBh +; None +; +; Modified: +; None +; +; Purpose: +; This procedure call performs special configuration requirements for +; the graphics display hardware. +; +; These actions are performed by the BSP. The APs are not assigned any +; tasks at this time point. +; +; Dependencies: +; This procedure must be called after PCI enumeration has allocated +; resources, but before the video BIOS call is performed. +; +; This procedure requires a stack. The host environment must use one +; of the provided service functions to establish the stack environment +; prior to making the call to this procedure. +; +AmdInitMidWrapper PROC NEAR PUBLIC + local localCfgBlock:AMD_INTERFACE_PARAMS + + pushad + + ; Prepare for the call to create and initialize the input parameters for AmdInitMid + xor eax, eax + mov ax, ss + shl eax, 4 + lea esi, localCfgBlock + add esi, eax + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0 + mov edx, SEG AmdCallout16 + shl edx, 4 + add edx, OFFSET AmdCallout16 + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx + + mov (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_INIT_MID + mov (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PostMemDram + mov (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0 + push esi + mov dx, SEG AmdCalloutRouterPost + shl edx, 16 + mov dx, OFFSET AmdCalloutRouterPost + push edx + call AmdBridge32 + pop edx + + mov esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr + + ; The structure has been initialized. Now modify the default settings as desired. + + mov edi, esi + add edi, SIZEOF AMD_CONFIG_PARAMS + call oemPlatformConfigInit + + ; Call in to the AmdInitMid entry point + push edx + call AmdBridge32 + pop edx + + ;; EAX = AGESA_STATUS + ;; AGESA_SUCCESS The function has completed successfully. + + .if (eax != AGESA_SUCCESS) + mov al, (AMD_MID_PARAMS ptr [esi]).StdHeader.HeapStatus + mov ebx, AGESA_B2_ADDRESS + call AmdProcessAgesaErrors + .endif + + ; Allow AGESA to free the space used by AmdInitMid + pop esi + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT + call AmdBridge32 + + + popad + ret + +AmdInitMidWrapper ENDP + + +;+--------------------------------------------------------------------------- +; +; AmdInitLateWrapper +; +; Entry: +; On Entry to "AmdInitLate" AGESA will display AGESA_TESTPOINT - CCh +; DS - 0000 with 4 gigabyte access +; ES - 0000 with 4 gigabyte access +; +; Exit: +; On Exit from "AmdInitLate" AGESA will display AGESA_TESTPOINT - CDh +; None +; +; Modified: +; None +; +; Purpose: +; The main purpose of this function is to generate informational +; data tables used by the operating system. The individual tables +; can be selected for generation through the user selection entries +; on the input parameters. +; +; This routine uses the Call-Out AgesaAllocateBuffer to allocate a +; buffer of the proper size to contain the data. +; +; The code path separates the BSP from the APs and perform a separate +; and appropriate list of tasks for each class of core. +; For the BSP, the following actions are performed: +; Allocate buffer space for the tables. +; Generate the table contents. +; Make sure that the CPU is in a known good power state before +; proceeding to boot the OS. +; For the APs, the following actions are performed: +; Final register settings preparing for entry to OS. +; Establish the final PState for entry to OS. +; +; Dependencies: +; This routine is expected to be executed late in the boot sequence +; after main memory has been initialized, after PCI enumeration has +; completed, after the host environment ACPI sub-system has started, +; after the host environment has taken control of the APs, but just +; before the start of OS boot. +; +; The host environment must provide the required call-outs listed in +; the "Required Call-Out Procedures" section of the AGESA interface +; specification to provide the buffer space in main memory and execute +; code on the APs. The host environment must register the created ACPI +; table in the main ACPI pointer tables. This may require moving the +; generated tables to another location in memory. +; +; This procedure requires a stack. The host environment must establish +; the stack environment prior to making the call to this procedure. +; Some functions depend upon the preservation of the heap data across +; the shift from pre-memory environment to a post-memory environment. +; If that data was not preserved, then those functions cannot complete +; and an error is returned. +; +AmdInitLateWrapper PROC NEAR PUBLIC + local localCfgBlock:AMD_INTERFACE_PARAMS + + pushad + + ; Prepare for the call to create and initialize the input parameters for AmdInitLate + xor eax, eax + mov ax, ss + shl eax, 4 + lea esi, localCfgBlock + add esi, eax + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0 + mov edx, SEG AmdCallout16 + shl edx, 4 + add edx, OFFSET AmdCallout16 + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx + + mov (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_INIT_LATE + mov (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PostMemDram + mov (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0 + push esi + mov dx, SEG AmdCalloutRouterPost + shl edx, 16 + mov dx, OFFSET AmdCalloutRouterPost + push edx + call AmdBridge32 + pop edx + + mov esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr + + ; The structure has been initialized. Now modify the default settings as desired. + + mov edi, esi + add edi, SIZEOF AMD_CONFIG_PARAMS + call oemPlatformConfigInit + + ; Call in to the AmdInitLate entry point + push edx + call AmdBridge32 + pop edx + + ;; EAX = AGESA_STATUS + ;; AGESA_SUCCESS The function has completed successfully. + ;; AGESA_ALERT + ;; AGESA_ERROR The system could not allocate the needed amount of + ;; buffer space; or could not locate the artifact data block in + ;; memory. Likely cause: the host environment may not have preserved + ;; the data properly. + + .if (eax != AGESA_SUCCESS) + mov al, (AMD_LATE_PARAMS ptr [esi]).StdHeader.HeapStatus + mov ebx, AGESA_B2_ADDRESS + call AmdProcessAgesaErrors + .endif + + push es + mov ax, SEG AmdAcpiSratPointer + mov es, ax + + mov ebx, (AMD_LATE_PARAMS ptr [esi]).AcpiSrat + mov es:AmdAcpiSratPointer, ebx + mov eax, DWORD PTR [ebx + 4] + mov es:AmdAcpiSratSize, eax + + mov ebx, (AMD_LATE_PARAMS ptr [esi]).AcpiSlit + mov es:AmdAcpiSlitPointer, ebx + mov eax, DWORD PTR [ebx + 4] + mov es:AmdAcpiSlitSize, eax + + mov ebx, (AMD_LATE_PARAMS ptr [esi]).AcpiPState + mov es:AmdAcpiSsdtPointer, ebx + mov eax, DWORD PTR [ebx + 4] + mov es:AmdAcpiSsdtSize, eax + + xor eax, eax + + mov ebx, (AMD_LATE_PARAMS ptr [esi]).AcpiWheaMce + mov es:AmdAcpiWheaMcePointer, ebx + mov ax, WORD PTR [ebx] + mov es:AmdAcpiWheaMceSize, eax + + mov ebx, (AMD_LATE_PARAMS ptr [esi]).AcpiWheaMce + mov es:AmdAcpiWheaCmcPointer, ebx + mov ax, WORD PTR [ebx] + mov es:AmdAcpiWheaCmcSize, eax + + mov eax, (AMD_LATE_PARAMS ptr [esi]).DmiTable + mov es:AmdDmiInfoPointer, eax + pop es + + + ; Allow AGESA to free the space used by AmdInitLate + pop esi + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT + call AmdBridge32 + + popad + ret + +AmdInitLateWrapper ENDP + + +;+--------------------------------------------------------------------------- +; +; AmdS3SaveWrapper +; +; Entry: +; On Entry to "AmdS3Save" AGESA will display AGESA_TESTPOINT - CEh +; DS - 0000 with 4 gigabyte access +; ES - 0000 with 4 gigabyte access +; +; Exit: +; On Entry to "AmdS3Save" AGESA will display AGESA_TESTPOINT - CFh +; None +; +; Modified: +; None +; +; Purpose: +; This procedure saves critical registers and/or configuration +; information for preservation across a system suspend mode. All +; actions needed to prepare the processor for suspend mode is +; performed, however this procedure does NOT initiate the suspend +; process. The host environment is expected to perform that duty. +; +; These actions are performed by the BSP. The APs are not assigned +; any tasks at this time point. +; +; The initializer routine will NULL out the save area pointers and +; sizes. This procedure will determine the size of storage needed +; for all the processor context, and make a call out to the environment +; for allocation of one buffer to store all of the data. Upon exit, the +; pointers and sizes within the AMD_S3_PARAMS structure will be updated +; with the appropriate addresses within the buffer that was allocated. +; The host environment is expected to then transfer the data pointed to +; by NvStorage to a non-volatile storage area, and the data pointed to +; by VolatileStorage to either a non-volatile storage area or system +; RAM that retains its content across suspend. +; +; Dependencies: +; The host environment must initiate the suspend process. +; +; This procedure requires a stack. The host environment must establish +; the stack environment prior to making the call to this procedure. +; +AmdS3SaveWrapper PROC NEAR PUBLIC + local localCfgBlock:AMD_INTERFACE_PARAMS + + pushad + + ; Prepare for the call to create and initialize the input parameters for AmdS3Save + xor eax, eax + mov ax, ss + shl eax, 4 + lea esi, localCfgBlock + add esi, eax + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0 + mov edx, SEG AmdCallout16 + shl edx, 4 + add edx, OFFSET AmdCallout16 + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx + + mov (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_S3_SAVE + mov (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PostMemDram + mov (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0 + push esi + mov dx, SEG AmdCalloutRouterPost + shl edx, 16 + mov dx, OFFSET AmdCalloutRouterPost + push edx + call AmdBridge32 + pop edx + + mov esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr + + ; The structure has been initialized. Now modify the default settings as desired. + + mov edi, esi + add edi, (SIZEOF AMD_CONFIG_PARAMS + SIZEOF AMD_S3_PARAMS) + call oemPlatformConfigInit + + ; Call in to the AmdS3Save entry point + push edx + call AmdBridge32 + pop edx + + ;; EAX = AGESA_STATUS + ;; AGESA_SUCCESS All suspend duties have been completed successfully. + + .if (eax != AGESA_SUCCESS) + mov al, (AMD_S3SAVE_PARAMS ptr [esi]).StdHeader.HeapStatus + mov ebx, AGESA_B2_ADDRESS + call AmdProcessAgesaErrors + .endif + + mov ecx, (AMD_S3SAVE_PARAMS ptr [esi]).S3DataBlock.NvStorageSize + .if (ecx != 0) + mov ebx, (AMD_S3SAVE_PARAMS ptr [esi]).S3DataBlock.NvStorage + call mySaveNonVolatileS3Context + .endif + + mov ecx, (AMD_S3SAVE_PARAMS ptr [esi]).S3DataBlock.VolatileStorageSize + .if (ecx != 0) + mov ebx, (AMD_S3SAVE_PARAMS ptr [esi]).S3DataBlock.VolatileStorage + call mySaveVolatileS3Context + .endif + + ; Allow AGESA to free the space used by AmdS3Save + pop esi + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT + call AmdBridge32 + + popad + ret + +AmdS3SaveWrapper ENDP + + +;+--------------------------------------------------------------------------- +; +; AmdS3LateRestoreWrapper +; +; Entry: +; On Entry to "AmdS3LateRestore" AGESA will display AGESA_TESTPOINT - D2h +; DS - 0000 with 4 gigabyte access +; ES - 0000 with 4 gigabyte access +; +; Exit: +; On Exit from "AmdS3LateRestore" AGESA will display AGESA_TESTPOINT - D3h +; None +; +; Modified: +; None +; +; Purpose: +; This procedure restores the processor state, reloads critical +; silicon component registers, and performs any re-initialization +; required by the silicon. This procedure will use the context data +; in the VolatileStorage area of the input structure to restore the +; processor registers. +; +; The host environment must fill the AMD_S3_PARAMS NvStorage and +; VolatileStorage pointers and related size elements to describe +; the location of the context data. Note that for this procedure, +; the two data areas do not need to be contained in one buffer zone, +; they can be anywhere in the accessible memory address space. If +; the host environment uses a non-volatile storage device accessed +; on the system address bus such as flashROM, then the context data +; does not need to be moved prior to this call. If the host +; environment uses a non-volatile storage device not located on the +; system address bus (e.g. CMOS or SSEPROM) then the host environment +; must transfer the context data to a buffer in main memory prior to +; calling this procedure. +; +; These actions are performed by the BSP. The APs are not assigned +; any tasks at this time point. +; +; Dependencies: +; This procedure is called late in the resume sequence, after the +; PCI control space is restored and just before resuming operating +; system execution. +; +; The host environment must initiate the OS restart process. +; +; This procedure requires a stack. The host environment must establish +; the stack environment prior to making the call to this procedure. +; +AmdS3LateRestoreWrapper PROC NEAR PUBLIC + local localCfgBlock:AMD_INTERFACE_PARAMS + + pushad + + ; Prepare for the call to create and initialize the input parameters for AmdS3LateRestore + xor eax, eax + mov ax, ss + shl eax, 4 + lea esi, localCfgBlock + add esi, eax + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0 + mov edx, SEG AmdCallout16 + shl edx, 4 + add edx, OFFSET AmdCallout16 + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx + + mov (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_S3LATE_RESTORE + mov (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PostMemDram + mov (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0 + push esi + mov dx, SEG AmdCalloutRouterPost + shl edx, 16 + mov dx, OFFSET AmdCalloutRouterPost + push edx + call AmdBridge32 + pop edx + + mov esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr + + ; The structure has been initialized. Now modify the default settings as desired. + + mov edi, esi + add edi, (SIZEOF AMD_CONFIG_PARAMS + SIZEOF AMD_S3_PARAMS) + call oemPlatformConfigInit + + call myGetVolatileS3Context + mov (AMD_S3LATE_PARAMS ptr [esi]).S3DataBlock.VolatileStorage, ebx + mov (AMD_S3LATE_PARAMS ptr [esi]).S3DataBlock.VolatileStorageSize, ecx + + ; Call in to the AmdS3LateRestore entry point + push edx + call AmdBridge32 + pop edx + + ;; EAX = AGESA_STATUS + ;; AGESA_SUCCESS All resume processes have been completed successfully. + + .if (eax != AGESA_SUCCESS) + mov al, (AMD_S3LATE_PARAMS ptr [esi]).StdHeader.HeapStatus + mov ebx, AGESA_B2_ADDRESS + call AmdProcessAgesaErrors + .endif + + ; Allow AGESA to free the space used by AmdS3LateRestore + pop esi + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT + call AmdBridge32 + + popad + ret +AmdS3LateRestoreWrapper ENDP + + +;+--------------------------------------------------------------------------- +; +; AmdLateRunApTaskWrapper +; +; Entry: +; Prior to this hook, AGESA will display - AGESA_TESTPOINT - D4h +; DS - 0000 with 4 gigabyte access +; ES - 0000 with 4 gigabyte access +; +; Exit: +; After this hook, AGESA will display - AGESA_TESTPOINT - D5h +; None +; +; Modified: +; None +; +; Purpose: +; This entry point is tightly connected with the "AgesaRunFcnOnAp" +; call out. The AGESA software will call the call-out "AgesaRunFcnOnAp"; +; the host environment will then call this entry point to have the AP +; execute the requested function. This is needed late in the Post and +; Resume branches for running an AP task since the AGESA software has +; relinquished control of the APs to the host environment. +; +; Dependencies: +; The host environment must implement the"AgesaRunFcnOnAp" call-out +; and route execution to the target AP. +; +AmdLateRunApTaskWrapper PROC NEAR PUBLIC + local localCfgBlock:AMD_INTERFACE_PARAMS + + pushad + + ; Prepare for the call to create and initialize the input parameters for AmdLateRunApTask + xor eax, eax + mov ax, ss + shl eax, 4 + lea esi, localCfgBlock + add esi, eax + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0 + mov edx, SEG AmdCallout16 + shl edx, 4 + add edx, OFFSET AmdCallout16 + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx + + mov (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_LATE_RUN_AP_TASK + mov (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PostMemDram + mov (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0 + push esi + mov dx, SEG AmdCalloutRouterPost + shl edx, 16 + mov dx, OFFSET AmdCalloutRouterPost + push edx + call AmdBridge32 + pop edx + + mov esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr + + ; The structure has been initialized. Now modify the default settings as desired. + + push es + mov ax, SEG AmdRunCodeOnApDataPointer + mov es, ax + mov eax, es:AmdRunCodeOnApDataPointer + mov (AP_EXE_PARAMS PTR [esi]).RelatedDataBlock, eax + mov eax, es:AmdRunCodeOnApDataSize + mov (AP_EXE_PARAMS PTR [esi]).RelatedBlockLength, eax + mov eax, es:AmdRunCodeOnApFunction + mov (AP_EXE_PARAMS PTR [esi]).FunctionNumber, eax + pop es + + ; Call in to the AmdLateRunApTask dispatcher + push edx + call AmdBridge32 + pop edx + + ;; EAX = AGESA_STATUS + push es + mov bx, SEG AmdRunCodeOnApStatus + mov es, bx + mov es:AmdRunCodeOnApStatus, eax + pop es + + ; Allow AGESA to free the space used by AmdLateRunApTask + pop esi + mov (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT + call AmdBridge32 + + popad + ret + +AmdLateRunApTaskWrapper ENDP + + +;+--------------------------------------------------------------------------- +; +; AmdRunFuncOnAp (Required) +; +; Entry: +; Prior to this hook, AGESA will display - AGESA_TESTPOINT - E8h +; EDX - Local APIC ID of the target core. +; ESI - Pointer to an AP_EXE_PARAMS structure. +; +; typedef struct { +; IN OUT AMD_CONFIG_PARAMS StdHeader; +; IN UINT32 FunctionNumber; +; IN VOID *RelatedDataBlock; +; IN UINT32 RelatedDataBlockLength; +; } AP_EXE_PARAMS; +; +; Exit: +; After this hook, AGESA will display - AGESA_TESTPOINT - E9h +; EAX - Contains the AGESA_STATUS return code. +; AGESA_SUCCESS The function has completed successfully. +; AGESA_UNSUPPORTED This is a required function, so this value +; being returned causes a critical error +; response value from the AGESAT software +; function and no memory initialized. +; AGESA_WARNING The AP did not respond. +; +; Modified: +; EAX +; +; Purpose: +; This function is used after main memory has been initialized +; and the host environment has taken control of AP task dispatching. +; This function must cause the indicated function code to be executed +; upon the specified Application Processor. This procedure must be +; executed in 32-bit mode. This function is required to be implemented +; in the host environment. +; +; Dependencies: +; The host environment must route execution to the target AP and +; have that AP call the"AmdLateRunApTask" entry point. +; +AmdRunFuncOnAp PROC NEAR PUBLIC + + push es + mov ax, SEG AmdRunCodeOnApDataPointer + mov es, ax + mov eax, (AP_EXE_PARAMS PTR [esi]).RelatedDataBlock + mov es:AmdRunCodeOnApDataPointer, eax + mov eax, (AP_EXE_PARAMS PTR [esi]).RelatedBlockLength + mov es:AmdRunCodeOnApDataSize, eax + mov eax, (AP_EXE_PARAMS PTR [esi]).FunctionNumber + mov es:AmdRunCodeOnApFunction, eax + mov eax, AGESA_UNSUPPORTED + mov es:AmdRunCodeOnApStatus, eax + pop es + + call myRunFuncOnAp + + push es + mov ax, SEG AmdRunCodeOnApStatus + mov es, ax + mov eax, es:AmdRunCodeOnApStatus + pop es + ret +AmdRunFuncOnAp ENDP + + + +;+--------------------------------------------------------------------------- +; +; AmdCalloutRouterPost +; +; Entry: +; ECX - Callout function number +; EDX - Function-specific UINTN +; ESI - Pointer to function specific data +; +; Exit: +; EAX - Contains the AGESA_STATUS return code. +; +; Modified: +; None +; +; Purpose: +; The call out router function for AmdInitEnv, +; AmdInitMid, AmdInitLate, AmdS3Save, and +; AmdS3LateRestore. +; +; Dependencies: +; None +; +AmdCalloutRouterPost PROC FAR PUBLIC USES ECX EBX ESI BX DI DS ES + xor ax, ax + mov ds, ax + mov es, ax + lea di, cs:CalloutRouterTablePost + mov eax, AGESA_UNSUPPORTED + +loopThruTable: + cmp di, OFFSET cs:CalloutRouterTablePostEnd + jae amdCpuCalloutExit ; exit with AGESA_UNSUPPORTED + cmp ecx, cs:[di].sOemCallout.FuncName + je FoundMatch + add di, SIZEOF sOemCallout + jmp loopThruTable + +FoundMatch: + mov bx, cs:[di].sOemCallout.FuncPtr + call bx + +amdCpuCalloutExit: + ret +AmdCalloutRouterPost ENDP + + +;---------------------------------------------------------------------------- +; Define the callout dispatch table for the POST segment +;---------------------------------------------------------------------------- + +CalloutRouterTablePost LABEL BYTE + ;; Add entries as desired. + sOemCallout <AGESA_ALLOCATE_BUFFER, OFFSET myAllocateBuffer> + sOemCallout <AGESA_DEALLOCATE_BUFFER, OFFSET myDeallocateBuffer> + sOemCallout <AGESA_LOCATE_BUFFER, OFFSET myLocateBuffer> + sOemCallout <AGESA_RUNFUNC_ONAP, OFFSET AmdRunFuncOnAp> +CalloutRouterTablePostEnd LABEL BYTE + +AMD_POST_END + + +;---------------------------------------------------------------------------- +; CPU DATA SEGMENT +; This segment must be writable, and present at the time that +; AmdInitLate is run. +;---------------------------------------------------------------------------- + +CPU_DATASEG_START + + ;; Data used to store pointers for later use by the host environment. + PUBLIC AmdAcpiSratPointer + PUBLIC AmdAcpiSratSize + PUBLIC AmdAcpiSlitPointer + PUBLIC AmdAcpiSlitSize + PUBLIC AmdAcpiSsdtPointer + PUBLIC AmdAcpiSsdtSize + PUBLIC AmdAcpiWheaMcePointer + PUBLIC AmdAcpiWheaMceSize + PUBLIC AmdAcpiWheaCmcPointer + PUBLIC AmdAcpiWheaCmcSize + PUBLIC AmdDmiInfoPointer + AmdAcpiSratPointer DWORD ? + AmdAcpiSratSize DWORD ? + AmdAcpiSlitPointer DWORD ? + AmdAcpiSlitSize DWORD ? + AmdAcpiSsdtPointer DWORD ? + AmdAcpiSsdtSize DWORD ? + AmdAcpiWheaMcePointer DWORD ? + AmdAcpiWheaMceSize DWORD ? + AmdAcpiWheaCmcPointer DWORD ? + AmdAcpiWheaCmcSize DWORD ? + AmdDmiInfoPointer DWORD ? + + ;; Data used for communication between the AP and the BSP. + PUBLIC AmdRunCodeOnApDataPointer + PUBLIC AmdRunCodeOnApDataSize + PUBLIC AmdRunCodeOnApFunction + PUBLIC AmdRunCodeOnApStatus + AmdRunCodeOnApDataPointer DWORD ? + AmdRunCodeOnApDataSize DWORD ? + AmdRunCodeOnApFunction DWORD ? + AmdRunCodeOnApStatus DWORD ? + +CPU_DATASEG_END + + +END |