diff options
author | efdesign98 <efdesign98@gmail.com> | 2011-06-16 16:35:54 -0700 |
---|---|---|
committer | Marc Jones <marcj303@gmail.com> | 2011-06-21 22:37:51 +0200 |
commit | b0969d65e675f7c7a3004fc3f6fc154f22e73d44 (patch) | |
tree | 7e11f186e900ce6fc77603515b85c2a4154c6849 /src/vendorcode/amd/agesa/f12/Lib | |
parent | d1cb0eecd130cb4259ce9fedb32ebcd9ada0d4b7 (diff) |
Add AMD Family 12 cpu Agesa code
This is the addition of the AMD Family 12 cpu code.
Change-Id: I3febc81e192b4e86bbd3e8d6e1da62a28598fa8c
Signed-off-by: Frank Vibrans<frank.vibrans@amd.com>
Signed-off-by: efdesign98 <efdesign98@gmail.com>
Reviewed-on: http://review.coreboot.org/40
Tested-by: build bot (Jenkins)
Reviewed-by: Marc Jones <marcj303@gmail.com>
Diffstat (limited to 'src/vendorcode/amd/agesa/f12/Lib')
-rwxr-xr-x | src/vendorcode/amd/agesa/f12/Lib/amdlib.c | 1340 | ||||
-rwxr-xr-x | src/vendorcode/amd/agesa/f12/Lib/amdlib.h | 419 | ||||
-rwxr-xr-x | src/vendorcode/amd/agesa/f12/Lib/helper.c | 68 |
3 files changed, 1827 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f12/Lib/amdlib.c b/src/vendorcode/amd/agesa/f12/Lib/amdlib.c new file mode 100755 index 0000000000..cb8f695a89 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Lib/amdlib.c @@ -0,0 +1,1340 @@ +/* $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: 48409 $ @e \$Date: 2011-03-09 01:19:40 +0800 (Wed, 09 Mar 2011) $ + * + */ +/* + ***************************************************************************** + * + * 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 = 0; + UINT32 TempMask = 0; + 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 = 0; + UINT32 TempMask = 0; + 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 = 0; + UINT32 TempMask = 0; + 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 = 0; + UINT32 TempMask = 0; + 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 | 0x0000400000000000ull; + 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); + } + IDS_HDT_CONSOLE (LIB_PCI_RD, "~PCI RD %08x = %08x\n", LegacyPciAccess, *(UINT32 *)Value); + } else { + // Setup the MMIO address + ASSERT ((MMIOAddress + MMIOSize) > (MMIOAddress + (PciAddress.AddressValue & 0x0FFFFFFF))); + MMIOAddress += (PciAddress.AddressValue & 0x0FFFFFFF); + LibAmdMemRead (AccessWidth, MMIOAddress, Value, StdHeader); + IDS_HDT_CONSOLE (LIB_PCI_RD, "~MMIO RD %08x = %08x\n", (UINT32) MMIOAddress, *(UINT32 *)Value); + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 | 0x0000400000000000ull; + 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); + } + IDS_HDT_CONSOLE (LIB_PCI_WR, "~PCI WR %08x = %08x\n", LegacyPciAccess, *(UINT32 *)Value); + } else { + // Setup the MMIO address + ASSERT ((MMIOAddress + MMIOSize) > (MMIOAddress + (PciAddress.AddressValue & 0x0FFFFFFF))); + MMIOAddress += (PciAddress.AddressValue & 0x0FFFFFFF); + LibAmdMemWrite (AccessWidth, MMIOAddress, Value, StdHeader); + IDS_HDT_CONSOLE (LIB_PCI_WR, "~MMIO WR %08x = %08x\n", (UINT32) MMIOAddress, *(UINT32 *)Value); + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 = 0; + UINT32 TempMask = 0; + 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 = 0; + UINT32 TempMask = 0; + 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 LocalMsrRegister; + + ASSERT (StdHeader != NULL); + + MmioIsEnabled = FALSE; + LibAmdMsrRead (MSR_MMIO_Cfg_Base, &LocalMsrRegister, StdHeader); + if ((LocalMsrRegister & BIT0) != 0) { + *MmioAddress = LocalMsrRegister & 0xFFFFFFFFFFF00000ull; + EncodedSize = (UINT32) ((LocalMsrRegister & 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/f12/Lib/amdlib.h b/src/vendorcode/amd/agesa/f12/Lib/amdlib.h new file mode 100755 index 0000000000..63cd659f58 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/Lib/amdlib.h @@ -0,0 +1,419 @@ +/* $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: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 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/f12/Lib/helper.c b/src/vendorcode/amd/agesa/f12/Lib/helper.c new file mode 100755 index 0000000000..baf661c009 --- /dev/null +++ b/src/vendorcode/amd/agesa/f12/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 |