summaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/agesa/Lib')
-rw-r--r--src/vendorcode/amd/agesa/Lib/IA32/amdlib32.asm151
-rw-r--r--src/vendorcode/amd/agesa/Lib/IA32/ms_shift.asm110
-rw-r--r--src/vendorcode/amd/agesa/Lib/IA32/msmemcpy.asm84
-rw-r--r--src/vendorcode/amd/agesa/Lib/amdlib.c1336
-rw-r--r--src/vendorcode/amd/agesa/Lib/amdlib.h421
-rw-r--r--src/vendorcode/amd/agesa/Lib/helper.c68
-rw-r--r--src/vendorcode/amd/agesa/Lib/x64/amdlib64.asm591
7 files changed, 2761 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/Lib/IA32/amdlib32.asm b/src/vendorcode/amd/agesa/Lib/IA32/amdlib32.asm
new file mode 100644
index 0000000000..ff0f85b0ba
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Lib/IA32/amdlib32.asm
@@ -0,0 +1,151 @@
+;/**
+; * @file
+; *
+; * Agesa library 32bit
+; *
+; * Contains AMD AGESA Library
+; *
+; * @xrefitem bom "File Content Label" "Release Content"
+; * @e project: AGESA
+; * @e sub-project: Lib
+; * @e \$Revision: 17071 $ @e \$Date: 2009-07-30 10:13:11 -0700 (Thu, 30 Jul 2009) $
+; */
+;*****************************************************************************
+;
+; 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.
+;
+;*****************************************************************************
+
+.586p
+.xmm
+.model flat,C
+ASSUME FS:NOTHING
+.code
+
+;---------------------------------------------------------------------------
+;
+; _mm_clflush_fs - execute clflush instruction for address fs:address32
+; this lets clflush operate beyond 4GB in 32-bit mode
+;
+; void _mm_clflush_fs (void *address32);
+;
+
+_mm_clflush_fs proc public
+
+
+
+
+
+
+ mov eax, [esp+8]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ clflush fs:[eax]
+
+
+
+ ret
+_mm_clflush_fs ENDP
+
+
+;---------------------------------------------------------------------------
+;
+; _mm_stream_si128_fs - execute movntdq instruction for address fs:address32
+; this lets movntdq operate beyond 4GB in 32-bit mode
+;
+; void _mm_stream_si128_fs (void *dest, void *data)
+;
+_mm_stream_si128_fs proc public
+ push esi
+ mov esi, [esp+12]
+ movdqa xmm0, [esi]
+ mov esi, [esp+8]
+ movntdq fs:[esi], xmm0
+
+
+
+
+
+
+
+ pop esi
+ ret
+
+
+
+
+_mm_stream_si128_fs ENDP
+
+
+
+
+;---------------------------------------------------------------------------
+
+
+END
diff --git a/src/vendorcode/amd/agesa/Lib/IA32/ms_shift.asm b/src/vendorcode/amd/agesa/Lib/IA32/ms_shift.asm
new file mode 100644
index 0000000000..3eb51134d5
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Lib/IA32/ms_shift.asm
@@ -0,0 +1,110 @@
+;/**
+; * @file
+; *
+; * Agesa library 32bit
+; *
+; * Contains AMD AGESA Library
+; *
+; * @xrefitem bom "File Content Label" "Release Content"
+; * @e project: AGESA
+; * @e sub-project: Lib
+; * @e \$Revision: 9201 $ @e \$Date: 2008-10-31 03:36:20 -0500 (Fri, 31 Oct 2008) $
+; */
+;*****************************************************************************
+;
+; 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.
+;
+;*****************************************************************************
+
+.586p
+.model flat
+ASSUME FS:NOTHING
+.code
+;/*++
+;
+;Routine Description:
+;
+; Shifts a UINT64 to the right.
+;
+;Arguments:
+;
+; EDX:EAX - UINT64 value to be shifted
+; CL - Shift count
+;
+;Returns:
+;
+; EDX:EAX - shifted value
+;
+;--*/
+_aullshr PROC NEAR C PUBLIC
+ .if (cl < 64)
+ .if (cl >= 32)
+ sub cl, 32
+ mov eax, edx
+ xor edx, edx
+ .endif
+ shrd eax, edx, cl
+ shr edx, cl
+ .else
+ xor eax, eax
+ xor edx, edx
+ .endif
+ ret
+_aullshr ENDP
+
+;/*++
+;
+;Routine Description:
+;
+; Shifts a UINT64 to the left.
+;
+;Arguments:
+;
+; EDX:EAX - UINT64 value to be shifted
+; CL - Shift count
+;
+;Returns:
+;
+; EDX:EAX - shifted value
+;
+;--*/
+_allshl PROC NEAR C PUBLIC USES CX
+ .if (cl < 64)
+ .if (cl >= 32)
+ sub cl, 32
+ mov edx, eax
+ xor eax, eax
+ .endif
+ shld edx, eax, cl
+ shl eax, cl
+ .else
+ xor eax, eax
+ xor edx, edx
+ .endif
+ ret
+_allshl ENDP
+
+END
diff --git a/src/vendorcode/amd/agesa/Lib/IA32/msmemcpy.asm b/src/vendorcode/amd/agesa/Lib/IA32/msmemcpy.asm
new file mode 100644
index 0000000000..b74818c3d0
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Lib/IA32/msmemcpy.asm
@@ -0,0 +1,84 @@
+;/**
+; * @file
+; *
+; * Agesa library 32bit
+; *
+; * Contains AMD AGESA Library
+; *
+; * @xrefitem bom "File Content Label" "Release Content"
+; * @e project: AGESA
+; * @e sub-project: Lib
+; * @e \$Revision: 9201 $ @e \$Date: 2008-10-31 03:36:20 -0500 (Fri, 31 Oct 2008) $
+; */
+;*****************************************************************************
+;
+; 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.
+;
+;*****************************************************************************
+
+.586p
+.model flat
+ASSUME FS:NOTHING
+.code
+; void *memcpy( void *dest, void *src, size_t count );
+;
+; Copy count bytes from src to dest, returning dest.
+; ("c" is not legal as an assembly parameter name, replaced with value.)
+; Assume ES is set appropriately, 32 bit flat.
+;
+public memcpy
+memcpy PROC NEAR C PUBLIC USES ECX EDI ESI dest:DWORD, src:DWORD, count:DWORD
+ pushf
+ cld ; We will increment through *dest
+ mov edi, dest
+ mov esi, src
+ mov ecx, count
+ rep movsb
+ mov eax, dest
+ popf
+ ret
+memcpy ENDP
+
+; void *memset( void *dest, int c, size_t count );
+;
+; At dest, set count bytes to byte value, returning dest.
+; ("c" is not legal as an assembly parameter name, replaced with value.)
+; Assume ES is set appropriately, 32 bit flat.
+;
+public memset
+memset PROC NEAR C PUBLIC USES ECX EDI dest:DWORD, value:DWORD, count:DWORD
+ pushf
+ cld ; We will increment through *dest
+ mov edi, dest
+ mov eax, value
+ mov ecx, count
+ rep stosb
+ mov eax, edi
+ popf
+ ret
+memset ENDP
+
+END
diff --git a/src/vendorcode/amd/agesa/Lib/amdlib.c b/src/vendorcode/amd/agesa/Lib/amdlib.c
new file mode 100644
index 0000000000..1a30dd2f7a
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Lib/amdlib.c
@@ -0,0 +1,1336 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * AMD Library
+ *
+ * Contains interface to the AMD AGESA library
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: Lib
+ * @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 "Ids.h"
+#include "cpuRegisters.h"
+#include "amdlib.h"
+#include "Filecode.h"
+CODE_GROUP (G1_PEICC)
+RDATA_GROUP (G1_PEICC)
+
+#define FILECODE LIB_AMDLIB_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
+ *----------------------------------------------------------------------------------------
+ */
+
+
+BOOLEAN
+STATIC
+GetPciMmioAddress (
+ OUT UINT64 *MmioAddress,
+ OUT UINT32 *MmioSize,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ );
+
+VOID
+STATIC
+LibAmdGetDataFromPtr (
+ IN ACCESS_WIDTH AccessWidth,
+ IN VOID *Data,
+ IN VOID *DataMask,
+ OUT UINT32 *TemData,
+ OUT UINT32 *TempDataMask
+ );
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+UINT8
+ReadIo8 (
+ IN UINT16 Address
+ )
+{
+ return __inbyte (Address);
+}
+UINT16
+ReadIo16 (
+ IN UINT16 Address
+ )
+{
+ return __inword (Address);
+}
+UINT32
+ReadIo32 (
+ IN UINT16 Address
+ )
+{
+ return __indword (Address);
+}
+VOID
+WriteIo8 (
+ IN UINT16 Address,
+ IN UINT8 Data
+ )
+{
+ __outbyte (Address, Data);
+}
+VOID
+WriteIo16 (
+ IN UINT16 Address,
+ IN UINT16 Data
+ )
+{
+ __outword (Address, Data);
+}
+VOID
+WriteIo32 (
+ IN UINT16 Address,
+ IN UINT32 Data
+ )
+{
+ __outdword (Address, Data);
+}
+STATIC
+UINT64 SetFsBase (
+ UINT64 address
+ )
+{
+ UINT64 hwcr;
+ hwcr = __readmsr (0xC0010015);
+ __writemsr (0xC0010015, hwcr | 1 << 17);
+ __writemsr (0xC0000100, address);
+ return hwcr;
+}
+STATIC
+VOID
+RestoreHwcr (
+ UINT64
+ value
+ )
+{
+ __writemsr (0xC0010015, value);
+}
+UINT8
+Read64Mem8 (
+ IN UINT64 Address
+ )
+{
+ UINT8 dataRead;
+ UINT64 hwcrSave;
+ if ((Address >> 32) == 0) {
+ return *(volatile UINT8 *) (UINTN) Address;
+ }
+ hwcrSave = SetFsBase (Address);
+ dataRead = __readfsbyte (0);
+ RestoreHwcr (hwcrSave);
+ return dataRead;
+}
+UINT16
+Read64Mem16 (
+ IN UINT64 Address
+ )
+{
+ UINT16 dataRead;
+ UINT64 hwcrSave;
+ if ((Address >> 32) == 0) {
+ return *(volatile UINT16 *) (UINTN) Address;
+ }
+ hwcrSave = SetFsBase (Address);
+ dataRead = __readfsword (0);
+ RestoreHwcr (hwcrSave);
+ return dataRead;
+}
+UINT32
+Read64Mem32 (
+ IN UINT64 Address
+ )
+{
+ UINT32 dataRead;
+ UINT64 hwcrSave;
+ if ((Address >> 32) == 0) {
+ return *(volatile UINT32 *) (UINTN) Address;
+ }
+ hwcrSave = SetFsBase (Address);
+ dataRead = __readfsdword (0);
+ RestoreHwcr (hwcrSave);
+ return dataRead;
+ }
+VOID
+Write64Mem8 (
+ IN UINT64 Address,
+ IN UINT8 Data
+ )
+{
+ if ((Address >> 32) == 0){
+ *(volatile UINT8 *) (UINTN) Address = Data;
+ }
+ else {
+ UINT64 hwcrSave;
+ hwcrSave = SetFsBase (Address);
+ __writefsbyte (0, Data);
+ RestoreHwcr (hwcrSave);
+ }
+}
+VOID
+Write64Mem16 (
+ IN UINT64 Address,
+ IN UINT16 Data
+ )
+{
+ if ((Address >> 32) == 0){
+ *(volatile UINT16 *) (UINTN) Address = Data;
+ }
+ else {
+ UINT64 hwcrSave;
+ hwcrSave = SetFsBase (Address);
+ __writefsword (0, Data);
+ RestoreHwcr (hwcrSave);
+ }
+}
+VOID
+Write64Mem32 (
+ IN UINT64 Address,
+ IN UINT32 Data
+ )
+{
+ if ((Address >> 32) == 0){
+ *(volatile UINT32 *) (UINTN) Address = Data;
+ }
+ else {
+ UINT64 hwcrSave;
+ hwcrSave = SetFsBase (Address);
+ __writefsdword (0, Data);
+ RestoreHwcr (hwcrSave);
+ }
+}
+VOID
+LibAmdReadCpuReg (
+ IN UINT8 RegNum,
+ OUT UINT32 *Value
+ )
+{
+ *Value = 0;
+ switch (RegNum){
+ case CR4_REG:
+ *Value = __readcr4 ();
+ break;
+ case DR0_REG:
+ *Value = __readdr (0);
+ break;
+ case DR1_REG:
+ *Value = __readdr (1);
+ break;
+ case DR2_REG:
+ *Value = __readdr (2);
+ break;
+ case DR3_REG:
+ *Value = __readdr (3);
+ break;
+ case DR7_REG:
+ *Value = __readdr (7);
+ break;
+ default:
+ *Value = -1;
+ }
+}
+VOID
+LibAmdWriteCpuReg (
+ IN UINT8 RegNum,
+ IN UINT32 Value
+ )
+{
+ switch (RegNum){
+ case CR4_REG:
+ __writecr4 (Value);
+ break;
+ case DR0_REG:
+ __writedr (0, Value);
+ break;
+ case DR1_REG:
+ __writedr (1, Value);
+ break;
+ case DR2_REG:
+ __writedr (2, Value);
+ break;
+ case DR3_REG:
+ __writedr (3, Value);
+ break;
+ case DR7_REG:
+ __writedr (7, Value);
+ break;
+ default:
+ ;
+ }
+}
+VOID
+LibAmdWriteBackInvalidateCache (
+ IN VOID
+ )
+{
+ __wbinvd ();
+}
+VOID
+LibAmdHDTBreakPoint (
+ VOID
+ )
+{
+ __writemsr (0xC001100A, __readmsr (0xC001100A) | 1);
+ __debugbreak (); // do you really need icebp? If so, go back to asm code
+}
+UINT8
+LibAmdBitScanForward (
+ IN UINT32 value
+ )
+{
+ UINTN Index;
+ for (Index = 0; Index < 32; Index++){
+ if (value & (1 << Index)) break;
+ }
+ return (UINT8) Index;
+}
+UINT8
+LibAmdBitScanReverse (
+ IN UINT32 value
+)
+{
+ UINTN Index;
+ for (Index = 31; Index >= 0; Index--){
+ if (value & (1 << Index)) break;
+ }
+ return (UINT8) Index;
+}
+VOID
+LibAmdMsrRead (
+ IN UINT32 MsrAddress,
+ OUT UINT64 *Value,
+ IN OUT AMD_CONFIG_PARAMS *ConfigPtr
+ )
+{
+ *Value = __readmsr (MsrAddress);
+}
+VOID
+LibAmdMsrWrite (
+ IN UINT32 MsrAddress,
+ IN UINT64 *Value,
+ IN OUT AMD_CONFIG_PARAMS *ConfigPtr
+ )
+{
+ __writemsr (MsrAddress, *Value);
+}
+void LibAmdCpuidRead (
+ IN UINT32 CpuidFcnAddress,
+ OUT CPUID_DATA* Value,
+ IN OUT AMD_CONFIG_PARAMS *ConfigPtr
+ )
+{
+ __cpuid ((int *)Value, CpuidFcnAddress);
+}
+UINT64
+ReadTSC (
+ VOID
+ )
+{
+ return __rdtsc ();
+}
+VOID
+LibAmdSimNowEnterDebugger (
+ VOID
+ )
+{
+ STATIC CONST UINT8 opcode [] = {0x60, // pushad
+ 0xBB, 0x02, 0x00, 0x00, 0x00, // mov ebx, 2
+ 0xB8, 0x0B, 0xD0, 0xCC, 0xBA, // mov eax, 0xBACCD00B
+ 0x0F, 0xA2, // cpuid
+ 0x61, // popad
+ 0xC3 // ret
+ };
+ ((VOID (*)(VOID)) (size_t) opcode) (); // call the function
+}
+VOID F10RevDProbeFilterCritical (
+ IN PCI_ADDR PciAddress,
+ IN UINT32 PciRegister
+ )
+{
+ UINT64 msrsave;
+ msrsave = __readmsr (0xC001001F);
+ __writemsr (0xC001001F, msrsave | 1ULL << 46); // EnableCf8ExtCfg
+ _mm_mfence ();
+ __outdword (0xCF8, PciAddress.AddressValue);
+ _mm_mfence ();
+ __outdword (0xCFC, PciRegister | 2);
+ _mm_mfence ();
+ __writemsr (0xC001001F, msrsave);
+}
+VOID
+IdsOutPort (
+ IN UINT32 Addr,
+ IN UINT32 Value,
+ IN UINT32 Flag
+ )
+{
+ __outdword ((UINT16) Addr, Value);
+}
+VOID
+StopHere (
+ VOID
+ )
+{
+ VOLATILE UINTN x = 1;
+ while (x);
+}
+VOID
+LibAmdCLFlush (
+ IN UINT64 Address,
+ IN UINT8 Count
+ )
+{
+ UINT64 hwcrSave;
+ UINT8 *address32;
+ UINTN Index;
+ address32 = 0;
+ hwcrSave = SetFsBase (Address);
+ for (Index = 0; Index < Count; Index++){
+ _mm_mfence ();
+ _mm_clflush_fs (&address32 [Index * 64]);
+ }
+ RestoreHwcr (hwcrSave);
+}
+
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Read IO port
+ *
+ *
+ * @param[in] AccessWidth Access width
+ * @param[in] IoAddress IO port address
+ * @param[in] Value Pointer to save data
+ * @param[in] StdHeader Standard configuration header
+ *
+ */
+VOID
+LibAmdIoRead (
+ IN ACCESS_WIDTH AccessWidth,
+ IN UINT16 IoAddress,
+ OUT VOID *Value,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ switch (AccessWidth) {
+ case AccessWidth8:
+ case AccessS3SaveWidth8:
+ *(UINT8 *) Value = ReadIo8 (IoAddress);
+ break;
+ case AccessWidth16:
+ case AccessS3SaveWidth16:
+ *(UINT16 *) Value = ReadIo16 (IoAddress);
+ break;
+ case AccessWidth32:
+ case AccessS3SaveWidth32:
+ *(UINT32 *) Value = ReadIo32 (IoAddress);
+ break;
+ default:
+ ASSERT (FALSE);
+ }
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Write IO port
+ *
+ *
+ * @param[in] AccessWidth Access width
+ * @param[in] IoAddress IO port address
+ * @param[in] Value Pointer to data
+ * @param[in] StdHeader Standard configuration header
+ *
+ */
+VOID
+LibAmdIoWrite (
+ IN ACCESS_WIDTH AccessWidth,
+ IN UINT16 IoAddress,
+ IN VOID *Value,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ switch (AccessWidth) {
+ case AccessWidth8:
+ case AccessS3SaveWidth8:
+ WriteIo8 (IoAddress, *(UINT8 *) Value);
+ break;
+ case AccessWidth16:
+ case AccessS3SaveWidth16:
+ WriteIo16 (IoAddress, *(UINT16 *) Value);
+ break;
+ case AccessWidth32:
+ case AccessS3SaveWidth32:
+ WriteIo32 (IoAddress, *(UINT32 *) Value);
+ break;
+ default:
+ ASSERT (FALSE);
+ }
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * IO read modify write
+ *
+ *
+ * @param[in] AccessWidth Access width
+ * @param[in] IoAddress IO address
+ * @param[in] Data OR data
+ * @param[in] DataMask Mask to be used before data write back to register.
+ * @param[in] StdHeader Standard configuration header
+ *
+ */
+VOID
+LibAmdIoRMW (
+ IN ACCESS_WIDTH AccessWidth,
+ IN UINT16 IoAddress,
+ IN VOID *Data,
+ IN VOID *DataMask,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 TempData;
+ UINT32 TempMask;
+ UINT32 Value;
+ LibAmdGetDataFromPtr (AccessWidth, Data, DataMask, &TempData, &TempMask);
+ LibAmdIoRead (AccessWidth, IoAddress, &Value, StdHeader);
+ Value = (Value & (~TempMask)) | TempData;
+ LibAmdIoWrite (AccessWidth, IoAddress, &Value, StdHeader);
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Poll IO register
+ *
+ * Poll register until (RegisterValue & DataMask) == Data
+ *
+ * @param[in] AccessWidth Access width
+ * @param[in] IoAddress IO address
+ * @param[in] Data Data to compare
+ * @param[in] DataMask And mask
+ * @param[in] Delay Poll for time in 100ns (not supported)
+ * @param[in] StdHeader Standard configuration header
+ *
+ */
+VOID
+LibAmdIoPoll (
+ IN ACCESS_WIDTH AccessWidth,
+ IN UINT16 IoAddress,
+ IN VOID *Data,
+ IN VOID *DataMask,
+ IN UINT64 Delay,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 TempData;
+ UINT32 TempMask;
+ UINT32 Value;
+ LibAmdGetDataFromPtr (AccessWidth, Data, DataMask, &TempData, &TempMask);
+ do {
+ LibAmdIoRead (AccessWidth, IoAddress, &Value, StdHeader);
+ } while (TempData != (Value & TempMask));
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Read memory/MMIO
+ *
+ *
+ * @param[in] AccessWidth Access width
+ * @param[in] MemAddress Memory address
+ * @param[in] Value Pointer to data
+ * @param[in] StdHeader Standard configuration header
+ *
+ */
+VOID
+LibAmdMemRead (
+ IN ACCESS_WIDTH AccessWidth,
+ IN UINT64 MemAddress,
+ OUT VOID *Value,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ switch (AccessWidth) {
+ case AccessWidth8:
+ case AccessS3SaveWidth8:
+ *(UINT8 *) Value = Read64Mem8 (MemAddress);
+ break;
+ case AccessWidth16:
+ case AccessS3SaveWidth16:
+ *(UINT16 *) Value = Read64Mem16 (MemAddress);
+ break;
+ case AccessWidth32:
+ case AccessS3SaveWidth32:
+ *(UINT32 *) Value = Read64Mem32 (MemAddress);
+ break;
+ default:
+ ASSERT (FALSE);
+ }
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Write memory/MMIO
+ *
+ *
+ * @param[in] AccessWidth Access width
+ * @param[in] MemAddress Memory address
+ * @param[in] Value Pointer to data
+ * @param[in] StdHeader Standard configuration header
+ *
+ */
+VOID
+LibAmdMemWrite (
+ IN ACCESS_WIDTH AccessWidth,
+ IN UINT64 MemAddress,
+ IN VOID *Value,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+
+ switch (AccessWidth) {
+ case AccessWidth8:
+ case AccessS3SaveWidth8:
+ Write64Mem8 (MemAddress, *((UINT8 *) Value));
+ break;
+ case AccessWidth16:
+ case AccessS3SaveWidth16:
+ Write64Mem16 (MemAddress, *((UINT16 *) Value));
+ break;
+ case AccessWidth32:
+ case AccessS3SaveWidth32:
+ Write64Mem32 (MemAddress, *((UINT32 *) Value));
+ break;
+ default:
+ ASSERT (FALSE);
+ }
+}
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Memory/MMIO read modify write
+ *
+ *
+ * @param[in] AccessWidth Access width
+ * @param[in] MemAddress Memory address
+ * @param[in] Data OR data
+ * @param[in] DataMask Mask to be used before data write back to register.
+ * @param[in] StdHeader Standard configuration header
+ *
+ */
+VOID
+LibAmdMemRMW (
+ IN ACCESS_WIDTH AccessWidth,
+ IN UINT64 MemAddress,
+ IN VOID *Data,
+ IN VOID *DataMask,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 TempData;
+ UINT32 TempMask;
+ UINT32 Value;
+ LibAmdGetDataFromPtr (AccessWidth, Data, DataMask, &TempData, &TempMask);
+ LibAmdMemRead (AccessWidth, MemAddress, &Value, StdHeader);
+ Value = (Value & (~TempMask)) | TempData;
+ LibAmdMemWrite (AccessWidth, MemAddress, &Value, StdHeader);
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Poll Mmio
+ *
+ * Poll register until (RegisterValue & DataMask) == Data
+ *
+ * @param[in] AccessWidth Access width
+ * @param[in] MemAddress Memory address
+ * @param[in] Data Data to compare
+ * @param[in] DataMask AND mask
+ * @param[in] Delay Poll for time in 100ns (not supported)
+ * @param[in] StdHeader Standard configuration header
+ *
+ */
+VOID
+LibAmdMemPoll (
+ IN ACCESS_WIDTH AccessWidth,
+ IN UINT64 MemAddress,
+ IN VOID *Data,
+ IN VOID *DataMask,
+ IN UINT64 Delay,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 TempData;
+ UINT32 TempMask;
+ UINT32 Value;
+ LibAmdGetDataFromPtr (AccessWidth, Data, DataMask, &TempData, &TempMask);
+ do {
+ LibAmdMemRead (AccessWidth, MemAddress, &Value, StdHeader);
+ } while (TempData != (Value & TempMask));
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Read PCI config space
+ *
+ *
+ * @param[in] AccessWidth Access width
+ * @param[in] PciAddress Pci address
+ * @param[in] Value Pointer to data
+ * @param[in] StdHeader Standard configuration header
+ *
+ */
+VOID
+LibAmdPciRead (
+ IN ACCESS_WIDTH AccessWidth,
+ IN PCI_ADDR PciAddress,
+ OUT VOID *Value,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 LegacyPciAccess;
+ UINT32 MMIOSize;
+ UINT64 RMWrite;
+ UINT64 RMWritePrevious;
+ UINT64 MMIOAddress;
+
+ ASSERT (StdHeader != NULL);
+ ASSERT (PciAddress.AddressValue != ILLEGAL_SBDFO);
+ if (!GetPciMmioAddress (&MMIOAddress, &MMIOSize, StdHeader)) {
+ // We need to convert our "portable" PCI address into a "real" PCI access
+ LegacyPciAccess = ((1 << 31) + (PciAddress.Address.Register & 0xFC) + (PciAddress.Address.Function << 8) + (PciAddress.Address.Device << 11) + (PciAddress.Address.Bus << 16) + ((PciAddress.Address.Register & 0xF00) << (24 - 8)));
+ if (PciAddress.Address.Register <= 0xFF) {
+ LibAmdIoWrite (AccessWidth32, IOCF8, &LegacyPciAccess, StdHeader);
+ LibAmdIoRead (AccessWidth, IOCFC + (UINT16) (PciAddress.Address.Register & 0x3), Value, StdHeader);
+ } else {
+ LibAmdMsrRead (NB_CFG, &RMWritePrevious, StdHeader);
+ RMWrite = RMWritePrevious | 0x0000400000000000;
+ LibAmdMsrWrite (NB_CFG, &RMWrite, StdHeader);
+ LibAmdIoWrite (AccessWidth32, IOCF8, &LegacyPciAccess, StdHeader);
+ LibAmdIoRead (AccessWidth, IOCFC + (UINT16) (PciAddress.Address.Register & 0x3), Value, StdHeader);
+ LibAmdMsrWrite (NB_CFG, &RMWritePrevious, StdHeader);
+ }
+ } else {
+ // Setup the MMIO address
+ ASSERT ((MMIOAddress + MMIOSize) > (MMIOAddress + (PciAddress.AddressValue & 0x0FFFFFFF)));
+ MMIOAddress += (PciAddress.AddressValue & 0x0FFFFFFF);
+ LibAmdMemRead (AccessWidth, MMIOAddress, Value, StdHeader);
+ }
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Write PCI config space
+ *
+ *
+ * @param[in] AccessWidth Access width
+ * @param[in] PciAddress Pci address
+ * @param[in] Value Pointer to data
+ * @param[in] StdHeader Standard configuration header
+ *
+ */
+VOID
+LibAmdPciWrite (
+ IN ACCESS_WIDTH AccessWidth,
+ IN PCI_ADDR PciAddress,
+ IN VOID *Value,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 LegacyPciAccess;
+ UINT32 MMIOSize;
+ UINT64 RMWrite;
+ UINT64 RMWritePrevious;
+ UINT64 MMIOAddress;
+
+ ASSERT (StdHeader != NULL);
+ ASSERT (PciAddress.AddressValue != ILLEGAL_SBDFO);
+ if (!GetPciMmioAddress (&MMIOAddress, &MMIOSize, StdHeader)) {
+ // We need to convert our "portable" PCI address into a "real" PCI access
+ LegacyPciAccess = ((1 << 31) + (PciAddress.Address.Register & 0xFC) + (PciAddress.Address.Function << 8) + (PciAddress.Address.Device << 11) + (PciAddress.Address.Bus << 16) + ((PciAddress.Address.Register & 0xF00) << (24 - 8)));
+ if (PciAddress.Address.Register <= 0xFF) {
+ LibAmdIoWrite (AccessWidth32, IOCF8, &LegacyPciAccess, StdHeader);
+ LibAmdIoWrite (AccessWidth, IOCFC + (UINT16) (PciAddress.Address.Register & 0x3), Value, StdHeader);
+ } else {
+ LibAmdMsrRead (NB_CFG, &RMWritePrevious, StdHeader);
+ RMWrite = RMWritePrevious | 0x0000400000000000;
+ LibAmdMsrWrite (NB_CFG, &RMWrite, StdHeader);
+ LibAmdIoWrite (AccessWidth32, IOCF8, &LegacyPciAccess, StdHeader);
+ LibAmdIoWrite (AccessWidth, IOCFC + (UINT16) (PciAddress.Address.Register & 0x3), Value, StdHeader);
+ LibAmdMsrWrite (NB_CFG, &RMWritePrevious, StdHeader);
+ }
+ } else {
+ // Setup the MMIO address
+ ASSERT ((MMIOAddress + MMIOSize) > (MMIOAddress + (PciAddress.AddressValue & 0x0FFFFFFF)));
+ MMIOAddress += (PciAddress.AddressValue & 0x0FFFFFFF);
+ LibAmdMemWrite (AccessWidth, MMIOAddress, Value, StdHeader);
+ }
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * PCI read modify write
+ *
+ *
+ * @param[in] AccessWidth Access width
+ * @param[in] PciAddress Pci address
+ * @param[in] Data OR Data
+ * @param[in] DataMask Mask to be used before data write back to register.
+ * @param[in] StdHeader Standard configuration header
+ *
+ */
+VOID
+LibAmdPciRMW (
+ IN ACCESS_WIDTH AccessWidth,
+ IN PCI_ADDR PciAddress,
+ IN VOID *Data,
+ IN VOID *DataMask,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 TempData;
+ UINT32 TempMask;
+ UINT32 Value;
+ LibAmdGetDataFromPtr (AccessWidth, Data, DataMask, &TempData, &TempMask);
+ LibAmdPciRead (AccessWidth, PciAddress, &Value, StdHeader);
+ Value = (Value & (~TempMask)) | TempData;
+ LibAmdPciWrite (AccessWidth, PciAddress, &Value, StdHeader);
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Poll PCI config space register
+ *
+ * Poll register until (RegisterValue & DataMask) == Data
+ *
+ * @param[in] AccessWidth Access width
+ * @param[in] PciAddress Pci address
+ * @param[in] Data Data to compare
+ * @param[in] DataMask AND mask
+ * @param[in] Delay Poll for time in 100ns (not supported)
+ * @param[in] StdHeader Standard configuration header
+ *
+ */
+VOID
+LibAmdPciPoll (
+ IN ACCESS_WIDTH AccessWidth,
+ IN PCI_ADDR PciAddress,
+ IN VOID *Data,
+ IN VOID *DataMask,
+ IN UINT64 Delay,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 TempData;
+ UINT32 TempMask;
+ UINT32 Value;
+ LibAmdGetDataFromPtr (AccessWidth, Data, DataMask, &TempData, &TempMask);
+ do {
+ LibAmdPciRead (AccessWidth, PciAddress, &Value, StdHeader);
+ } while (TempData != (Value & TempMask));
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Get MMIO base address for PCI accesses
+ *
+ * @param[out] MmioAddress PCI MMIO base address
+ * @param[out] MmioSize Size of region in bytes
+ * @param[in] StdHeader Standard configuration header
+ *
+ * @retval TRUE MmioAddress/MmioSize are valid
+ */
+BOOLEAN
+STATIC
+GetPciMmioAddress (
+ OUT UINT64 *MmioAddress,
+ OUT UINT32 *MmioSize,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ BOOLEAN MmioIsEnabled;
+ UINT32 EncodedSize;
+ UINT64 MsrReg;
+
+ ASSERT (StdHeader != NULL);
+
+ MmioIsEnabled = FALSE;
+ LibAmdMsrRead (MSR_MMIO_Cfg_Base, &MsrReg, StdHeader);
+ if ((MsrReg & BIT0) != 0) {
+ *MmioAddress = MsrReg & 0xFFFFFFFFFFF00000;
+ EncodedSize = (UINT32) ((MsrReg & 0x3C) >> 2);
+ *MmioSize = ((1 << EncodedSize) * 0x100000);
+ MmioIsEnabled = TRUE;
+ }
+ return MmioIsEnabled;
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Read field of PCI config register.
+ *
+ *
+ *
+ * @param[in] Address Pci address (register must be DWORD aligned)
+ * @param[in] Highbit High bit position of the field in DWORD
+ * @param[in] Lowbit Low bit position of the field in DWORD
+ * @param[out] Value Pointer to data
+ * @param[in] StdHeader Standard configuration header
+ */
+VOID
+LibAmdPciReadBits (
+ IN PCI_ADDR Address,
+ IN UINT8 Highbit,
+ IN UINT8 Lowbit,
+ OUT UINT32 *Value,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ ASSERT (Highbit < 32 && Lowbit < 32 && Highbit >= Lowbit && (Address.AddressValue & 3) == 0);
+
+ LibAmdPciRead (AccessWidth32, Address, Value, StdHeader);
+ *Value >>= Lowbit; // Shift
+
+ // A 1 << 32 == 1 << 0 due to x86 SHL instruction, so skip if that is the case
+
+ if ((Highbit - Lowbit) != 31) {
+ *Value &= (((UINT32) 1 << (Highbit - Lowbit + 1)) - 1);
+ }
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Write field of PCI config register.
+ *
+ *
+ *
+ * @param[in] Address Pci address (register must be DWORD aligned)
+ * @param[in] Highbit High bit position of the field in DWORD
+ * @param[in] Lowbit Low bit position of the field in DWORD
+ * @param[in] Value Pointer to data
+ * @param[in] StdHeader Standard configuration header
+ */
+VOID
+LibAmdPciWriteBits (
+ IN PCI_ADDR Address,
+ IN UINT8 Highbit,
+ IN UINT8 Lowbit,
+ IN UINT32 *Value,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 Temp;
+ UINT32 Mask;
+
+ ASSERT (Highbit < 32 && Lowbit < 32 && Highbit >= Lowbit && (Address.AddressValue & 3) == 0);
+
+ // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
+
+ if ((Highbit - Lowbit) != 31) {
+ Mask = (((UINT32) 1 << (Highbit - Lowbit + 1)) - 1);
+ } else {
+ Mask = (UINT32) 0xFFFFFFFF;
+ }
+
+ LibAmdPciRead (AccessWidth32, Address, &Temp, StdHeader);
+ Temp &= ~(Mask << Lowbit);
+ Temp |= (*Value & Mask) << Lowbit;
+ LibAmdPciWrite (AccessWidth32, Address, &Temp, StdHeader);
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Locate next capability pointer
+ *
+ * Given a SBDFO this routine will find the next PCI capabilities list entry.
+ * if the end of the list is reached, or if a problem is detected, then ILLEGAL_SBDFO is
+ * returned.
+ * To start a new search from the head of the list, specify a SBDFO with an offset of zero.
+ *
+ * @param[in,out] Address Pci address
+ * @param[in] StdHeader Standard configuration header
+ */
+
+VOID
+LibAmdPciFindNextCap (
+ IN OUT PCI_ADDR *Address,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ PCI_ADDR Base;
+ UINT32 Offset;
+ UINT32 Temp;
+ PCI_ADDR TempAddress;
+
+ ASSERT (Address != NULL);
+ ASSERT (*(UINT32 *) Address != ILLEGAL_SBDFO);
+
+ Base.AddressValue = Address->AddressValue;
+ Offset = Base.Address.Register;
+ Base.Address.Register = 0;
+
+ Address->AddressValue = (UINT32) ILLEGAL_SBDFO;
+
+ // Verify that the SBDFO points to a valid PCI device SANITY CHECK
+ LibAmdPciRead (AccessWidth32, Base, &Temp, StdHeader);
+ if (Temp == 0xFFFFFFFF) {
+ ASSERT (FALSE);
+ return; // There is no device at this address
+ }
+
+ // Verify that the device supports a capability list
+ TempAddress.AddressValue = Base.AddressValue + 0x04;
+ LibAmdPciReadBits (TempAddress, 20, 20, &Temp, StdHeader);
+ if (Temp == 0) {
+ return; // This PCI device does not support capability lists
+ }
+
+ if (Offset != 0) {
+ // If we are continuing on an existing list
+ TempAddress.AddressValue = Base.AddressValue + Offset;
+ LibAmdPciReadBits (TempAddress, 15, 8, &Temp, StdHeader);
+ } else {
+ // We are starting on a new list
+ TempAddress.AddressValue = Base.AddressValue + 0x34;
+ LibAmdPciReadBits (TempAddress, 7, 0, &Temp, StdHeader);
+ }
+
+ if (Temp == 0) {
+ return; // We have reached the end of the capabilities list
+ }
+
+ // Error detection and recovery- The statement below protects against
+ // PCI devices with broken PCI capabilities lists. Detect a pointer
+ // that is not uint32 aligned, points into the first 64 reserved DWORDs
+ // or points back to itself.
+ if (((Temp & 3) != 0) || (Temp == Offset) || (Temp < 0x40)) {
+ ASSERT (FALSE);
+ return;
+ }
+
+ Address->AddressValue = Base.AddressValue + Temp;
+ return;
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Set memory with value
+ *
+ *
+ * @param[in,out] Destination Pointer to memory range
+ * @param[in] Value Value to set memory with
+ * @param[in] FillLength Size of the memory range
+ * @param[in] StdHeader Standard configuration header (Optional)
+ */
+VOID
+LibAmdMemFill (
+ IN VOID *Destination,
+ IN UINT8 Value,
+ IN UINTN FillLength,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT8 *Dest;
+ ASSERT (StdHeader != NULL);
+ Dest = Destination;
+ while ((FillLength--) != 0) {
+ *Dest++ = Value;
+ }
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Copy memory
+ *
+ *
+ * @param[in,out] Destination Pointer to destination buffer
+ * @param[in] Source Pointer to source buffer
+ * @param[in] CopyLength buffer length
+ * @param[in] StdHeader Standard configuration header (Optional)
+ */
+VOID
+LibAmdMemCopy (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN CopyLength,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT8 *Dest;
+ UINT8 *SourcePtr;
+ ASSERT (StdHeader != NULL);
+ Dest = Destination;
+ SourcePtr = Source;
+ while ((CopyLength--) != 0) {
+ *Dest++ = *SourcePtr++;
+ }
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Verify checksum of binary image (B1/B2/B3)
+ *
+ *
+ * @param[in] ImagePtr Pointer to image start
+ * @retval TRUE Checksum valid
+ * @retval FALSE Checksum invalid
+ */
+BOOLEAN
+LibAmdVerifyImageChecksum (
+ IN VOID *ImagePtr
+ )
+{
+ // Assume ImagePtr points to the binary start ($AMD)
+ // Checksum is on an even boundary in AMD_IMAGE_HEADER
+
+ UINT16 Sum;
+ UINT32 i;
+
+ Sum = 0;
+
+ i = ((AMD_IMAGE_HEADER*) ImagePtr)->ImageSize;
+
+ while (i > 1) {
+ Sum = Sum + *((UINT16 *)ImagePtr);
+ ImagePtr = (VOID *) ((UINT8 *)ImagePtr + 2);
+ i = i - 2;
+ }
+ if (i > 0) {
+ Sum = Sum + *((UINT8 *) ImagePtr);
+ }
+
+ return (Sum == 0)?TRUE:FALSE;
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Locate AMD binary image that contain specific module
+ *
+ *
+ * @param[in] StartAddress Pointer to start range
+ * @param[in] EndAddress Pointer to end range
+ * @param[in] Alignment Image address alignment
+ * @param[in] ModuleSignature Module signature.
+ * @retval NULL if image not found
+ * @retval pointer to image header
+ */
+VOID *
+LibAmdLocateImage (
+ IN VOID *StartAddress,
+ IN VOID *EndAddress,
+ IN UINT32 Alignment,
+ IN CHAR8 ModuleSignature[8]
+ )
+
+{
+ UINT8 *CurrentPtr;
+ AMD_MODULE_HEADER *ModuleHeaderPtr;
+ UINT64 *SearchStr;
+ UINT64 *InputStr;
+
+ CurrentPtr = StartAddress;
+ InputStr = (UINT64 *)ModuleSignature;
+
+ // Search from start to end incrementing by alignment
+ while ((CurrentPtr >= (UINT8 *) StartAddress) && (CurrentPtr < (UINT8 *) EndAddress)) {
+ // First find a binary image
+ if (*((UINT32 *) CurrentPtr) == IMAGE_SIGNATURE) {
+ if (LibAmdVerifyImageChecksum (CurrentPtr)) {
+ // If we have a valid image, search module linked list for a match
+ ModuleHeaderPtr = (AMD_MODULE_HEADER*) ((UINT8 *)CurrentPtr + ((AMD_IMAGE_HEADER *) CurrentPtr)->ModuleInfoOffset);
+ while (ModuleHeaderPtr != NULL) {
+ SearchStr = (UINT64 *)&ModuleHeaderPtr->ModuleIdentifier;
+ if (*InputStr == *SearchStr) {
+ return CurrentPtr;
+ }
+ ModuleHeaderPtr = (AMD_MODULE_HEADER *)ModuleHeaderPtr->NextBlock;
+ }
+ }
+ }
+ CurrentPtr += Alignment;
+ }
+ return NULL;
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Returns the package type mask for the processor
+ *
+ *
+ * @param[in] StdHeader Standard configuration header (Optional)
+ */
+
+// Returns the package type mask for the processor
+UINT32
+LibAmdGetPackageType (
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 ProcessorPackageType;
+ CPUID_DATA CpuId;
+
+ LibAmdCpuidRead (0x80000001, &CpuId, StdHeader);
+ ProcessorPackageType = (UINT32) (CpuId.EBX_Reg >> 28) & 0xF; // bit 31:28
+ return (UINT32) (1 << ProcessorPackageType);
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Returns the package type mask for the processor
+ *
+ *
+ * @param[in] AccessWidth Access width
+ * @param[in] Data data
+ * @param[in] DataMask data
+ * @param[out] TemData typecast data
+ * @param[out] TempDataMask typecast data
+ */
+
+
+VOID
+STATIC
+LibAmdGetDataFromPtr (
+ IN ACCESS_WIDTH AccessWidth,
+ IN VOID *Data,
+ IN VOID *DataMask,
+ OUT UINT32 *TemData,
+ OUT UINT32 *TempDataMask
+ )
+{
+ switch (AccessWidth) {
+ case AccessWidth8:
+ case AccessS3SaveWidth8:
+ *TemData = (UINT32)*(UINT8 *) Data;
+ *TempDataMask = (UINT32)*(UINT8 *) DataMask;
+ break;
+ case AccessWidth16:
+ case AccessS3SaveWidth16:
+ *TemData = (UINT32)*(UINT16 *) Data;
+ *TempDataMask = (UINT32)*(UINT16 *) DataMask;
+ break;
+ case AccessWidth32:
+ case AccessS3SaveWidth32:
+ *TemData = *(UINT32 *) Data;
+ *TempDataMask = *(UINT32 *) DataMask;
+ break;
+ default:
+ IDS_ERROR_TRAP;
+ }
+}
+
+/*---------------------------------------------------------------------------------------*/
+/**
+ * Returns the package type mask for the processor
+ *
+ *
+ * @param[in] AccessWidth Access width
+ * @retval Width in number of bytes
+ */
+
+
+UINT8
+LibAmdAccessWidth (
+ IN ACCESS_WIDTH AccessWidth
+ )
+{
+ UINT8 Width;
+
+ switch (AccessWidth) {
+ case AccessWidth8:
+ case AccessS3SaveWidth8:
+ Width = 1;
+ break;
+ case AccessWidth16:
+ case AccessS3SaveWidth16:
+ Width = 2;
+ break;
+ case AccessWidth32:
+ case AccessS3SaveWidth32:
+ Width = 4;
+ break;
+ case AccessWidth64:
+ case AccessS3SaveWidth64:
+ Width = 8;
+ break;
+ default:
+ Width = 0;
+ IDS_ERROR_TRAP;
+ }
+ return Width;
+}
+
+VOID
+CpuidRead (
+ IN UINT32 CpuidFcnAddress,
+ OUT CPUID_DATA *Value
+ )
+{
+ __cpuid ((int *)Value, CpuidFcnAddress);
+}
+
+UINT8
+ReadNumberOfCpuCores(
+ VOID
+ )
+{
+ CPUID_DATA Value;
+ CpuidRead (0x80000008, &Value);
+ return Value.ECX_Reg & 0xff;
+}
diff --git a/src/vendorcode/amd/agesa/Lib/amdlib.h b/src/vendorcode/amd/agesa/Lib/amdlib.h
new file mode 100644
index 0000000000..83edc68862
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Lib/amdlib.h
@@ -0,0 +1,421 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * AMD Library
+ *
+ * Contains interface to the AMD AGESA library
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: Lib
+ * @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+#ifndef _AMD_LIB_H_
+#define _AMD_LIB_H_
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+#define IOCF8 0xCF8
+#define IOCFC 0xCFC
+
+// Reg Values for ReadCpuReg and WriteCpuReg
+#define CR0_REG 0x00
+#define CR4_REG 0x04
+#define DR0_REG 0x10
+#define DR1_REG 0x11
+#define DR2_REG 0x12
+#define DR3_REG 0x13
+#define DR7_REG 0x17
+
+/*----------------------------------------------------------------------------------------
+ * 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
+ *----------------------------------------------------------------------------------------
+ */
+
+#if !defined __GNUC__
+// PROTOTYPES FOR amdlib32.asm
+void _mm_stream_si128_fs (void *__A, void *__B);
+void _mm_store_si128_fs (void *dest, void *data);
+void _mm_clflush_fs (void *address32);
+#endif
+/*---------------------------------------------------------------------------------------
+ * L O C A L F U N C T I O N S
+ *---------------------------------------------------------------------------------------
+ */
+UINT8
+ReadIo8 (
+ IN UINT16 Address
+ );
+
+UINT16
+ReadIo16 (
+ IN UINT16 Address
+ );
+
+UINT32
+ReadIo32 (
+ IN UINT16 Address
+ );
+
+VOID
+WriteIo8 (
+ IN UINT16 Address,
+ IN UINT8 Data
+ );
+
+VOID
+WriteIo16 (
+ IN UINT16 Address,
+ IN UINT16 Data
+ );
+
+VOID
+WriteIo32 (
+ IN UINT16 Address,
+ IN UINT32 Data
+ );
+
+UINT8
+Read64Mem8 (
+ IN UINT64 Address
+ );
+
+UINT16
+Read64Mem16 (
+ IN UINT64 Address
+ );
+
+UINT32
+Read64Mem32 (
+ IN UINT64 Address
+ );
+
+VOID
+Write64Mem8 (
+ IN UINT64 Address,
+ IN UINT8 Data
+ );
+
+VOID
+Write64Mem16 (
+ IN UINT64 Address,
+ IN UINT16 Data
+ );
+
+VOID
+Write64Mem32 (
+ IN UINT64 Address,
+ IN UINT32 Data
+ );
+
+UINT64
+ReadTSC (
+ VOID
+ );
+
+// MSR
+VOID
+LibAmdMsrRead (
+ IN UINT32 MsrAddress,
+ OUT UINT64 *Value,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+VOID
+LibAmdMsrWrite (
+ IN UINT32 MsrAddress,
+ IN UINT64 *Value,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+// IO
+VOID
+LibAmdIoRead (
+ IN ACCESS_WIDTH AccessWidth,
+ IN UINT16 IoAddress,
+ OUT VOID *Value,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+VOID
+LibAmdIoWrite (
+ IN ACCESS_WIDTH AccessWidth,
+ IN UINT16 IoAddress,
+ IN VOID *Value,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+VOID
+LibAmdIoRMW (
+ IN ACCESS_WIDTH AccessWidth,
+ IN UINT16 IoAddress,
+ IN VOID *Data,
+ IN VOID *DataMask,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+VOID
+LibAmdIoPoll (
+ IN ACCESS_WIDTH AccessWidth,
+ IN UINT16 IoAddress,
+ IN VOID *Data,
+ IN VOID *DataMask,
+ IN UINT64 Delay,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+// Memory or MMIO
+VOID
+LibAmdMemRead (
+ IN ACCESS_WIDTH AccessWidth,
+ IN UINT64 MemAddress,
+ OUT VOID *Value,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+VOID
+LibAmdMemWrite (
+ IN ACCESS_WIDTH AccessWidth,
+ IN UINT64 MemAddress,
+ IN VOID *Value,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+VOID
+LibAmdMemRMW (
+ IN ACCESS_WIDTH AccessWidth,
+ IN UINT64 MemAddress,
+ IN VOID *Data,
+ IN VOID *DataMask,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+VOID
+LibAmdMemPoll (
+ IN ACCESS_WIDTH AccessWidth,
+ IN UINT64 MemAddress,
+ IN VOID *Data,
+ IN VOID *DataMask,
+ IN UINT64 Delay,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+// PCI
+VOID
+LibAmdPciRead (
+ IN ACCESS_WIDTH AccessWidth,
+ IN PCI_ADDR PciAddress,
+ OUT VOID *Value,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+VOID
+LibAmdPciWrite (
+ IN ACCESS_WIDTH AccessWidth,
+ IN PCI_ADDR PciAddress,
+ IN VOID *Value,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+VOID
+LibAmdPciRMW (
+ IN ACCESS_WIDTH AccessWidth,
+ IN PCI_ADDR PciAddress,
+ IN VOID *Data,
+ IN VOID *DataMask,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+VOID
+LibAmdPciPoll (
+ IN ACCESS_WIDTH AccessWidth,
+ IN PCI_ADDR PciAddress,
+ IN VOID *Data,
+ IN VOID *DataMask,
+ IN UINT64 Delay,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+VOID
+LibAmdPciReadBits (
+ IN PCI_ADDR Address,
+ IN UINT8 Highbit,
+ IN UINT8 Lowbit,
+ OUT UINT32 *Value,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ );
+
+VOID
+LibAmdPciWriteBits (
+ IN PCI_ADDR Address,
+ IN UINT8 Highbit,
+ IN UINT8 Lowbit,
+ IN UINT32 *Value,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ );
+
+VOID
+LibAmdPciFindNextCap (
+ IN OUT PCI_ADDR *Address,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ );
+
+// CPUID
+VOID
+LibAmdCpuidRead (
+ IN UINT32 CpuidFcnAddress,
+ OUT CPUID_DATA *Value,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+// Utility Functions
+VOID
+LibAmdMemFill (
+ IN VOID *Destination,
+ IN UINT8 Value,
+ IN UINTN FillLength,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+VOID
+LibAmdMemCopy (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN CopyLength,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+VOID *
+LibAmdLocateImage (
+ IN VOID *StartAddress,
+ IN VOID *EndAddress,
+ IN UINT32 Alignment,
+ IN CHAR8 ModuleSignature[8]
+ );
+
+UINT32
+LibAmdGetPackageType (
+ IN AMD_CONFIG_PARAMS *StdHeader
+ );
+
+BOOLEAN
+LibAmdVerifyImageChecksum (
+ IN VOID *ImagePtr
+ );
+
+UINT8
+LibAmdBitScanReverse (
+ IN UINT32 value
+ );
+UINT8
+LibAmdBitScanForward (
+ IN UINT32 value
+ );
+
+VOID
+LibAmdReadCpuReg (
+ IN UINT8 RegNum,
+ OUT UINT32 *Value
+ );
+VOID
+LibAmdWriteCpuReg (
+ IN UINT8 RegNum,
+ IN UINT32 Value
+ );
+
+VOID
+LibAmdWriteBackInvalidateCache (
+ IN VOID
+ );
+
+VOID
+LibAmdSimNowEnterDebugger (VOID);
+
+VOID
+LibAmdHDTBreakPoint (VOID);
+
+UINT8
+LibAmdAccessWidth (
+ IN ACCESS_WIDTH AccessWidth
+ );
+
+VOID
+LibAmdCLFlush (
+ IN UINT64 Address,
+ IN UINT8 Count
+ );
+
+VOID F10RevDProbeFilterCritical (
+ IN PCI_ADDR PciAddress,
+ IN UINT32 PciRegister
+ );
+VOID
+IdsOutPort (
+ IN UINT32 Addr,
+ IN UINT32 Value,
+ IN UINT32 Flag
+ );
+
+VOID
+StopHere (
+ VOID
+ );
+
+VOID
+CpuidRead (
+ IN UINT32 CpuidFcnAddress,
+ OUT CPUID_DATA *Value
+ );
+
+UINT8
+ReadNumberOfCpuCores(
+ VOID
+ );
+
+#endif // _AMD_LIB_H_
diff --git a/src/vendorcode/amd/agesa/Lib/helper.c b/src/vendorcode/amd/agesa/Lib/helper.c
new file mode 100644
index 0000000000..baf661c009
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Lib/helper.c
@@ -0,0 +1,68 @@
+/*
+ *****************************************************************************
+ *
+ * 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+// helper.c - these functions are compiled separately because they redefine
+// functions invoked directly by the compiler code generator.
+// The Microsoft tools do not allow such functions to be compiled
+// with the "Enable link-time code generation (/GL)" option. Compile
+// this module without /GL to avoid a build failure LNK1237.
+//
+
+#if defined (_MSC_VER)
+
+#include "Porting.h"
+
+//---------------------------------------------------------------------------
+void *memcpy (void *dest, const void *src, size_t bytes)
+ {
+ // Rep movsb is faster than a byte loop, but still quite slow
+ // for large operations. However, it is a good choice here because
+ // this function is intended for use by the compiler only. For
+ // large copy operations, call LibAmdMemCopy.
+ __movsb (dest, src, bytes);
+ return dest;
+ }
+
+//---------------------------------------------------------------------------
+
+void *memset (void *dest, int value, size_t bytes)
+ {
+ // Rep stosb is faster than a byte loop, but still quite slow
+ // for large operations. However, it is a good choice here because
+ // this function is intended for use by the compiler only. For
+ // large fill operations, call LibAmdMemFill.
+ __stosb (dest, value, bytes);
+ return dest;
+ }
+//---------------------------------------------------------------------------
+
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/agesa/Lib/x64/amdlib64.asm b/src/vendorcode/amd/agesa/Lib/x64/amdlib64.asm
new file mode 100644
index 0000000000..abc1179903
--- /dev/null
+++ b/src/vendorcode/amd/agesa/Lib/x64/amdlib64.asm
@@ -0,0 +1,591 @@
+;/**
+; * @file
+; *
+; * Agesa library 64bit
+; *
+; * Contains AMD AGESA Library
+; *
+; * @xrefitem bom "File Content Label" "Release Content"
+; * @e project: AGESA
+; * @e sub-project: Lib
+; * @e \$Revision: 17071 $ @e \$Date: 2009-07-30 10:13:11 -0700 (Thu, 30 Jul 2009) $
+; */
+;*****************************************************************************
+;
+; 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.
+;
+;*****************************************************************************
+
+.code
+;/*++
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Write IO byte
+; *
+; * @param[in] CX IO port address
+; * @param[in] DL IO port Value
+; */
+
+PUBLIC WriteIo8
+WriteIo8 PROC
+ mov al, dl
+ mov dx, cx
+ out dx, al
+ ret
+WriteIo8 ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Write IO word
+; *
+; * @param[in] CX IO port address
+; * @param[in] DX IO port Value
+; */
+PUBLIC WriteIo16
+WriteIo16 PROC
+ mov ax, dx
+ mov dx, cx
+ out dx, ax
+ ret
+WriteIo16 ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Write IO dword
+; *
+; * @param[in] CX IO port address
+; * @param[in] EDX IO port Value
+; */
+
+PUBLIC WriteIo32
+WriteIo32 PROC
+ mov eax, edx
+ mov dx, cx
+ out dx, eax
+ ret
+WriteIo32 ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Read IO byte
+; *
+; * @param[in] CX IO port address
+; * @retval AL IO port Value
+; */
+PUBLIC ReadIo8
+ReadIo8 PROC
+ mov dx, cx
+ in al, dx
+ ret
+ReadIo8 ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Read IO word
+; *
+; * @param[in] CX IO port address
+; * @retval AX IO port Value
+; */
+PUBLIC ReadIo16
+ReadIo16 PROC
+ mov dx, cx
+ in ax, dx
+ ret
+ReadIo16 ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Read IO dword
+; *
+; * @param[in] CX IO port address
+; * @retval EAX IO port Value
+; */
+PUBLIC ReadIo32
+ReadIo32 PROC
+ mov dx, cx
+ in eax, dx
+ ret
+ReadIo32 ENDP
+
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Read MSR
+; *
+; * @param[in] RCX MSR Address
+; * @param[in] RDX Pointer to data
+; * @param[in] R8D ConfigPtr (Optional)
+; */
+PUBLIC LibAmdMsrRead
+LibAmdMsrRead PROC
+ push rsi
+ mov rsi, rdx
+ rdmsr
+ mov [rsi], eax
+ mov [rsi+4], edx
+ pop rsi
+ ret
+LibAmdMsrRead ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Write MSR
+; *
+; * @param[in] RCX MSR Address
+; * @param[in] RDX Pointer to data
+; * @param[in] R8D ConfigPtr (Optional)
+; */
+PUBLIC LibAmdMsrWrite
+LibAmdMsrWrite PROC
+ push rsi
+ mov rsi, rdx
+ mov eax, [rsi]
+ and rax, 0ffffffffh
+ mov edx, [rsi+4]
+ and rdx, 0ffffffffh
+ wrmsr
+ pop rsi
+ ret
+LibAmdMsrWrite ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Read CPUID
+; *
+; * @param[in] RCX CPUID function
+; * @param[in] RDX Pointer to CPUID_DATA to save cpuid data
+; * @param[in] R8D ConfigPtr (Optional)
+; */
+PUBLIC LibAmdCpuidRead
+LibAmdCpuidRead PROC
+
+ push rbx
+ push rsi
+ mov rsi, rdx
+ mov rax, rcx
+ cpuid
+ mov [rsi], eax
+ mov [rsi+4], ebx
+ mov [rsi+8], ecx
+ mov [rsi+12],edx
+ pop rsi
+ pop rbx
+ ret
+
+LibAmdCpuidRead ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Read TSC
+; *
+; *
+; * @retval RAX Time stamp counter value
+; */
+
+PUBLIC ReadTSC
+ReadTSC PROC
+ rdtsc
+ and rax, 0ffffffffh
+ shl rdx, 32
+ or rax, rdx
+ ret
+ReadTSC ENDP
+
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Read memory/MMIO byte
+; *
+; * @param[in] RCX - Memory Address
+; * @retval Memory byte at given address
+; */
+PUBLIC Read64Mem8
+Read64Mem8 PROC
+
+ xor rax, rax
+ mov al, [rcx]
+ ret
+
+Read64Mem8 ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Read memory/MMIO word
+; *
+; * @param[in] RCX - Memory Address
+; * @retval Memory word at given address
+; */
+PUBLIC Read64Mem16
+Read64Mem16 PROC
+
+ xor rax, rax
+ mov ax, [rcx]
+ ret
+
+Read64Mem16 ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Read memory/MMIO dword
+; *
+; * @param[in] RCX - Memory Address
+; * @retval Memory dword at given address
+; */
+PUBLIC Read64Mem32
+Read64Mem32 PROC
+
+ xor rax, rax
+ mov eax, [rcx]
+ ret
+
+Read64Mem32 ENDP
+
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Write memory/MMIO byte
+; *
+; * @param[in] RCX Memory Address
+; * @param[in] DL Value to write
+; */
+
+PUBLIC Write64Mem8
+Write64Mem8 PROC
+
+ xor rax, rax
+ mov rax, rdx
+ mov [rcx], al
+ ret
+
+Write64Mem8 ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Write memory/MMIO word
+; *
+; * @param[in] RCX Memory Address
+; * @param[in] DX Value to write
+; */
+PUBLIC Write64Mem16
+Write64Mem16 PROC
+
+ xor rax, rax
+ mov rax, rdx
+ mov [rcx], ax
+ ret
+
+Write64Mem16 ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Write memory/MMIO dword
+; *
+; * @param[in] RCX Memory Address
+; * @param[in] EDX Value to write
+; */
+PUBLIC Write64Mem32
+Write64Mem32 PROC
+
+ xor rax, rax
+ mov rax, rdx
+ mov [rcx], eax
+ ret
+
+Write64Mem32 ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Read various CPU registers
+; *
+; * @param[in] CL Register ID (0/4 - CR0/CR4, 10h/11h/12h/13h/17h - DR0/DR1/DR2/DR3/DR7)
+; * @param[in] RDX Pointer to value
+; */
+
+PUBLIC LibAmdReadCpuReg
+LibAmdReadCpuReg PROC
+
+ push rax
+ xor rax, rax
+Reg00h:
+ cmp cl, 00h
+ jne Reg04h
+ mov rax, cr0
+ jmp RegRead
+Reg04h:
+ cmp cl, 04h
+ jne Reg10h
+ mov rax, cr4
+ jmp RegRead
+Reg10h:
+ cmp cl, 10h
+ jne Reg11h
+ mov rax, dr0
+ jmp RegRead
+Reg11h:
+ cmp cl, 11h
+ jne Reg12h
+ mov rax, dr1
+ jmp RegRead
+Reg12h:
+ cmp cl, 12h
+ jne Reg13h
+ mov rax, dr2
+ jmp RegRead
+Reg13h:
+ cmp cl, 13h
+ jne Reg17h
+ mov rax, dr3
+ jmp RegRead
+Reg17h:
+ cmp cl, 17h
+ jne RegRead
+ mov rax, dr7
+RegRead:
+ mov [rdx], eax
+ pop rax
+ ret
+LibAmdReadCpuReg ENDP
+
+
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Write various CPU registers
+; *
+; * @param[in] CL Register ID (0/4 - CR0/CR4, 10h/11h/12h/13h/17h - DR0/DR1/DR2/DR3/DR7)
+; * @param[in] RDX Value to write
+; */
+
+PUBLIC LibAmdWriteCpuReg
+LibAmdWriteCpuReg PROC
+
+ push rax
+Reg00h:
+ cmp cl, 00h
+ jne Reg04h
+ mov rax, cr0
+ mov eax, edx
+ mov cr0, rax
+ jmp Done
+Reg04h:
+ cmp cl, 04h
+ jne Reg10h
+ mov rax, cr4
+ mov eax, edx
+ mov cr4, rax
+ jmp Done
+Reg10h:
+ cmp cl, 10h
+ jne Reg11h
+ mov rax, dr0
+ mov eax, edx
+ mov dr0, rax
+ jmp Done
+Reg11h:
+ cmp cl, 11h
+ jne Reg12h
+ mov rax, dr1
+ mov eax, edx
+ mov dr1, rax
+ jmp Done
+Reg12h:
+ cmp cl, 12h
+ jne Reg13h
+ mov rax, dr2
+ mov eax, edx
+ mov dr2, rax
+ jmp Done
+Reg13h:
+ cmp cl, 13h
+ jne Reg17h
+ mov rax, dr3
+ mov eax, edx
+ mov dr3, rax
+ jmp Done
+Reg17h:
+ cmp cl, 17h
+ jne Done
+ mov rax, dr7
+ mov eax, edx
+ mov dr7, rax
+Done:
+ pop rax
+ ret
+LibAmdWriteCpuReg ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Write back invalidate caches using wbinvd.
+; *
+; *
+; *
+; */
+
+PUBLIC LibAmdWriteBackInvalidateCache
+LibAmdWriteBackInvalidateCache PROC
+ wbinvd
+ ret
+LibAmdWriteBackInvalidateCache ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Stop CPU
+; *
+; *
+; *
+; */
+
+PUBLIC StopHere
+StopHere PROC
+@@:
+ jmp short @b
+StopHere ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Enter debugger on SimNow
+; *
+; *
+; *
+; */
+PUBLIC LibAmdSimNowEnterDebugger
+LibAmdSimNowEnterDebugger PROC
+ pushfq
+ mov rax, 0BACCD00Bh ; Backdoor in SimNow
+ mov rbx, 2 ; Select breakpoint feature
+ cpuid
+@@:
+ jmp short @b
+ popfq
+ ret
+LibAmdSimNowEnterDebugger ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * IDS IO port write
+; *
+; * @param[in] ECX IO Port Address
+; * @param[in] EDX Value to write
+; * @param[in] R8D IDS flags
+; *
+; */
+
+PUBLIC IdsOutPort
+IdsOutPort PROC
+ push rbx
+ push rax
+
+ mov ebx, r8d
+ mov eax, edx
+ mov edx, ecx
+ out dx, eax
+
+ pop rax
+ pop rbx
+ ret
+IdsOutPort ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Force breakpoint on HDT
+; *
+; *
+; */
+PUBLIC LibAmdHDTBreakPoint
+LibAmdHDTBreakPoint PROC
+
+ push rbx
+
+ mov rcx, 0C001100Ah ;bit 0 = HDT redirect
+ mov rdi, 09C5A203Ah ;Password
+ rdmsr
+ and rax, 0ffffffffh
+ or rax, 1
+
+ wrmsr
+
+ mov rax, 0B2h ;Marker = B2
+ db 0F1h ;ICEBP
+
+ pop rbx
+ ret
+
+LibAmdHDTBreakPoint ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Find the most right hand side non-zero bit with
+; *
+; * @param[in] ECX Value
+; */
+PUBLIC LibAmdBitScanForward
+LibAmdBitScanForward PROC
+ bsf eax, ecx
+ jnz nonZeroSource
+ mov al,32
+nonZeroSource:
+ ret
+LibAmdBitScanForward ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Find the most left hand side non-zero bit.
+; *
+; * @param[in] ECX Value
+; */
+PUBLIC LibAmdBitScanReverse
+LibAmdBitScanReverse PROC
+ bsr eax, ecx
+ jnz nonZeroSource
+ mov al,0FFh
+nonZeroSource:
+ ret
+LibAmdBitScanReverse ENDP
+
+;/*---------------------------------------------------------------------------------------*/
+;/**
+; * Flush specified number of cache line
+; *
+; * @param[in] RCX Physical address to be flushed
+; * @param[in] DL number of cachelines to be flushed
+; */
+PUBLIC LibAmdCLFlush
+LibAmdCLFlush PROC
+ push rax
+ mov rax, rcx
+ movzx rcx, dl
+ @@:
+ mfence
+ clflush [rax]
+ mfence
+ add rax,64
+ loop @B
+ pop rax
+ ret
+LibAmdCLFlush ENDP
+
+END