From 7d94cf93eec15dfb8eef9cd044fe39319d4ee9bc Mon Sep 17 00:00:00 2001 From: zbao Date: Mon, 2 Jul 2012 14:19:14 +0800 Subject: AGESA F15tn: AMD family15 AGESA code for Trinity AMD AGESA code for trinity. Change-Id: I847a54b15e8ce03ad5dbc17b95ee6771a9da0592 Signed-off-by: Zheng Bao Signed-off-by: zbao Reviewed-on: http://review.coreboot.org/1155 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/vendorcode/amd/agesa/f15tn/Lib/amdlib.c | 1387 ++++++++++++++++++++ src/vendorcode/amd/agesa/f15tn/Lib/amdlib.h | 398 ++++++ src/vendorcode/amd/agesa/f15tn/Lib/helper.c | 68 + .../amd/agesa/f15tn/Lib/x64/amdlib64.asm | 629 +++++++++ 4 files changed, 2482 insertions(+) create mode 100644 src/vendorcode/amd/agesa/f15tn/Lib/amdlib.c create mode 100644 src/vendorcode/amd/agesa/f15tn/Lib/amdlib.h create mode 100644 src/vendorcode/amd/agesa/f15tn/Lib/helper.c create mode 100644 src/vendorcode/amd/agesa/f15tn/Lib/x64/amdlib64.asm (limited to 'src/vendorcode/amd/agesa/f15tn/Lib') diff --git a/src/vendorcode/amd/agesa/f15tn/Lib/amdlib.c b/src/vendorcode/amd/agesa/f15tn/Lib/amdlib.c new file mode 100644 index 0000000000..81ff635086 --- /dev/null +++ b/src/vendorcode/amd/agesa/f15tn/Lib/amdlib.c @@ -0,0 +1,1387 @@ +/* $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-08 11:19:40 -0600 (Tue, 08 Mar 2011) $ + * + */ +/* + ****************************************************************************** + * + * Copyright 2008 - 2011 ADVANCED MICRO DEVICES, INC. All Rights Reserved. + * + * AMD is granting you permission to use this software (the Materials) + * pursuant to the terms and conditions of your Software License Agreement + * with AMD. This header does *NOT* give you permission to use the Materials + * or any rights under AMD's intellectual property. Your use of any portion + * of these Materials shall constitute your acceptance of those terms and + * conditions. If you do not agree to the terms and conditions of the Software + * License Agreement, please do not use any portion of these Materials. + * + * CONFIDENTIALITY: The Materials and all other information, identified as + * confidential and provided to you by AMD shall be kept confidential in + * accordance with the terms and conditions of the Software License Agreement. + * + * LIMITATION OF LIABILITY: THE MATERIALS AND ANY OTHER RELATED INFORMATION + * PROVIDED TO YOU BY AMD ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF + * MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE, + * OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR USAGE OF TRADE. + * IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER + * (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS + * INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF AMD'S NEGLIGENCE, + * GROSS NEGLIGENCE, THE USE OF OR INABILITY TO USE THE MATERIALS OR ANY OTHER + * RELATED INFORMATION PROVIDED TO YOU BY AMD, EVEN IF AMD HAS BEEN ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE + * EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, + * THE ABOVE LIMITATION MAY NOT APPLY TO YOU. + * + * AMD does not assume any responsibility for any errors which may appear in + * the Materials or any other related information provided to you by AMD, or + * result from use of the Materials or any related information. + * + * You agree that you will not reverse engineer or decompile the Materials. + * + * NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any + * further information, software, technical information, know-how, or show-how + * available to you. Additionally, AMD retains the right to modify the + * Materials at any time, without notice, and is not obligated to provide such + * modified Materials to you. + * + * U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with + * "RESTRICTED RIGHTS." Use, duplication, or disclosure by the Government is + * subject to the restrictions as set forth in FAR 52.227-14 and + * DFAR252.227-7013, et seq., or its successor. Use of the Materials by the + * Government constitutes acknowledgement of AMD's proprietary rights in them. + * + * EXPORT ASSURANCE: You agree and certify that neither the Materials, nor any + * direct product thereof will be exported directly or indirectly, into any + * country prohibited by the United States Export Administration Act and the + * regulations thereunder, without the required authorization from the U.S. + * government nor will be used for any purpose prohibited by the same. + ****************************************************************************** + */ + +/*---------------------------------------------------------------------------------------- + * 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 + ); +VOID +IdsOutPort ( + IN UINT32 Addr, + IN UINT32 Value, + IN UINT32 Flag + ); + +VOID +CpuidRead ( + IN UINT32 CpuidFcnAddress, + OUT CPUID_DATA *Value + ); + +UINT8 +ReadNumberOfCpuCores( + VOID + ); + +/*---------------------------------------------------------------------------------------- + * 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 +} +#if 0 +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); +} +#endif +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); +} + +VOID +LibAmdFinit() +{ + /* TODO: finit */ + __asm__ volatile ("finit"); +} +/*---------------------------------------------------------------------------------------*/ +/** + * 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 = 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 | 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); + } + //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 | 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); + } + //IDS_HDT_CONSOLE (LIB_PCI_WR, "~PCI WR %08x = %08x\n", LegacyPciAccess, *(UINT32 *)Value); + //printk(BIOS_DEBUG, "~PCI WR %08x = %08x\n", LegacyPciAccess, *(UINT32 *)Value);; + //printk(BIOS_DEBUG, "LibAmdPciWrite\n"); + } 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); + //printk(BIOS_DEBUG, "~MMIO WR %08x = %08x\n", (UINT32) MMIOAddress, *(UINT32 *)Value); + //printk(BIOS_DEBUG, "LibAmdPciWrite mmio\n"); + } +} + +/*---------------------------------------------------------------------------------------*/ +/** + * 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 & 0xFFFFFFFFFFF00000; + 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/f15tn/Lib/amdlib.h b/src/vendorcode/amd/agesa/f15tn/Lib/amdlib.h new file mode 100644 index 0000000000..d95d22ec8d --- /dev/null +++ b/src/vendorcode/amd/agesa/f15tn/Lib/amdlib.h @@ -0,0 +1,398 @@ +/* $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: 63425 $ @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $ + * + */ +/* + ****************************************************************************** + * + * Copyright 2008 - 2012 ADVANCED MICRO DEVICES, INC. All Rights Reserved. + * + * AMD is granting you permission to use this software (the Materials) + * pursuant to the terms and conditions of your Software License Agreement + * with AMD. This header does *NOT* give you permission to use the Materials + * or any rights under AMD's intellectual property. Your use of any portion + * of these Materials shall constitute your acceptance of those terms and + * conditions. If you do not agree to the terms and conditions of the Software + * License Agreement, please do not use any portion of these Materials. + * + * CONFIDENTIALITY: The Materials and all other information, identified as + * confidential and provided to you by AMD shall be kept confidential in + * accordance with the terms and conditions of the Software License Agreement. + * + * LIMITATION OF LIABILITY: THE MATERIALS AND ANY OTHER RELATED INFORMATION + * PROVIDED TO YOU BY AMD ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF + * MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE, + * OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR USAGE OF TRADE. + * IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER + * (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS + * INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF AMD'S NEGLIGENCE, + * GROSS NEGLIGENCE, THE USE OF OR INABILITY TO USE THE MATERIALS OR ANY OTHER + * RELATED INFORMATION PROVIDED TO YOU BY AMD, EVEN IF AMD HAS BEEN ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE + * EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, + * THE ABOVE LIMITATION MAY NOT APPLY TO YOU. + * + * AMD does not assume any responsibility for any errors which may appear in + * the Materials or any other related information provided to you by AMD, or + * result from use of the Materials or any related information. + * + * You agree that you will not reverse engineer or decompile the Materials. + * + * NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any + * further information, software, technical information, know-how, or show-how + * available to you. Additionally, AMD retains the right to modify the + * Materials at any time, without notice, and is not obligated to provide such + * modified Materials to you. + * + * U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with + * "RESTRICTED RIGHTS." Use, duplication, or disclosure by the Government is + * subject to the restrictions as set forth in FAR 52.227-14 and + * DFAR252.227-7013, et seq., or its successor. Use of the Materials by the + * Government constitutes acknowledgement of AMD's proprietary rights in them. + * + * EXPORT ASSURANCE: You agree and certify that neither the Materials, nor any + * direct product thereof will be exported directly or indirectly, into any + * country prohibited by the United States Export Administration Act and the + * regulations thereunder, without the required authorization from the U.S. + * government nor will be used for any purpose prohibited by the same. + ****************************************************************************** + **/ + +#ifndef _AMD_LIB_H_ +#define _AMD_LIB_H_ + +#define IOCF8 0xCF8 +#define IOCFC 0xCFC + +// Reg Values for ReadCpuReg and WriteCpuReg +#define CR4_REG 0x04 +#define DR0_REG 0x10 +#define DR1_REG 0x11 +#define DR2_REG 0x12 +#define DR3_REG 0x13 +#define DR7_REG 0x17 + +// PROTOTYPES FOR amdlib32.asm +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 +LibAmdFinit ( + VOID); + +VOID +StopHere ( + VOID + ); + +#endif // _AMD_LIB_H_ diff --git a/src/vendorcode/amd/agesa/f15tn/Lib/helper.c b/src/vendorcode/amd/agesa/f15tn/Lib/helper.c new file mode 100644 index 0000000000..2c5de90b87 --- /dev/null +++ b/src/vendorcode/amd/agesa/f15tn/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 diff --git a/src/vendorcode/amd/agesa/f15tn/Lib/x64/amdlib64.asm b/src/vendorcode/amd/agesa/f15tn/Lib/x64/amdlib64.asm new file mode 100644 index 0000000000..467f4b7a3e --- /dev/null +++ b/src/vendorcode/amd/agesa/f15tn/Lib/x64/amdlib64.asm @@ -0,0 +1,629 @@ +;/** +; * @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 2008 - 2012 ADVANCED MICRO DEVICES, INC. All Rights Reserved. +; +; AMD is granting you permission to use this software (the Materials) +; pursuant to the terms and conditions of your Software License Agreement +; with AMD. This header does *NOT* give you permission to use the Materials +; or any rights under AMD's intellectual property. Your use of any portion +; of these Materials shall constitute your acceptance of those terms and +; conditions. If you do not agree to the terms and conditions of the Software +; License Agreement, please do not use any portion of these Materials. +; +; CONFIDENTIALITY: The Materials and all other information, identified as +; confidential and provided to you by AMD shall be kept confidential in +; accordance with the terms and conditions of the Software License Agreement. +; +; LIMITATION OF LIABILITY: THE MATERIALS AND ANY OTHER RELATED INFORMATION +; PROVIDED TO YOU BY AMD ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED +; WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF +; MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE, +; OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR USAGE OF TRADE. +; IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER +; (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS +; INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF AMD'S NEGLIGENCE, +; GROSS NEGLIGENCE, THE USE OF OR INABILITY TO USE THE MATERIALS OR ANY OTHER +; RELATED INFORMATION PROVIDED TO YOU BY AMD, EVEN IF AMD HAS BEEN ADVISED OF +; THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE +; EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, +; THE ABOVE LIMITATION MAY NOT APPLY TO YOU. +; +; AMD does not assume any responsibility for any errors which may appear in +; the Materials or any other related information provided to you by AMD, or +; result from use of the Materials or any related information. +; +; You agree that you will not reverse engineer or decompile the Materials. +; +; NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any +; further information, software, technical information, know-how, or show-how +; available to you. Additionally, AMD retains the right to modify the +; Materials at any time, without notice, and is not obligated to provide such +; modified Materials to you. +; +; U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with +; "RESTRICTED RIGHTS." Use, duplication, or disclosure by the Government is +; subject to the restrictions as set forth in FAR 52.227-14 and +; DFAR252.227-7013, et seq., or its successor. Use of the Materials by the +; Government constitutes acknowledgement of AMD's proprietary rights in them. +; +; EXPORT ASSURANCE: You agree and certify that neither the Materials, nor any +; direct product thereof will be exported directly or indirectly, into any +; country prohibited by the United States Export Administration Act and the +; regulations thereunder, without the required authorization from the U.S. +; government nor will be used for any purpose prohibited by the same. +;***************************************************************************** + +.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 + +;/*---------------------------------------------------------------------------------------*/ +;/** +; * FPU init +; * +; * +; */ +PUBLIC LibAmdFinit +LibAmdFinit PROC + finit + ret +LibAmdFinit ENDP + +END -- cgit v1.2.3