summaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/f14/Legacy/Proc
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/agesa/f14/Legacy/Proc')
-rw-r--r--src/vendorcode/amd/agesa/f14/Legacy/Proc/Dispatcher.c161
-rw-r--r--src/vendorcode/amd/agesa/f14/Legacy/Proc/Legacy.bat286
-rw-r--r--src/vendorcode/amd/agesa/f14/Legacy/Proc/agesaCallouts.c397
-rw-r--r--src/vendorcode/amd/agesa/f14/Legacy/Proc/arch2008.asm2674
-rw-r--r--src/vendorcode/amd/agesa/f14/Legacy/Proc/hobTransfer.c394
5 files changed, 3912 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f14/Legacy/Proc/Dispatcher.c b/src/vendorcode/amd/agesa/f14/Legacy/Proc/Dispatcher.c
new file mode 100644
index 0000000000..fed63ed525
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f14/Legacy/Proc/Dispatcher.c
@@ -0,0 +1,161 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * AMD binary block interface
+ *
+ * Contains the block entry function dispatcher
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: Legacy
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ */
+/*
+ *****************************************************************************
+ *
+ * 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+#include "AGESA.h"
+#include "amdlib.h"
+#include "Dispatcher.h"
+#include "Options.h"
+#include "Filecode.h"
+CODE_GROUP (G1_PEICC)
+RDATA_GROUP (G1_PEICC)
+
+#define FILECODE LEGACY_PROC_DISPATCHER_FILECODE
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+extern CONST DISPATCH_TABLE DispatchTable[];
+extern AMD_MODULE_HEADER mCpuModuleID;
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * The Dispatcher is the entry point into the AGESA software. It takes a function
+ * number as entry parameter in order to invoke the published function
+ *
+ * @param[in,out] ConfigPtr
+ *
+ * @return AGESA Status.
+ *
+ */
+AGESA_STATUS
+CALLCONV
+AmdAgesaDispatcher (
+ IN OUT VOID *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ IMAGE_ENTRY ImageEntry;
+ MODULE_ENTRY ModuleEntry;
+ DISPATCH_TABLE *Entry;
+ UINT32 ImageStart;
+ UINT32 ImageEnd;
+ AMD_IMAGE_HEADER* AltImagePtr;
+
+ Status = AGESA_UNSUPPORTED;
+ ImageEntry = NULL;
+ ModuleEntry = NULL;
+ ImageStart = 0xFFF00000;
+ ImageEnd = 0xFFFFFFFF;
+ AltImagePtr = NULL;
+
+ Entry = (DISPATCH_TABLE *) DispatchTable;
+ while (Entry->FunctionId != 0) {
+ if ((((AMD_CONFIG_PARAMS *) ConfigPtr)->Func) == Entry->FunctionId) {
+ Status = Entry->EntryPoint (ConfigPtr);
+ break;
+ }
+ Entry++;
+ }
+
+ // 2. Try next dispatcher if possible, and we have not already got status back
+ if ((mCpuModuleID.NextBlock != NULL) && (Status == AGESA_UNSUPPORTED)) {
+ ModuleEntry = (MODULE_ENTRY) (UINT64) mCpuModuleID.NextBlock->ModuleDispatcher;
+ if (ModuleEntry != NULL) {
+ Status = (*ModuleEntry) (ConfigPtr);
+ }
+ }
+
+ // 3. If not this image specific function, see if we can find alternative image instead
+ if (Status == AGESA_UNSUPPORTED) {
+ if ((((AMD_CONFIG_PARAMS *)ConfigPtr)->AltImageBasePtr != 0xFFFFFFFF ) || (((AMD_CONFIG_PARAMS *)ConfigPtr)->AltImageBasePtr != 0)) {
+ ImageStart = ((AMD_CONFIG_PARAMS *)ConfigPtr)->AltImageBasePtr;
+ ImageEnd = ImageStart + 4;
+ // Locate/test image base that matches this component
+ AltImagePtr = LibAmdLocateImage ((VOID *) (UINT64)ImageStart, (VOID *) (UINT64)ImageEnd, 4096, AGESA_ID);
+ if (AltImagePtr != NULL) {
+ //Invoke alternative Image
+ ImageEntry = (IMAGE_ENTRY) ((UINT64) AltImagePtr + AltImagePtr->EntryPointAddress);
+ Status = (*ImageEntry) (ConfigPtr);
+ }
+ }
+ }
+
+ return (Status);
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * The host environment interface of callout.
+ *
+ * @param[in] Func
+ * @param[in] Data
+ * @param[in,out] ConfigPtr
+ *
+ * @return The AGESA Status returned from the callout.
+ *
+ */
+AGESA_STATUS
+CALLCONV
+AmdAgesaCallout (
+ IN UINT32 Func,
+ IN UINT32 Data,
+ IN OUT VOID *ConfigPtr
+ )
+{
+ UINT32 Result;
+ Result = AGESA_UNSUPPORTED;
+ if (((AMD_CONFIG_PARAMS *) ConfigPtr)->CalloutPtr == NULL) {
+ return Result;
+ }
+
+ Result = (((AMD_CONFIG_PARAMS *) ConfigPtr)->CalloutPtr) (Func, Data, ConfigPtr);
+ return (Result);
+}
diff --git a/src/vendorcode/amd/agesa/f14/Legacy/Proc/Legacy.bat b/src/vendorcode/amd/agesa/f14/Legacy/Proc/Legacy.bat
new file mode 100644
index 0000000000..0b79a987c1
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f14/Legacy/Proc/Legacy.bat
@@ -0,0 +1,286 @@
+@echo off
+echo *****************************************************************************
+echo *
+echo * Copyright (c) 2011, Advanced Micro Devices, Inc.
+echo * All rights reserved.
+echo *
+echo * Redistribution and use in source and binary forms, with or without
+echo * modification, are permitted provided that the following conditions are met:
+echo * * Redistributions of source code must retain the above copyright
+echo * notice, this list of conditions and the following disclaimer.
+echo * * Redistributions in binary form must reproduce the above copyright
+echo * notice, this list of conditions and the following disclaimer in the
+echo * documentation and/or other materials provided with the distribution.
+echo * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+echo * its contributors may be used to endorse or promote products derived
+echo * from this software without specific prior written permission.
+echo *
+echo * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+echo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+echo * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+echo * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+echo * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+echo * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+echo * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+echo * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+echo * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+echo * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+echo *
+echo * ***************************************************************************
+
+
+goto Begin
+:Documentation
+echo off
+echo **************************************************************************
+echo * Legacy.Bat
+echo * This batchfile establishes the build environment for an AGESA(TM)
+echo * legacy build.
+echo *
+echo * Syntax:
+echo * Legacy.bat Solution [DevTipPath] [DevKey] [DoxKey] [Release^|Debug] [Internal]
+echo * Parameters:
+echo * %% 1 Solution name. This is the AMD Platform Solution name that
+echo * identifies the delivery package. No default, this
+echo * parameter MUST be specified. This parameter MUST
+echo * be specified before the DevTip Path parameter.
+echo * %% 2 Path to the platform specific build directory. This is
+echo * where the options file %%Solution%%Options.c is located,
+echo * which contains the platform specific build option settings.
+echo * If left blank, the default %%Solution%%Options.c file from
+echo * the AGESA\Addendum directory is used.
+echo * %% 3 Developer's key - open an interactive MSVS window. This parameter is
+echo * optional, but when used it requires the first two parameters.
+echo * %% 4 Documentation Key - requests a compilation of the DOxygen
+echo * documentation files. key is "DOX". This parameter is
+echo * optional, but when used it requires the first two parameters.
+echo * %% 5 Build Configuration. There are two choices, "Release" and "Debug".
+echo * Debug is the default choice if not specified. This parameter is
+echo * optional, but when used it requires the first two parameters.
+echo * %% 6 Internal solution file select - choose a internal solution file.This parameter
+echo * is optional, but when used it requires the first two parameters.
+echo * NOTE: The paths MUST have a trailing '\' character.
+echo *
+echo * The AGESA build environment requires the following environment
+echo * variables MUST be defined for proper operation:
+echo * $(AGESA_ROOT) - identifies the directory where the AGESA code
+echo * is located. The top most dir; where AGESA.h is located.
+echo * This must be the full path, eg D:\myPlatform\AGESA\
+echo * **** This var is expected to be set by the caller ****
+echo *
+echo * $(Solution) - identifies the Platform Solution being targeted
+echo * $(AGESA_OptsDir) - identifies the directory where the platform
+echo * options and customization files are located.
+echo * This must be the full path
+echo *
+echo * Optional build environment variables
+echo *
+echo * set AGESA_B1_ADDRESS=0xFFF?????
+echo * Sets the B1 image base address in the ROM (otherwise 0xFFFD0000).
+echo * set AGESA_B2_ADDRESS=0xFFF?????
+echo * Sets the B2 image base address in the ROM (otherwise 0xFFFA0000).
+echo *
+echo * NOTE: The paths MUST have a trailing '\' character.
+echo **************************************************************************
+goto Exit
+
+:Begin
+rem Clear working vars...
+set DevKey=
+set DoxKey=
+set Solution=
+set Configuration=
+
+rem set default to external file prefix none
+set SolutionType=
+
+rem Validate the AGESA_ROOT variable
+IF "%AGESA_ROOT%"=="" goto Else001
+ rem User has set a path for Agesa_Root, verify that path...
+ IF EXIST %AGESA_ROOT%Agesa.h goto EndIf002
+ rem Try adding trailing '\'
+ set AGESA_ROOT=%AGESA_ROOT%\
+ IF EXIST %AGESA_ROOT%Agesa.h goto EndIf003
+ echo Build ERROR: Environment variable AGESA_ROOT is invalid,
+ echo Build ERROR: Could not find file Agesa.h at: %AGESA_ROOT%
+ pause
+ goto Documentation
+ :EndIf003
+ :EndIf002
+ goto EndIf001
+:Else001
+ echo Build ERROR: Required environment variable missing: AGESA_ROOT
+ pause
+ goto Documentation
+:EndIf001
+
+rem Start processing the input parameters...
+:DoLoop
+ rem Switch (%1)
+ IF /I "%1"=="DevKey" goto Case001
+ IF /I "%1"=="Maranello" goto Case002
+ IF /I "%1"=="DevTest" goto Case002
+ IF /I "%1"=="Danube" goto Case002
+ IF /I "%1"=="DanNi" goto Case002
+ IF /I "%1"=="Nile" goto Case002
+ IF /I "%1"=="Dragon" goto Case002
+ IF /I "%1"=="SanMarino" goto Case002
+ IF /I "%1"=="Scorpius" goto Case002
+ IF /I "%1"=="Sabine" goto Case002
+ IF /I "%1"=="Lynx" goto Case002
+ IF /I "%1"=="Brazos" goto Case002
+ IF /I "%1"=="DOX" goto Case009
+ IF /I "%1"=="Debug" goto Case011
+ IF /I "%1"=="Release" goto Case011
+ IF /I "%1"=="Internal" goto Case012
+ IF "%1"=="" goto Case006
+ goto Case004
+ :Case001
+ rem Case 1: Special command param
+ set DevKey=DevKey
+ goto EndSwitch
+ :Case002
+ rem Case 2: Solution name parameter
+ rem Set the Platform Solution name for the build environment
+ rem Validation of the names was done by the IF's at the top of DoLoop
+ set Solution=%1
+ goto EndSwitch
+ :Case004
+ rem Case 4: Path param, check for validity
+ rem Check if parameter matches the default
+ rem Check for shortcut versions of the default. Also
+ rem checking for missing trailing '\'
+ IF /I "%1"=="Addendum" goto Then040
+ IF /I "%1"=="Addendum\" goto Then040
+ IF /I "%1"=="..\Addendum" goto Then040
+ IF /I "%1"=="..\Addendum\" goto Then040
+ IF /I "%1"=="..\..\Addendum" goto Then040
+ IF /I "%1"=="..\..\Addendum\" goto Then040
+ goto Else040
+ :Then040
+ set AGESA_OptsDir=%AGESA_ROOT%Addendum\
+ Echo Build WARNING: User selected the default options path.
+ goto EndIf040
+ :Else040
+ set AGESA_OptsDir=%1
+ rem Non-default path given,
+ rem Validate the AGESA_OptsDir parameter ( %%1 = %1 )...
+ IF /I "%Solution%"=="" goto Else042
+ IF EXIST %AGESA_OptsDir%%Solution%Options.c goto EndIf044
+ rem Check if param was missing trailing '\'...
+ set AGESA_OptsDir=%AGESA_OptsDir%\
+ IF EXIST %AGESA_OptsDir%%Solution%Options.c goto EndIf045
+ rem If using the default, assume the release file is in place.
+ rem Could not find options file, post an error
+ Echo Build ERROR: Path to AGESA options file is not valid...
+ Echo . . Could not find options file: %AGESA_OptsDir%%Solution%Options.c
+ set AGESA_OptsDir=
+ set Solution=
+ exit /B 5
+ :EndIf045
+ :EndIf044
+ goto EndIf042
+ :Else042
+ rem Else042 - parameter ordering error, need to specify solution before tip path
+ Echo Build ERROR: The 'Solution' name was not recognized or
+ Echo The Solution must be specified before the Development tip path
+ Echo . . . Legacy.bat Solution [DevTipPath] [DevKey] [DoxKey]
+ exit /B 4
+ :EndIf042
+ :EndIf040
+ goto EndSwitch
+ :Case006
+ rem Case 6: Parameter is blank, end of list
+ rem Validate the required Environment Variables
+ IF /I "%Solution%"=="" goto Else066
+ IF NOT "%AGESA_OptsDir%"=="" goto Else060
+ Rem No path param specified. Use the default file shipped with the AGESA package...
+ Echo Build WARNING: Using default options file.
+ set AGESA_OptsDir=%AGESA_ROOT%Addendum\
+ goto EndIf060
+ :Else060
+ rem Else060 - tip path may have been set by caller prior to call,
+ rem Validate the AGESA_OptsDir parameter ( %%AGESA_OptsDir = %AGESA_OptsDir% )...
+ IF EXIST %AGESA_OptsDir%%Solution%Options.c goto EndIf061
+ rem Check if param was missing trailing '\'...
+ set AGESA_OptsDir=%AGESA_OptsDir%\
+ IF EXIST %AGESA_OptsDir%%Solution%Options.c goto EndIf062
+ rem If using the default, assume the release file is in place.
+ rem Could not find options file, post an error
+ Echo Build ERROR: Path to AGESA options file is not valid...
+ Echo . . Could not find options file: %AGESA_OptsDir%%Solution%Options.c
+ set AGESA_OptsDir=
+ set Solution=
+ exit /B 4
+ :EndIf062
+ :EndIf061
+ :EndIf060
+ goto EndIf066
+ :Else066
+ rem Else066 - parameter missing error, need to specify 'solution'
+ Echo Build ERROR: The Platform Solution name must be specified:
+ Echo . . . Legacy.bat Solution [DevTipPath] [DevKey] [DoxKey]
+ exit /B 4
+ :EndIf066
+ goto EndDo
+ :Case009
+ rem Case 9: Documentation generation key
+ set DoxKey=DoxKey
+ goto EndSwitch
+ :Case011
+ rem Case 11: Build Configuration
+ set Configuration=%1
+ goto EndSwitch
+ :Case012
+ rem Case 12: Select Internal solution file prefix
+ set SolutionType=%1
+ goto EndSwitch
+ :EndSwitch
+ SHIFT
+ goto DoLoop
+:EndDo
+
+rem # Ensure that Microsoft Visual Studio 2005 is installed on this machine.
+IF NOT "%VS80COMNTOOLS%"=="" goto EndIf95
+echo ---------------------------------------------------------------------
+echo - Building AGESA ARCH2008 requires Microsoft Visual Studio 2005 -
+echo - Install Visual Studio 2005 and confirm environment -
+echo - variable VS80COMNTOOLS is present. -
+echo ---------------------------------------------------------------------
+pause
+exit
+:EndIf95
+
+rem set the Visual Studio 32-bit development environment
+call "%VS80COMNTOOLS%vsvars32.bat"
+
+rem Launch the documentation generator if selected by the user
+IF NOT "%DoxKey%"=="DoxKey" goto EndIf100
+ devenv %AGESA_ROOT%Proc\AgesaDoc.sln /Rebuild "Release|Win32"
+:EndIf100
+
+rem Use the default build configuration if none was specified.
+IF NOT "%Configuration%"=="" goto EndIf110
+ set Configuration=Debug
+:EndIf110
+
+rem Check image bases
+IF NOT "%AGESA_B1_ADDRESS%"=="" goto EndIf120
+ set AGESA_B1_ADDRESS=0xFFFD0000
+:EndIf120
+IF NOT "%AGESA_B2_ADDRESS%"=="" goto EndIf130
+ set AGESA_B2_ADDRESS=0xFFFA0000
+:EndIf130
+
+rem Check if the 'secret' developers' key was used, open an interactive VS window
+IF NOT "%DevKey%"=="DevKey" goto Else140
+ set DevKey=
+ rem This is the command to open an interactive development window ...
+ start /NORMAL devenv.exe %AGESA_ROOT%Legacy\Proc\%Solution%%SolutionType%Legacy.sln /ProjectConfig "%Configuration%|Win32"
+ goto EndIf140
+:Else140
+ rem Else140 - This is the command to perform a background or automated build ...
+ devenv %AGESA_ROOT%Legacy\Proc\%Solution%%SolutionType%Legacy.sln /Rebuild "%Configuration%|Win32"
+:EndIf140
+:Exit
+exit /B 0
diff --git a/src/vendorcode/amd/agesa/f14/Legacy/Proc/agesaCallouts.c b/src/vendorcode/amd/agesa/f14/Legacy/Proc/agesaCallouts.c
new file mode 100644
index 0000000000..ffb712ef0b
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f14/Legacy/Proc/agesaCallouts.c
@@ -0,0 +1,397 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * AMD CPU AGESA Callout Functions
+ *
+ * Contains code to set / get useful platform information.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: Common
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ */
+/*
+ *****************************************************************************
+ *
+ * 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+#include "AGESA.h"
+#include "cpuRegisters.h"
+#include "Dispatcher.h"
+#include "cpuServices.h"
+#include "Ids.h"
+#include "Filecode.h"
+
+#define FILECODE LEGACY_PROC_AGESACALLOUTS_FILECODE
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S - (AGESA ONLY)
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ *
+ * Call the host environment interface to do the warm or cold reset.
+ *
+ * @param[in] ResetType Warm or Cold Reset is requested
+ * @param[in,out] StdHeader Config header
+ *
+ */
+VOID
+AgesaDoReset (
+ IN UINTN ResetType,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ AGESA_STATUS Status;
+ WARM_RESET_REQUEST Request;
+
+ // Clear warm request bit and set state bits to the current post stage
+ GetWarmResetFlag (StdHeader, &Request);
+ Request.RequestBit = FALSE;
+ Request.StateBits = Request.PostStage;
+ SetWarmResetFlag (StdHeader, &Request);
+
+ Status = AmdAgesaCallout (AGESA_DO_RESET, (UINT32)ResetType, (VOID *) StdHeader);
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ *
+ * Call the host environment interface to allocate buffer in main system memory.
+ *
+ * @param[in] FcnData
+ * @param[in,out] AllocParams Heap manager parameters
+ *
+ * @return The AGESA Status returned from the callout.
+ *
+ */
+AGESA_STATUS
+AgesaAllocateBuffer (
+ IN UINTN FcnData,
+ IN OUT AGESA_BUFFER_PARAMS *AllocParams
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = AmdAgesaCallout (AGESA_ALLOCATE_BUFFER, (UINT32)FcnData, (VOID *) AllocParams);
+
+ return Status;
+}
+
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Call the host environment interface to deallocate buffer in main system memory.
+ *
+ * @param[in] FcnData
+ * @param[in,out] DeallocParams Heap Manager parameters
+ *
+ * @return The AGESA Status returned from the callout.
+ */
+AGESA_STATUS
+AgesaDeallocateBuffer (
+ IN UINTN FcnData,
+ IN OUT AGESA_BUFFER_PARAMS *DeallocParams
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = AmdAgesaCallout (AGESA_DEALLOCATE_BUFFER, (UINT32)FcnData, (VOID *) DeallocParams);
+
+ return Status;
+}
+
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ *
+ * Call the host environment interface to Locate buffer Pointer in main system memory
+ *
+ * @param[in] FcnData
+ * @param[in,out] LocateParams Heap manager parameters
+ *
+ * @return The AGESA Status returned from the callout.
+ *
+ */
+AGESA_STATUS
+AgesaLocateBuffer (
+ IN UINTN FcnData,
+ IN OUT AGESA_BUFFER_PARAMS *LocateParams
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = AmdAgesaCallout (AGESA_LOCATE_BUFFER, (UINT32)FcnData, (VOID *) LocateParams);
+
+ return Status;
+}
+
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Call the host environment interface to launch APs
+ *
+ * @param[in] ApicIdOfCore
+ * @param[in,out] LaunchApParams
+ *
+ * @return The AGESA Status returned from the callout.
+ *
+ */
+AGESA_STATUS
+AgesaRunFcnOnAp (
+ IN UINTN ApicIdOfCore,
+ IN AP_EXE_PARAMS *LaunchApParams
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = AmdAgesaCallout (AGESA_RUNFUNC_ONAP, (UINT32)ApicIdOfCore, (VOID *) LaunchApParams);
+
+ return Status;
+}
+
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Call the host environment interface to read an SPD's content.
+ *
+ * @param[in] FcnData
+ * @param[in,out] ReadSpd
+ *
+ * @return The AGESA Status returned from the callout.
+ *
+ */
+AGESA_STATUS
+AgesaReadSpd (
+ IN UINTN FcnData,
+ IN OUT AGESA_READ_SPD_PARAMS *ReadSpd
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = AmdAgesaCallout (AGESA_READ_SPD, (UINT32)FcnData, ReadSpd);
+
+ return Status;
+}
+
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Call the host environment interface to read an SPD's content.
+ *
+ * @param[in] FcnData
+ * @param[in,out] ReadSpd
+ *
+ * @return The AGESA Status returned from the callout.
+ *
+ */
+AGESA_STATUS
+AgesaReadSpdRecovery (
+ IN UINTN FcnData,
+ IN OUT AGESA_READ_SPD_PARAMS *ReadSpd
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = AmdAgesaCallout (AGESA_READ_SPD_RECOVERY, (UINT32)FcnData, ReadSpd);
+
+ return Status;
+}
+
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Call the host environment interface to provide a user hook opportunity.
+ *
+ * @param[in] FcnData
+ * @param[in,out] MemData
+ *
+ * @return The AGESA Status returned from the callout.
+ *
+ */
+AGESA_STATUS
+AgesaHookBeforeDramInitRecovery (
+ IN UINTN FcnData,
+ IN OUT MEM_DATA_STRUCT *MemData
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = AmdAgesaCallout (AGESA_HOOKBEFORE_DRAM_INIT_RECOVERY, (UINT32)FcnData, MemData);
+
+ return Status;
+}
+
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Call the host environment interface to provide a user hook opportunity.
+ *
+ * @param[in] FcnData
+ * @param[in,out] MemData
+ *
+ * @return The AGESA Status returned from the callout.
+ *
+ */
+AGESA_STATUS
+AgesaHookBeforeDramInit (
+ IN UINTN FcnData,
+ IN OUT MEM_DATA_STRUCT *MemData
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = AmdAgesaCallout (AGESA_HOOKBEFORE_DRAM_INIT, (UINT32)FcnData, MemData);
+
+ return Status;
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Call the host environment interface to provide a user hook opportunity.
+ *
+ * @param[in] FcnData
+ * @param[in,out] MemData
+ *
+ * @return The AGESA Status returned from the callout.
+ *
+ */
+AGESA_STATUS
+AgesaHookBeforeDQSTraining (
+ IN UINTN FcnData,
+ IN OUT MEM_DATA_STRUCT *MemData
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = AmdAgesaCallout (AGESA_HOOKBEFORE_DQS_TRAINING, (UINT32)FcnData, MemData);
+
+ return Status;
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Call the host environment interface to provide a user hook opportunity.
+ *
+ * @param[in] FcnData
+ * @param[in,out] MemData
+ *
+ * @return The AGESA Status returned from the callout.
+ *
+ */
+AGESA_STATUS
+AgesaHookBeforeExitSelfRefresh (
+ IN UINTN FcnData,
+ IN OUT MEM_DATA_STRUCT *MemData
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = AmdAgesaCallout (AGESA_HOOKBEFORE_EXIT_SELF_REF, (UINT32)FcnData, MemData);
+
+ return Status;
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Call the host environment interface to provide a user hook opportunity.
+ *
+ * @param[in] Data
+ * @param[in,out] IdsCalloutData
+ *
+ * @return The AGESA Status returned from the callout.
+ *
+ */
+
+
+AGESA_STATUS
+AgesaGetIdsData (
+ IN UINTN Data,
+ IN OUT IDS_CALLOUT_STRUCT *IdsCalloutData
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = AmdAgesaCallout (AGESA_GET_IDS_INIT_DATA, (UINT32)Data, IdsCalloutData);
+
+ return Status;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * PCIE slot reset control
+ *
+ *
+ *
+ * @param[in] FcnData Function data
+ * @param[in] ResetInfo Reset information
+ * @retval Status Agesa status
+ */
+
+AGESA_STATUS
+AgesaPcieSlotResetControl (
+ IN UINTN FcnData,
+ IN PCIe_SLOT_RESET_INFO *ResetInfo
+ )
+{
+ AGESA_STATUS Status;
+ Status = AmdAgesaCallout (AGESA_GNB_PCIE_SLOT_RESET, (UINT32) FcnData, ResetInfo);
+ return Status;
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/f14/Legacy/Proc/arch2008.asm b/src/vendorcode/amd/agesa/f14/Legacy/Proc/arch2008.asm
new file mode 100644
index 0000000000..d30790621c
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f14/Legacy/Proc/arch2008.asm
@@ -0,0 +1,2674 @@
+;*****************************************************************************
+; AMD Generic Encapsulated Software Architecture
+;
+; Workfile: arch2008.asm $Revision: 37157 $ $Date: 2010-09-01 03:24:07 +0800 (Wed, 01 Sep 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 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
diff --git a/src/vendorcode/amd/agesa/f14/Legacy/Proc/hobTransfer.c b/src/vendorcode/amd/agesa/f14/Legacy/Proc/hobTransfer.c
new file mode 100644
index 0000000000..d205b5488c
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f14/Legacy/Proc/hobTransfer.c
@@ -0,0 +1,394 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * AMD Hob Transfer functions.
+ *
+ * Contains code that copy Heap to temp memory or main memory.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: CPU
+ * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
+ *
+ */
+/*
+ *****************************************************************************
+ *
+ * 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "AGESA.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "cpuRegisters.h"
+#include "GeneralServices.h"
+#include "cpuServices.h"
+#include "cpuCacheInit.h"
+#include "cpuFamilyTranslation.h"
+#include "heapManager.h"
+#include "cpuLateInit.h"
+#include "Filecode.h"
+CODE_GROUP (G1_PEICC)
+RDATA_GROUP (G1_PEICC)
+
+#define FILECODE LEGACY_PROC_HOBTRANSFER_FILECODE
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P U B L I C F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+extern BUILD_OPT_CFG UserOptions;
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * CopyHeapToTempRamAtPost
+ *
+ * This function copies BSP heap content to RAM
+ *
+ * @param[in,out] StdHeader - Pointer to AMD_CONFIG_PARAMS struct.
+ *
+ * @retval AGESA_STATUS
+ *
+ */
+AGESA_STATUS
+CopyHeapToTempRamAtPost (
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT8 *BaseAddressInCache;
+ UINT8 *BaseAddressInTempMem;
+ UINT8 *Source;
+ UINT8 *Destination;
+ UINT8 AlignTo16ByteInCache;
+ UINT8 AlignTo16ByteInTempMem;
+ UINT8 Ignored;
+ UINT32 SizeOfNodeData;
+ UINT32 TotalSize;
+ UINT32 HeapRamFixMtrr;
+ UINT32 HeapRamVariableMtrr;
+ UINT32 HeapInCacheOffset;
+ UINT64 MsrData;
+ UINT64 VariableMtrrBase;
+ UINT64 VariableMtrrMask;
+ UINTN AmdHeapRamAddress;
+ AGESA_STATUS IgnoredStatus;
+ BUFFER_NODE *HeapInCache;
+ BUFFER_NODE *HeapInTempMem;
+ HEAP_MANAGER *HeapManagerInCache;
+ HEAP_MANAGER *HeapManagerInTempMem;
+ CACHE_INFO *CacheInfoPtr;
+ CPU_SPECIFIC_SERVICES *FamilySpecificServices;
+
+ AmdHeapRamAddress = (UINTN) UserOptions.CfgHeapDramAddress;
+ //
+ //If the user define address above 1M, Mem Init has already set
+ //whole available memory as WB cacheable.
+ //
+ if (AmdHeapRamAddress < 0x100000) {
+ // Region below 1MB
+ // Fixed MTTR region
+ // turn on modification bit
+ LibAmdMsrRead (MSR_SYS_CFG, &MsrData, StdHeader);
+ MsrData |= 0x80000;
+ LibAmdMsrWrite (MSR_SYS_CFG, &MsrData, StdHeader);
+
+ if (AmdHeapRamAddress >= 0xC0000) {
+ //
+ // 0xC0000 ~ 0xFFFFF
+ //
+ HeapRamFixMtrr = (UINT32) (AMD_MTRR_FIX4k_C0000 + (((AmdHeapRamAddress >> 16) & 0x3) * 2));
+ MsrData = AMD_MTRR_FIX4K_UC_DRAM;
+ LibAmdMsrWrite (HeapRamFixMtrr, &MsrData, StdHeader);
+ LibAmdMsrWrite ((HeapRamFixMtrr + 1), &MsrData, StdHeader);
+ } else if (AmdHeapRamAddress >= 0x80000) {
+ //
+ // 0x80000~0xBFFFF
+ //
+ HeapRamFixMtrr = (UINT32) (AMD_MTRR_FIX16k_80000 + ((AmdHeapRamAddress >> 17) & 0x1));
+ MsrData = AMD_MTRR_FIX16K_UC_DRAM;
+ LibAmdMsrWrite (HeapRamFixMtrr, &MsrData, StdHeader);
+ } else {
+ //
+ // 0x0 ~ 0x7FFFF
+ //
+ LibAmdMsrRead (AMD_MTRR_FIX64k_00000, &MsrData, StdHeader);
+ MsrData = MsrData & (~(0xFF << (8 * ((AmdHeapRamAddress >> 16) & 0x7))));
+ MsrData = MsrData | (AMD_MTRR_FIX64K_UC_DRAM << (8 * ((AmdHeapRamAddress >> 16) & 0x7)));
+ LibAmdMsrWrite (AMD_MTRR_FIX64k_00000, &MsrData, StdHeader);
+ }
+
+ // Turn on MTTR enable bit and turn off modification bit
+ LibAmdMsrRead (MSR_SYS_CFG, &MsrData, StdHeader);
+ MsrData |= 0x40000;
+ MsrData &= 0xFFFFFFFFFFF7FFFF;
+ LibAmdMsrWrite (MSR_SYS_CFG, &MsrData, StdHeader);
+ } else {
+ // Region above 1MB
+ // Variable MTTR region
+ // Get family specific cache Info
+ GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
+ FamilySpecificServices->GetCacheInfo (FamilySpecificServices, &CacheInfoPtr, &Ignored, StdHeader);
+
+ // Find an empty MTRRphysBase/MTRRphysMask
+ for (HeapRamVariableMtrr = AMD_MTRR_VARIABLE_HEAP_BASE;
+ HeapRamVariableMtrr >= AMD_MTRR_VARIABLE_BASE0;
+ HeapRamVariableMtrr--) {
+ LibAmdMsrRead (HeapRamVariableMtrr, &VariableMtrrBase, StdHeader);
+ LibAmdMsrRead ((HeapRamVariableMtrr + 1), &VariableMtrrMask, StdHeader);
+ if ((VariableMtrrBase == 0) && (VariableMtrrMask == 0)) {
+ break;
+ }
+ }
+ if (HeapRamVariableMtrr < AMD_MTRR_VARIABLE_BASE0) {
+ // All variable MTRR is used.
+ ASSERT (FALSE);
+ }
+
+ // Set variable MTRR base and mask
+ // If the address ranges of two or more MTRRs overlap
+ // and if at least one of the memory types is UC, the UC memory type is used.
+ VariableMtrrBase = (UINT64) (AmdHeapRamAddress & CacheInfoPtr->HeapBaseMask);
+ VariableMtrrMask = CacheInfoPtr->VariableMtrrHeapMask & AMD_HEAP_MTRR_MASK;
+ LibAmdMsrWrite (HeapRamVariableMtrr, &VariableMtrrBase, StdHeader);
+ LibAmdMsrWrite ((HeapRamVariableMtrr + 1), &VariableMtrrMask, StdHeader);
+ }
+ // Copying Heap content
+ if (IsBsp (StdHeader, &IgnoredStatus)) {
+ TotalSize = sizeof (HEAP_MANAGER);
+ SizeOfNodeData = 0;
+ AlignTo16ByteInTempMem = 0;
+ BaseAddressInCache = (UINT8 *) StdHeader->HeapBasePtr;
+ HeapManagerInCache = (HEAP_MANAGER *) BaseAddressInCache;
+ HeapInCacheOffset = HeapManagerInCache->FirstActiveBufferOffset;
+ HeapInCache = (BUFFER_NODE *) (BaseAddressInCache + HeapInCacheOffset);
+
+ BaseAddressInTempMem = (UINT8 *) UserOptions.CfgHeapDramAddress;
+ HeapManagerInTempMem = (HEAP_MANAGER *) BaseAddressInTempMem;
+ HeapInTempMem = (BUFFER_NODE *) (BaseAddressInTempMem + TotalSize);
+
+ // copy heap from cache to temp memory.
+ // only heap with persist great than HEAP_LOCAL_CACHE will be copied.
+ // Note: Only copy heap with persist greater than HEAP_LOCAL_CACHE.
+ while (HeapInCacheOffset != AMD_HEAP_INVALID_HEAP_OFFSET) {
+ if (HeapInCache->Persist > HEAP_LOCAL_CACHE) {
+ AlignTo16ByteInCache = HeapInCache->PadSize;
+ AlignTo16ByteInTempMem = (UINT8) ((0x10 - (((UINTN) (VOID *) HeapInTempMem + sizeof (BUFFER_NODE) + SIZE_OF_SENTINEL) & 0xF)) & 0xF);
+ SizeOfNodeData = HeapInCache->BufferSize - AlignTo16ByteInCache;
+ TotalSize = (UINT32) (TotalSize + sizeof (BUFFER_NODE) + SizeOfNodeData + AlignTo16ByteInTempMem);
+ Source = (UINT8 *) HeapInCache + sizeof (BUFFER_NODE) + AlignTo16ByteInCache;
+ Destination = (UINT8 *) HeapInTempMem + sizeof (BUFFER_NODE) + AlignTo16ByteInTempMem;
+ LibAmdMemCopy (HeapInTempMem, HeapInCache, sizeof (BUFFER_NODE), StdHeader);
+ LibAmdMemCopy (Destination, Source, SizeOfNodeData, StdHeader);
+ HeapInTempMem->OffsetOfNextNode = TotalSize;
+ HeapInTempMem->BufferSize = SizeOfNodeData + AlignTo16ByteInTempMem;
+ HeapInTempMem->PadSize = AlignTo16ByteInTempMem;
+ HeapInTempMem = (BUFFER_NODE *) (BaseAddressInTempMem + TotalSize);
+ }
+ HeapInCacheOffset = HeapInCache->OffsetOfNextNode;
+ HeapInCache = (BUFFER_NODE *) (BaseAddressInCache + HeapInCacheOffset);
+ }
+ // initialize heap manager
+ if (TotalSize == sizeof (HEAP_MANAGER)) {
+ // heap is empty
+ HeapManagerInTempMem->UsedSize = sizeof (HEAP_MANAGER);
+ HeapManagerInTempMem->FirstActiveBufferOffset = AMD_HEAP_INVALID_HEAP_OFFSET;
+ HeapManagerInTempMem->FirstFreeSpaceOffset = sizeof (HEAP_MANAGER);
+ } else {
+ // heap is NOT empty
+ HeapManagerInTempMem->UsedSize = TotalSize;
+ HeapManagerInTempMem->FirstActiveBufferOffset = sizeof (HEAP_MANAGER);
+ HeapManagerInTempMem->FirstFreeSpaceOffset = TotalSize;
+ HeapInTempMem = (BUFFER_NODE *) (BaseAddressInTempMem + TotalSize - SizeOfNodeData - AlignTo16ByteInTempMem - sizeof (BUFFER_NODE));
+ HeapInTempMem->OffsetOfNextNode = AMD_HEAP_INVALID_HEAP_OFFSET;
+ HeapInTempMem = (BUFFER_NODE *) (BaseAddressInTempMem + TotalSize);
+ }
+ // heap signature
+ HeapManagerInCache->Signature = 0x00000000;
+ HeapManagerInTempMem->Signature = HEAP_SIGNATURE_VALID;
+ // Free space node
+ HeapInTempMem->BufferSize = (UINT32) (AMD_HEAP_SIZE_PER_CORE - TotalSize);
+ HeapInTempMem->OffsetOfNextNode = AMD_HEAP_INVALID_HEAP_OFFSET;
+ }
+ return AGESA_SUCCESS;
+}
+
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * CopyHeapToMainRamAtPost
+ *
+ * This function copies Temp Ram heap content to Main Ram
+ *
+ * @param[in,out] StdHeader - Pointer to AMD_CONFIG_PARAMS struct.
+ *
+ * @retval AGESA_STATUS
+ *
+ */
+AGESA_STATUS
+CopyHeapToMainRamAtPost (
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT8 *BaseAddressInTempMem;
+ UINT8 *BaseAddressInMainMem;
+ UINT8 *Source;
+ UINT8 *Destination;
+ UINT8 AlignTo16ByteInTempMem;
+ UINT8 AlignTo16ByteInMainMem;
+ UINT8 Ignored;
+ UINT32 SizeOfNodeData;
+ UINT32 TotalSize;
+ UINT32 HeapInTempMemOffset;
+ UINT32 HeapRamVariableMtrr;
+ UINT64 VariableMtrrBase;
+ UINT64 VariableMtrrMask;
+ AGESA_STATUS IgnoredStatus;
+ BUFFER_NODE *HeapInTempMem;
+ BUFFER_NODE *HeapInMainMem;
+ HEAP_MANAGER *HeapManagerInTempMem;
+ HEAP_MANAGER *HeapManagerInMainMem;
+ AGESA_BUFFER_PARAMS AgesaBuffer;
+ CACHE_INFO *CacheInfoPtr;
+ CPU_SPECIFIC_SERVICES *FamilySpecificServices;
+
+ if (IsBsp (StdHeader, &IgnoredStatus)) {
+ TotalSize = sizeof (HEAP_MANAGER);
+ SizeOfNodeData = 0;
+ AlignTo16ByteInMainMem = 0;
+ BaseAddressInTempMem = (UINT8 *) StdHeader->HeapBasePtr;
+ HeapManagerInTempMem = (HEAP_MANAGER *) StdHeader->HeapBasePtr;
+ HeapInTempMemOffset = HeapManagerInTempMem->FirstActiveBufferOffset;
+ HeapInTempMem = (BUFFER_NODE *) (BaseAddressInTempMem + HeapInTempMemOffset);
+
+ AgesaBuffer.StdHeader = *StdHeader;
+ AgesaBuffer.BufferHandle = AMD_HEAP_IN_MAIN_MEMORY_HANDLE;
+ AgesaBuffer.BufferLength = AMD_HEAP_SIZE_PER_CORE;
+ if (AgesaAllocateBuffer (0, &AgesaBuffer) != AGESA_SUCCESS) {
+ return AGESA_ERROR;
+ }
+ BaseAddressInMainMem = (UINT8 *) AgesaBuffer.BufferPointer;
+ HeapManagerInMainMem = (HEAP_MANAGER *) BaseAddressInMainMem;
+ HeapInMainMem = (BUFFER_NODE *) (BaseAddressInMainMem + TotalSize);
+ LibAmdMemFill (BaseAddressInMainMem, 0x00, AMD_HEAP_SIZE_PER_CORE, StdHeader);
+ // copy heap from temp memory to main memory.
+ // only heap with persist great than HEAP_TEMP_MEM will be copied.
+ // Note: Only copy heap buffers with persist greater than HEAP_TEMP_MEM.
+ while (HeapInTempMemOffset != AMD_HEAP_INVALID_HEAP_OFFSET) {
+ if (HeapInTempMem->Persist > HEAP_TEMP_MEM) {
+ AlignTo16ByteInTempMem = HeapInTempMem->PadSize;
+ AlignTo16ByteInMainMem = (UINT8) ((0x10 - (((UINTN) (VOID *) HeapInMainMem + sizeof (BUFFER_NODE) + SIZE_OF_SENTINEL) & 0xF)) & 0xF);
+ SizeOfNodeData = HeapInTempMem->BufferSize - AlignTo16ByteInTempMem;
+ TotalSize = (UINT32) (TotalSize + sizeof (BUFFER_NODE) + SizeOfNodeData + AlignTo16ByteInMainMem);
+ Source = (UINT8 *) HeapInTempMem + sizeof (BUFFER_NODE) + AlignTo16ByteInTempMem;
+ Destination = (UINT8 *) HeapInMainMem + sizeof (BUFFER_NODE) + AlignTo16ByteInMainMem;
+ LibAmdMemCopy (HeapInMainMem, HeapInTempMem, sizeof (BUFFER_NODE), StdHeader);
+ LibAmdMemCopy (Destination, Source, SizeOfNodeData, StdHeader);
+ HeapInMainMem->OffsetOfNextNode = TotalSize;
+ HeapInMainMem->BufferSize = SizeOfNodeData + AlignTo16ByteInMainMem;
+ HeapInMainMem->PadSize = AlignTo16ByteInMainMem;
+ HeapInMainMem = (BUFFER_NODE *) (BaseAddressInMainMem + TotalSize);
+ }
+ HeapInTempMemOffset = HeapInTempMem->OffsetOfNextNode;
+ HeapInTempMem = (BUFFER_NODE *) (BaseAddressInTempMem + HeapInTempMemOffset);
+ }
+ // initialize heap manager
+ if (TotalSize == sizeof (HEAP_MANAGER)) {
+ // heap is empty
+ HeapManagerInMainMem->UsedSize = sizeof (HEAP_MANAGER);
+ HeapManagerInMainMem->FirstActiveBufferOffset = AMD_HEAP_INVALID_HEAP_OFFSET;
+ HeapManagerInMainMem->FirstFreeSpaceOffset = sizeof (HEAP_MANAGER);
+ } else {
+ // heap is NOT empty
+ HeapManagerInMainMem->UsedSize = TotalSize;
+ HeapManagerInMainMem->FirstActiveBufferOffset = sizeof (HEAP_MANAGER);
+ HeapManagerInMainMem->FirstFreeSpaceOffset = TotalSize;
+ HeapInMainMem = (BUFFER_NODE *) (BaseAddressInMainMem + TotalSize - SizeOfNodeData - AlignTo16ByteInMainMem - sizeof (BUFFER_NODE));
+ HeapInMainMem->OffsetOfNextNode = AMD_HEAP_INVALID_HEAP_OFFSET;
+ HeapInMainMem = (BUFFER_NODE *) (BaseAddressInMainMem + TotalSize);
+ }
+ // heap signature
+ HeapManagerInTempMem->Signature = 0x00000000;
+ HeapManagerInMainMem->Signature = HEAP_SIGNATURE_VALID;
+ // Free space node
+ HeapInMainMem->BufferSize = AMD_HEAP_SIZE_PER_CORE - TotalSize;
+ HeapInMainMem->OffsetOfNextNode = AMD_HEAP_INVALID_HEAP_OFFSET;
+ }
+ // if address of heap in temp memory is above 1M, then we must used one variable MTRR.
+ if (StdHeader->HeapBasePtr >= 0x100000) {
+ // Find out which variable MTRR was used in CopyHeapToTempRamAtPost.
+ GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
+ FamilySpecificServices->GetCacheInfo (FamilySpecificServices, &CacheInfoPtr, &Ignored, StdHeader);
+ for (HeapRamVariableMtrr = AMD_MTRR_VARIABLE_HEAP_BASE;
+ HeapRamVariableMtrr >= AMD_MTRR_VARIABLE_BASE0;
+ HeapRamVariableMtrr--) {
+ LibAmdMsrRead (HeapRamVariableMtrr, &VariableMtrrBase, StdHeader);
+ LibAmdMsrRead ((HeapRamVariableMtrr + 1), &VariableMtrrMask, StdHeader);
+ if ((VariableMtrrBase == (UINT64) (StdHeader->HeapBasePtr & CacheInfoPtr->HeapBaseMask)) &&
+ (VariableMtrrMask == (UINT64) (CacheInfoPtr->VariableMtrrHeapMask & AMD_HEAP_MTRR_MASK))) {
+ break;
+ }
+ }
+ if (HeapRamVariableMtrr >= AMD_MTRR_VARIABLE_BASE0) {
+ // Clear variable MTRR which set in CopyHeapToTempRamAtPost.
+ VariableMtrrBase = 0;
+ VariableMtrrMask = 0;
+ LibAmdMsrWrite (HeapRamVariableMtrr, &VariableMtrrBase, StdHeader);
+ LibAmdMsrWrite ((HeapRamVariableMtrr + 1), &VariableMtrrMask, StdHeader);
+ }
+ }
+ return AGESA_SUCCESS;
+}