On 6/5/21 06:04, Leif Lindholm wrote: > On Wed, May 26, 2021 at 17:06:52 +0700, Nhi Pham wrote: >> From: Vu Nguyen >> >> This commit adds the support for Ampere’s Altra processor-based Mt. Jade >> platform that provides up to 160 processor cores in a dual socket >> configuration. The essential modules are wired up enough to boot system >> to EDK2 UiApp. >> >> Cc: Thang Nguyen >> Cc: Chuong Tran >> Cc: Phong Vo >> Cc: Leif Lindholm >> Cc: Michael D Kinney >> Cc: Ard Biesheuvel >> Cc: Nate DeSimone >> >> Signed-off-by: Vu Nguyen >> --- >> Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec | 28 + >> Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec | 42 ++ >> Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec | 46 ++ >> Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc | 674 +++++++++++++++++++ >> Platform/Ampere/JadePkg/Jade.dsc | 100 +++ >> Platform/Ampere/JadePkg/Jade.fdf | 225 +++++++ >> Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf | 41 ++ >> Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf | 64 ++ >> Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf | 44 ++ >> Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.inf | 57 ++ >> Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf | 37 + >> Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf | 63 ++ >> Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf | 35 + >> Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf | 32 + >> Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.inf | 42 ++ >> Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.inf | 29 + >> Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf | 30 + >> Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.inf | 29 + >> Silicon/Ampere/AmpereAltraPkg/Include/Guid/PlatformInfoHobGuid.h | 17 + >> Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h | 282 ++++++++ >> Silicon/Ampere/AmpereAltraPkg/Include/Library/MailboxInterfaceLib.h | 172 +++++ >> Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h | 19 + >> Silicon/Ampere/AmpereAltraPkg/Include/Library/NVParamLib.h | 133 ++++ >> Silicon/Ampere/AmpereAltraPkg/Include/Library/SystemFirmwareInterfaceLib.h | 282 ++++++++ >> Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h | 31 + >> Silicon/Ampere/AmpereAltraPkg/Include/MmLib.h | 79 +++ >> Silicon/Ampere/AmpereAltraPkg/Include/NVParamDef.h | 515 ++++++++++++++ >> Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h | 146 ++++ >> Silicon/Ampere/AmpereAltraPkg/Include/PlatformInfoHob.h | 182 +++++ >> Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.c | 52 ++ >> Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.c | 151 +++++ >> Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c | 706 ++++++++++++++++++++ >> Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c | 169 +++++ >> Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c | 399 +++++++++++ >> Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c | 282 ++++++++ >> Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.c | 93 +++ >> Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c | 184 +++++ >> Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.c | 202 ++++++ >> Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.c | 40 ++ >> Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.c | 141 ++++ >> Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.c | 328 +++++++++ >> Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.c | 63 ++ >> Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc | 176 +++++ >> Platform/Ampere/JadePkg/JadeBoardSetting.cfg | 209 ++++++ >> Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformHelper.S | 45 ++ >> Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.uni | 13 + >> 46 files changed, 6729 insertions(+) >> >> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc >> new file mode 100755 >> index 000000000000..f68af24a0d78 >> --- /dev/null >> +++ b/Platform/Ampere/JadePkg/Jade.dsc >> @@ -0,0 +1,100 @@ >> +## @file >> +# >> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
>> +# >> +# SPDX-License-Identifier: BSD-2-Clause-Patent >> +# >> +## >> + >> +################################################################################ >> +# >> +# Defines Section - statements that will be processed to create a Makefile. >> +# >> +################################################################################ >> +[Defines] >> + PLATFORM_NAME = Jade >> + PLATFORM_GUID = 7BDD00C0-68F3-4CC1-8775-F0F00572019F >> + PLATFORM_VERSION = 0.1 >> + DSC_SPECIFICATION = 0x0001001B >> + OUTPUT_DIRECTORY = Build/Jade >> + SUPPORTED_ARCHITECTURES = AARCH64 >> + BUILD_TARGETS = DEBUG|RELEASE|NOOPT >> + SKUID_IDENTIFIER = DEFAULT >> + FLASH_DEFINITION = Platform/Ampere/JadePkg/Jade.fdf >> + >> + # >> + # Defines for default states. These can be changed on the command line. >> + # -D FLAG=VALUE >> + # >> + >> + # DEBUG_INIT 0x00000001 // Initialization >> + # DEBUG_WARN 0x00000002 // Warnings >> + # DEBUG_LOAD 0x00000004 // Load events >> + # DEBUG_FS 0x00000008 // EFI File system >> + # DEBUG_POOL 0x00000010 // Alloc & Free (pool) >> + # DEBUG_PAGE 0x00000020 // Alloc & Free (page) >> + # DEBUG_INFO 0x00000040 // Informational debug messages >> + # DEBUG_DISPATCH 0x00000080 // PEI/DXE/SMM Dispatchers >> + # DEBUG_VARIABLE 0x00000100 // Variable >> + # DEBUG_BM 0x00000400 // Boot Manager >> + # DEBUG_BLKIO 0x00001000 // BlkIo Driver >> + # DEBUG_NET 0x00004000 // SNP Driver >> + # DEBUG_UNDI 0x00010000 // UNDI Driver >> + # DEBUG_LOADFILE 0x00020000 // LoadFile >> + # DEBUG_EVENT 0x00080000 // Event messages >> + # DEBUG_GCD 0x00100000 // Global Coherency Database changes >> + # DEBUG_CACHE 0x00200000 // Memory range cachability changes >> + # DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may >> + # // significantly impact boot performance >> + # DEBUG_ERROR 0x80000000 // Error >> + DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x8000000F >> + DEFINE FIRMWARE_VER = 0.01.001 >> + DEFINE EDK2_SKIP_PEICORE = TRUE >> + DEFINE SECURE_BOOT_ENABLE = FALSE >> + DEFINE INCLUDE_TFTP_COMMAND = TRUE >> + >> + # >> + # Network definition >> + # >> + DEFINE NETWORK_IP6_ENABLE = FALSE >> + DEFINE NETWORK_HTTP_BOOT_ENABLE = TRUE >> + DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS = TRUE >> + DEFINE NETWORK_TLS_ENABLE = FALSE >> + > You'll want to include that !include MdePkg/MdeLibs.dsc.inc bit > somewhere here. > >> +# Include default Ampere Platform DSC file >> +!include Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc >> + >> +################################################################################ >> +# >> +# Specific Platform Library >> +# >> +################################################################################ >> +[LibraryClasses] >> + # >> + # RTC Library: Common RTC >> + # >> + RealTimeClockLib|EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf >> + >> +################################################################################ >> +# >> +# Specific Platform Pcds >> +# >> +################################################################################ >> +[PcdsFeatureFlag.common] >> +[PcdsFixedAtBuild.common] >> + >> +!if $(SECURE_BOOT_ENABLE) == TRUE >> + # Override the default values from SecurityPkg to ensure images >> + # from all sources are verified in secure boot >> + gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04 >> + gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x04 >> + gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04 >> +!endif >> + >> + >> +################################################################################ >> +# >> +# Specific Platform Component >> +# >> +################################################################################ >> +[Components.common] > > >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h >> new file mode 100644 >> index 000000000000..de576474fb48 >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h >> @@ -0,0 +1,282 @@ >> +/** @file >> + >> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
>> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#ifndef AMPERE_CPU_LIB_H_ >> +#define AMPERE_CPU_LIB_H_ >> + >> +/* Ctypen, bits[3(n - 1) + 2 : 3(n - 1)], for n = 1 to 7 */ >> +#define CLIDR_CTYPE_SHIFT(Level) (3 * (Level - 1)) >> +#define CLIDR_CTYPE_MASK(Level) (7 << CLIDR_CTYPE_SHIFT(Level)) >> +#define CLIDR_CTYPE(Clidr, Level) \ >> + (((Clidr) & CLIDR_CTYPE_MASK(Level)) >> CLIDR_CTYPE_SHIFT(Level)) >> + >> +#define CCSIDR_NUMSETS_SHIFT 13 >> +#define CCSIDR_NUMSETS_MASK 0xFFFE000 >> +#define CCSIDR_NUMSETS(Ccsidr) \ >> + (((Ccsidr) & CCSIDR_NUMSETS_MASK) >> CCSIDR_NUMSETS_SHIFT) >> +#define CCSIDR_ASSOCIATIVITY_SHIFT 3 >> +#define CCSIDR_ASSOCIATIVITY_MASK 0x1FF8 >> +#define CCSIDR_ASSOCIATIVITY(Ccsidr) \ >> + (((Ccsidr) & CCSIDR_ASSOCIATIVITY_MASK) >> CCSIDR_ASSOCIATIVITY_SHIFT) >> +#define CCSIDR_LINE_SIZE_SHIFT 0 >> +#define CCSIDR_LINE_SIZE_MASK 0x7 >> +#define CCSIDR_LINE_SIZE(Ccsidr) \ >> + (((Ccsidr) & CCSIDR_LINE_SIZE_MASK) >> CCSIDR_LINE_SIZE_SHIFT) > All of the above (CLIDR/CCSIDR) are architectural. > We've also developed some new accessors and stuff for these, as part > of ArmPkg/Universal/SmbiosDxe work that's gone on since v1 of this set. > We may need to clean some interfaces up, but ideally I'd prefer if you > could use some accessors from ArmLib or such. > >> + >> +#define SUBNUMA_MODE_MONOLITHIC 0 >> +#define SUBNUMA_MODE_HEMISPHERE 1 >> +#define SUBNUMA_MODE_QUADRANT 2 >> + >> +#define MONOLITIC_NUM_OF_REGION 1 >> +#define HEMISPHERE_NUM_OF_REGION 2 >> +#define QUADRANT_NUM_OF_REGION 4 >> +#define SUBNUMA_CPM_REGION_SIZE 4 >> +#define NUM_OF_CPM_PER_MESH_ROW 8 >> + >> +#define CPM_PER_ROW_OFFSET(CpmId) ((CpmId) % NUM_OF_CPM_PER_MESH_ROW) >> +#define CPM_ROW_NUMBER(CpmId) ((CpmId) / NUM_OF_CPM_PER_MESH_ROW) >> + >> +#define SOCKET_ID(CpuId) ((CpuId) / (PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM)) >> +#define CLUSTER_ID(CpuId) (((CpuId) / PLATFORM_CPU_NUM_CORES_PER_CPM) % PLATFORM_CPU_MAX_CPM) >> + >> + >> +/** >> + Get the SubNUMA mode. >> + >> + @return UINT8 The SubNUMA mode. >> + >> +**/ >> +UINT8 >> +EFIAPI >> +CpuGetSubNumaMode ( >> + VOID >> + ); >> + >> +/** >> + Get the number of SubNUMA region. >> + >> + @return UINT8 The number of SubNUMA region. >> + >> +**/ >> +UINT8 >> +EFIAPI >> +CpuGetNumberOfSubNumaRegion ( >> + VOID >> + ); >> + >> +/** >> + Get the SubNUMA node of a CPM. >> + >> + @param SocketId Socket index. >> + @param Cpm CPM index. >> + @return UINT8 The SubNUMA node of a CPM. >> + >> +**/ >> +UINT8 >> +EFIAPI >> +CpuGetSubNumNode ( >> + UINT8 Socket, >> + UINT16 Cpm >> + ); >> + >> +/** >> + Get the associativity of cache. >> + >> + @param Level Cache level. >> + @return UINT32 Associativity of cache. >> + >> +**/ >> +UINT32 >> +EFIAPI >> +CpuGetAssociativity ( >> + UINT32 Level >> + ); >> + >> +/** >> + Get the cache size. >> + >> + @param Level Cache level. >> + @return UINT32 Cache size. >> + >> +**/ >> +UINT32 >> +EFIAPI >> +CpuGetCacheSize ( >> + UINT32 Level >> + ); >> + >> +/** >> + Get the number of supported socket. >> + >> + @return UINT8 Number of supported socket. >> + >> +**/ >> +UINT8 >> +EFIAPI >> +GetNumberOfSupportedSockets ( >> + VOID >> + ); >> + >> +/** >> + Get the number of active socket. >> + >> + @return UINT8 Number of active socket. >> + >> +**/ >> +UINT8 >> +EFIAPI >> +GetNumberOfActiveSockets ( >> + VOID >> + ); >> + >> +/** >> + Get the number of active CPM per socket. >> + >> + @param SocketId Socket index. >> + @return UINT16 Number of CPM. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +GetNumberOfActiveCPMsPerSocket ( >> + UINT8 SocketId >> + ); >> + >> +/** >> + Get the number of configured CPM per socket. >> + >> + @param SocketId Socket index. >> + @return UINT16 Number of configured CPM. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +GetNumberOfConfiguredCPMs ( >> + UINT8 SocketId >> + ); >> + >> +/** >> + Set the number of configured CPM per socket. >> + >> + @param SocketId Socket index. >> + @param NumberOfCPMs Number of CPM to be configured. >> + @return EFI_SUCCESS Operation succeeded. >> + @return Others An error has occurred. >> + >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SetNumberOfConfiguredCPMs ( >> + UINT8 SocketId, >> + UINT16 NumberOfCPMs >> + ); >> + >> +/** >> + Get the maximum number of core per socket. This number >> + should be the same for all sockets. >> + >> + @return UINT16 Maximum number of core. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +GetMaximumNumberOfCores ( >> + VOID >> + ); >> + >> +/** >> + Get the maximum number of CPM per socket. This number >> + should be the same for all sockets. >> + >> + @return UINT32 Maximum number of CPM. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +GetMaximumNumberOfCPMs ( >> + VOID >> + ); >> + >> +/** >> + Get the number of active cores of a sockets. >> + >> + @return UINT16 Number of active core. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +GetNumberOfActiveCoresPerSocket ( >> + UINT8 SocketId >> + ); >> + >> +/** >> + Get the number of active cores of all socket. >> + >> + @return UINT16 Number of active core. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +GetNumberOfActiveCores ( >> + VOID >> + ); >> + >> +/** >> + Check if the logical CPU is enabled or not. >> + >> + @param CpuId The logical Cpu ID. Started from 0. >> + @return BOOLEAN TRUE if the Cpu enabled >> + FALSE if the Cpu disabled. >> + >> +**/ >> +BOOLEAN >> +EFIAPI >> +IsCpuEnabled ( >> + UINT16 CpuId >> + ); >> + >> + >> +/** >> + Check if the slave socket is present >> + >> + @return BOOLEAN TRUE if the Slave Cpu is present >> + FALSE if the Slave Cpu is not present >> + >> +**/ >> +BOOLEAN >> +EFIAPI >> +IsSlaveSocketPresent ( >> + VOID >> + ); >> + >> +/** >> + Check if the slave socket is active >> + >> + @return BOOLEAN TRUE if the Slave CPU Socket is active. >> + FALSE if the Slave CPU Socket is not active. >> + >> +**/ >> +BOOLEAN >> +EFIAPI >> +IsSlaveSocketActive ( >> + VOID >> + ); >> + >> +/** >> + Check if the CPU product ID is Ac01 >> + @return BOOLEAN TRUE if the Product ID is Ac01 >> + FALSE otherwise. >> + >> +**/ >> +BOOLEAN >> +EFIAPI >> +IsAc01Processor ( >> + VOID >> + ); >> + >> +#endif /* AMPERE_CPU_LIB_H_ */ > >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c >> new file mode 100644 >> index 000000000000..8da698e0b855 >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c >> @@ -0,0 +1,706 @@ >> +/** @file >> + >> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
>> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#include >> +#include >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +STATIC PLATFORM_INFO_HOB *mPlatformInfoHob = NULL; >> + >> +PLATFORM_INFO_HOB * >> +GetPlatformHob ( >> + VOID >> + ) >> +{ >> + VOID *Hob; >> + >> + if (mPlatformInfoHob == NULL) { >> + Hob = GetNextGuidHob ( >> + &gPlatformHobGuid, >> + (CONST VOID *)FixedPcdGet64 (PcdSystemMemoryBase) >> + ); >> + ASSERT (Hob != NULL); >> + if (Hob == NULL) { >> + DEBUG ((DEBUG_ERROR, "%a: Failed to get gPlatformHobGuid!\n", __FUNCTION__)); >> + return NULL; >> + } >> + >> + mPlatformInfoHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob); >> + } >> + >> + return mPlatformInfoHob; >> +} >> + >> +/** >> + Get the SubNUMA mode. >> + >> + @return UINT8 The SubNUMA mode. >> + >> +**/ >> +UINT8 >> +EFIAPI >> +CpuGetSubNumaMode ( >> + VOID >> + ) >> +{ >> + PLATFORM_INFO_HOB *PlatformHob; >> + >> + PlatformHob = GetPlatformHob (); >> + if (PlatformHob == NULL) { >> + return SUBNUMA_MODE_MONOLITHIC; >> + } >> + >> + return PlatformHob->SubNumaMode[0]; >> +} >> + >> +/** >> + Get the number of SubNUMA region. >> + >> + @return UINT8 The number of SubNUMA region. >> + >> +**/ >> +UINT8 >> +EFIAPI >> +CpuGetNumberOfSubNumaRegion ( >> + VOID >> + ) >> +{ >> + UINT8 SubNumaMode; >> + UINT8 NumberOfSubNumaRegion; >> + >> + SubNumaMode = CpuGetSubNumaMode (); >> + ASSERT (SubNumaMode <= SUBNUMA_MODE_QUADRANT); >> + >> + switch (SubNumaMode) { >> + case SUBNUMA_MODE_MONOLITHIC: >> + NumberOfSubNumaRegion = MONOLITIC_NUM_OF_REGION; >> + break; >> + >> + case SUBNUMA_MODE_HEMISPHERE: >> + NumberOfSubNumaRegion = HEMISPHERE_NUM_OF_REGION; >> + break; >> + >> + case SUBNUMA_MODE_QUADRANT: >> + NumberOfSubNumaRegion = QUADRANT_NUM_OF_REGION; >> + break; >> + >> + default: >> + // Should never reach there. >> + ASSERT (FALSE); >> + break; >> + } >> + >> + return NumberOfSubNumaRegion; >> +} >> + >> +/** >> + Get the SubNUMA node of a CPM. >> + >> + @param SocketId Socket index. >> + @param Cpm CPM index. >> + @return UINT8 The SubNUMA node of a CPM. >> + >> +**/ >> +UINT8 >> +EFIAPI >> +CpuGetSubNumNode ( >> + UINT8 SocketId, >> + UINT16 Cpm >> + ) >> +{ >> + BOOLEAN IsAsymMesh; >> + UINT8 SubNumaNode; >> + UINT16 MaxNumberOfCPM; >> + UINT8 MiddleRow; >> + UINT8 QuadrantHigherRowNodeNumber[NUM_OF_CPM_PER_MESH_ROW] = {1, 1, 1, 1, 3, 3, 3, 3}; >> + UINT8 QuadrantLowerRowNodeNumber[NUM_OF_CPM_PER_MESH_ROW] = {0, 0, 0, 0, 2, 2, 2, 2}; >> + UINT8 QuadrantMiddleRowNodeNumber[NUM_OF_CPM_PER_MESH_ROW] = {0, 0, 1, 1, 3, 3, 2, 2}; >> + UINT8 SubNumaMode; >> + >> + MaxNumberOfCPM = GetMaximumNumberOfCPMs (); >> + SubNumaMode = CpuGetSubNumaMode (); >> + ASSERT (SubNumaMode <= SUBNUMA_MODE_QUADRANT); >> + >> + switch (SubNumaMode) { >> + case SUBNUMA_MODE_MONOLITHIC: >> + SubNumaNode = (SocketId == 0) ? 0 : 1; >> + break; >> + >> + case SUBNUMA_MODE_HEMISPHERE: >> + if (CPM_PER_ROW_OFFSET (Cpm) >= SUBNUMA_CPM_REGION_SIZE) { >> + SubNumaNode = 1; >> + } else { >> + SubNumaNode = 0; >> + } >> + >> + if (SocketId == 1) { >> + SubNumaNode += HEMISPHERE_NUM_OF_REGION; >> + } >> + break; >> + >> + case SUBNUMA_MODE_QUADRANT: >> + // >> + // CPM Mesh Rows >> + // >> + // |---------------------------------------| >> + // | 00 ----------- 03 | 04 ----------- 07 | Row 0 >> + // |-------------------|-------------------| >> + // | 08 ----------- 11 | 12 ----------- 15 | Row 1 >> + // |-------------------|-------------------| >> + // | 16 - 17 | 18 - 19 | 20 - 21 | 22 - 23 | Middle Row >> + // |-------------------|-------------------| >> + // | 24 ----------- 27 | 28 ----------- 31 | Row 3 >> + // |-------------------|-------------------| >> + // | 32 ----------- 35 | 36 ----------- 39 | Row 4 >> + // |---------------------------------------| >> + // >> + >> + IsAsymMesh = (BOOLEAN)(CPM_ROW_NUMBER (MaxNumberOfCPM) % 2 != 0); >> + MiddleRow = CPM_ROW_NUMBER (MaxNumberOfCPM) / 2; >> + if (IsAsymMesh >> + && CPM_ROW_NUMBER (Cpm) == MiddleRow) >> + { >> + SubNumaNode = QuadrantMiddleRowNodeNumber[CPM_PER_ROW_OFFSET (Cpm)]; >> + >> + } else if (CPM_ROW_NUMBER (Cpm) >= MiddleRow) { >> + SubNumaNode = QuadrantHigherRowNodeNumber[CPM_PER_ROW_OFFSET (Cpm)]; >> + >> + } else { >> + SubNumaNode = QuadrantLowerRowNodeNumber[CPM_PER_ROW_OFFSET (Cpm)]; >> + } >> + >> + if (SocketId == 1) { >> + SubNumaNode += QUADRANT_NUM_OF_REGION; >> + } >> + break; >> + >> + default: >> + // Should never reach there. >> + ASSERT (FALSE); >> + break; >> + } >> + >> + return SubNumaNode; >> +} >> + >> +/** >> + Get the associativity of cache. >> + >> + @param Level Cache level. >> + @return UINT32 Associativity of cache. >> + >> +**/ >> +UINT32 >> +EFIAPI >> +CpuGetAssociativity ( >> + UINT32 Level >> + ) >> +{ > I do feel some of this stuff could be replaced by the common functions > we now have in ArmLib (that we didn't when v1 went out). > >> + UINT64 CacheCCSIDR; >> + UINT64 CacheCLIDR; >> + UINT32 Value = 0x2; /* Unknown Set-Associativity */ >> + >> + CacheCLIDR = ReadCLIDR (); >> + if (!CLIDR_CTYPE (CacheCLIDR, Level)) { >> + return Value; >> + } >> + >> + CacheCCSIDR = ReadCCSIDR (Level); >> + switch (CCSIDR_ASSOCIATIVITY (CacheCCSIDR)) { >> + case 0: >> + /* Direct mapped */ >> + Value = 0x3; >> + break; >> + >> + case 1: >> + /* 2-way Set-Associativity */ >> + Value = 0x4; >> + break; >> + >> + case 3: >> + /* 4-way Set-Associativity */ >> + Value = 0x5; >> + break; >> + >> + case 7: >> + /* 8-way Set-Associativity */ >> + Value = 0x7; >> + break; >> + >> + case 15: >> + /* 16-way Set-Associativity */ >> + Value = 0x8; >> + break; >> + >> + case 11: >> + /* 12-way Set-Associativity */ >> + Value = 0x9; >> + break; >> + >> + case 23: >> + /* 24-way Set-Associativity */ >> + Value = 0xA; >> + break; >> + >> + case 31: >> + /* 32-way Set-Associativity */ >> + Value = 0xB; >> + break; >> + >> + case 47: >> + /* 48-way Set-Associativity */ >> + Value = 0xC; >> + break; >> + >> + case 63: >> + /* 64-way Set-Associativity */ >> + Value = 0xD; >> + break; >> + >> + case 19: >> + /* 20-way Set-Associativity */ >> + Value = 0xE; >> + break; >> + } >> + >> + return Value; >> +} >> + >> +/** >> + Get the cache size. >> + >> + @param Level Cache level. >> + @return UINT32 Cache size. >> + >> +**/ >> +UINT32 >> +EFIAPI >> +CpuGetCacheSize ( >> + UINT32 Level >> + ) >> +{ >> + UINT32 CacheLineSize; >> + UINT32 Count; >> + UINT64 CacheCCSIDR; >> + UINT64 CacheCLIDR; >> + >> + CacheCLIDR = ReadCLIDR (); >> + if (!CLIDR_CTYPE (CacheCLIDR, Level)) { >> + return 0; >> + } >> + >> + CacheCCSIDR = ReadCCSIDR (Level); >> + CacheLineSize = 1; >> + Count = CCSIDR_LINE_SIZE (CacheCCSIDR) + 4; >> + while (Count-- > 0) { >> + CacheLineSize *= 2; >> + } >> + >> + return ((CCSIDR_NUMSETS (CacheCCSIDR) + 1) * >> + (CCSIDR_ASSOCIATIVITY (CacheCCSIDR) + 1) * >> + CacheLineSize); >> +} >> + >> +/** >> + Get the number of supported socket. >> + >> + @return UINT8 Number of supported socket. >> + >> +**/ >> +UINT8 >> +EFIAPI >> +GetNumberOfSupportedSockets ( >> + VOID >> + ) >> +{ >> + PLATFORM_INFO_HOB *PlatformHob; >> + >> + PlatformHob = GetPlatformHob (); >> + if (PlatformHob == NULL) { >> + // >> + // By default, the number of supported sockets is 1. >> + // >> + return 1; >> + } >> + >> + return (sizeof (PlatformHob->ClusterEn) / sizeof (PLATFORM_CLUSTER_EN)); >> +} >> + >> +/** >> + Get the number of active socket. >> + >> + @return UINT8 Number of active socket. >> + >> +**/ >> +UINT8 >> +EFIAPI >> +GetNumberOfActiveSockets ( >> + VOID >> + ) >> +{ >> + UINT8 NumberOfActiveSockets, Count, Index, Index1; >> + PLATFORM_CLUSTER_EN *Socket; >> + PLATFORM_INFO_HOB *PlatformHob; >> + >> + PlatformHob = GetPlatformHob (); >> + if (PlatformHob == NULL) { >> + // >> + // By default, the number of active sockets is 1. >> + // >> + return 1; >> + } >> + >> + NumberOfActiveSockets = 0; >> + >> + for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) { >> + Socket = &PlatformHob->ClusterEn[Index]; >> + Count = ARRAY_SIZE (Socket->EnableMask); >> + for (Index1 = 0; Index1 < Count; Index1++) { >> + if (Socket->EnableMask[Index1] != 0) { >> + NumberOfActiveSockets++; >> + break; >> + } >> + } >> + } >> + >> + return NumberOfActiveSockets; >> +} >> + >> +/** >> + Get the number of active CPM per socket. >> + >> + @param SocketId Socket index. >> + @return UINT16 Number of CPM. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +GetNumberOfActiveCPMsPerSocket ( >> + UINT8 SocketId >> + ) >> +{ >> + UINT16 NumberOfCPMs, Count, Index; >> + UINT32 Val32; >> + PLATFORM_CLUSTER_EN *Socket; >> + PLATFORM_INFO_HOB *PlatformHob; >> + >> + PlatformHob = GetPlatformHob (); >> + if (PlatformHob == NULL) { >> + return 0; >> + } >> + >> + if (SocketId >= GetNumberOfActiveSockets ()) { >> + return 0; >> + } >> + >> + NumberOfCPMs = 0; >> + Socket = &PlatformHob->ClusterEn[SocketId]; >> + Count = ARRAY_SIZE (Socket->EnableMask); >> + for (Index = 0; Index < Count; Index++) { >> + Val32 = Socket->EnableMask[Index]; >> + while (Val32 > 0) { >> + if ((Val32 & 0x1) != 0) { >> + NumberOfCPMs++; >> + } >> + Val32 >>= 1; >> + } >> + } >> + >> + return NumberOfCPMs; >> +} >> + >> +/** >> + Get the number of configured CPM per socket. This number >> + should be the same for all sockets. >> + >> + @param SocketId Socket index. >> + @return UINT8 Number of configured CPM. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +GetNumberOfConfiguredCPMs ( >> + UINT8 SocketId >> + ) >> +{ >> + EFI_STATUS Status; >> + UINT32 Value; >> + UINT32 Param, ParamStart, ParamEnd; >> + UINT16 Count; >> + >> + Count = 0; >> + ParamStart = NV_SI_S0_PCP_ACTIVECPM_0_31 + SocketId * NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32); >> + ParamEnd = ParamStart + NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32); >> + for (Param = ParamStart; Param < ParamEnd; Param += NV_PARAM_ENTRYSIZE) { >> + Status = NVParamGet ( >> + Param, >> + NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC, >> + &Value >> + ); >> + if (EFI_ERROR (Status)) { >> + break; >> + } >> + while (Value != 0) { >> + if ((Value & 0x01) != 0) { >> + Count++; >> + } >> + Value >>= 1; >> + } >> + } >> + >> + return Count; >> +} >> + >> +/** >> + Set the number of configured CPM per socket. >> + >> + @param SocketId Socket index. >> + @param NumberOfCPMs Number of CPM to be configured. >> + @return EFI_SUCCESS Operation succeeded. >> + @return Others An error has occurred. >> + >> +**/ >> +EFI_STATUS >> +EFIAPI >> +SetNumberOfConfiguredCPMs ( >> + UINT8 SocketId, >> + UINT16 NumberOfCPMs >> + ) >> +{ >> + EFI_STATUS Status; >> + UINT32 Value; >> + UINT32 Param, ParamStart, ParamEnd; >> + BOOLEAN IsClear; >> + >> + IsClear = FALSE; >> + if (NumberOfCPMs == 0) { >> + IsClear = TRUE; >> + } >> + >> + Status = EFI_SUCCESS; >> + >> + ParamStart = NV_SI_S0_PCP_ACTIVECPM_0_31 + SocketId * NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32); >> + ParamEnd = ParamStart + NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32); >> + for (Param = ParamStart; Param < ParamEnd; Param += NV_PARAM_ENTRYSIZE) { >> + if (NumberOfCPMs >= 32) { >> + Value = 0xffffffff; >> + NumberOfCPMs -= 32; >> + } else { >> + Value = 0; >> + while (NumberOfCPMs > 0) { >> + Value |= (1 << (--NumberOfCPMs)); >> + } >> + } >> + if (IsClear) { >> + /* Clear this param */ >> + Status = NVParamClr ( >> + Param, >> + NV_PERM_BIOS | NV_PERM_MANU >> + ); >> + } else { >> + Status = NVParamSet ( >> + Param, >> + NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC, >> + NV_PERM_BIOS | NV_PERM_MANU, >> + Value >> + ); >> + } >> + } >> + >> + return Status; >> +} >> + >> +/** >> + Get the maximum number of core per socket. >> + >> + @return UINT16 Maximum number of core. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +GetMaximumNumberOfCores ( >> + VOID >> + ) >> +{ >> + PLATFORM_INFO_HOB *PlatformHob; >> + >> + PlatformHob = GetPlatformHob (); >> + if (PlatformHob == NULL) { >> + return 0; >> + } >> + >> + return PlatformHob->MaxNumOfCore[0]; >> +} >> + >> +/** >> + Get the maximum number of CPM per socket. This number >> + should be the same for all sockets. >> + >> + @return UINT16 Maximum number of CPM. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +GetMaximumNumberOfCPMs ( >> + VOID >> + ) >> +{ >> + return GetMaximumNumberOfCores () / PLATFORM_CPU_NUM_CORES_PER_CPM; >> +} >> + >> +/** >> + Get the number of active cores of a sockets. >> + >> + @param SocketId Socket Index. >> + @return UINT16 Number of active core. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +GetNumberOfActiveCoresPerSocket ( >> + UINT8 SocketId >> + ) >> +{ >> + return GetNumberOfActiveCPMsPerSocket (SocketId) * PLATFORM_CPU_NUM_CORES_PER_CPM; >> +} >> + >> +/** >> + Get the number of active cores of all sockets. >> + >> + @return UINT16 Number of active core. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +GetNumberOfActiveCores ( >> + VOID >> + ) >> +{ >> + UINT16 NumberOfActiveCores; >> + UINT8 Index; >> + >> + NumberOfActiveCores = 0; >> + >> + for (Index = 0; Index < GetNumberOfActiveSockets (); Index++) { >> + NumberOfActiveCores += GetNumberOfActiveCoresPerSocket (Index); >> + } >> + >> + return NumberOfActiveCores; >> +} >> + >> +/** >> + Check if the logical CPU is enabled or not. >> + >> + @param CpuId The logical Cpu ID. Started from 0. >> + @return BOOLEAN TRUE if the Cpu enabled >> + FALSE if the Cpu disabled. >> + >> +**/ >> +BOOLEAN >> +EFIAPI >> +IsCpuEnabled ( >> + UINT16 CpuId >> + ) >> +{ >> + PLATFORM_CLUSTER_EN *Socket; >> + PLATFORM_INFO_HOB *PlatformHob; >> + UINT8 SocketId; >> + UINT16 ClusterId; >> + >> + SocketId = SOCKET_ID (CpuId); >> + ClusterId = CLUSTER_ID (CpuId); >> + >> + PlatformHob = GetPlatformHob (); >> + if (PlatformHob == NULL) { >> + return FALSE; >> + } >> + >> + if (SocketId >= GetNumberOfActiveSockets ()) { >> + return FALSE; >> + } >> + >> + Socket = &PlatformHob->ClusterEn[SocketId]; >> + if ((Socket->EnableMask[ClusterId / 32] & (1 << (ClusterId % 32))) != 0) { >> + return TRUE; >> + } >> + >> + return FALSE; >> +} >> + >> +/** >> + Check if the slave socket is present >> + >> + @return BOOLEAN TRUE if the Slave Cpu is present >> + FALSE if the Slave Cpu is not present >> + >> +**/ >> +BOOLEAN >> +EFIAPI >> +IsSlaveSocketPresent ( >> + VOID >> + ) >> +{ >> + UINT32 Value; >> + >> + Value = MmioRead32 (SMPRO_EFUSE_SHADOW0 + CFG2P_OFFSET); >> + >> + return ((Value & SLAVE_PRESENT_N) != 0) ? FALSE : TRUE; >> +} >> + >> +/** >> + Check if the slave socket is active >> + >> + @return BOOLEAN TRUE if the Slave CPU Socket is active. >> + FALSE if the Slave CPU Socket is not active. >> + >> +**/ >> +BOOLEAN >> +EFIAPI >> +IsSlaveSocketActive ( >> + VOID >> + ) >> +{ >> + return (GetNumberOfActiveSockets () > 1) ? TRUE : FALSE; >> +} >> + >> +/** >> + Check if the CPU product ID is Ac01 >> + @return BOOLEAN TRUE if the Product ID is Ac01 >> + FALSE otherwise. >> + >> +**/ >> +BOOLEAN >> +EFIAPI >> +IsAc01Processor ( >> + VOID >> + ) >> +{ >> + PLATFORM_INFO_HOB *PlatformHob; >> + >> + PlatformHob = GetPlatformHob (); >> + ASSERT (PlatformHob != NULL); >> + >> + if (PlatformHob != NULL) { >> + if ((PlatformHob->ScuProductId[0] & 0xFF) == 0x01) { >> + return TRUE; >> + } >> + } >> + >> + return FALSE; >> +} > > >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c >> new file mode 100644 >> index 000000000000..8c1eb93f00fd >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c >> @@ -0,0 +1,169 @@ >> +/** @file >> + >> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
>> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#include >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +ARM_CORE_INFO mArmPlatformMpCoreInfoTable[PLATFORM_CPU_MAX_NUM_CORES]; >> + >> +/** >> + Return the current Boot Mode >> + >> + This function returns the boot reason on the platform >> + >> + @return Return the current Boot Mode of the platform >> + >> +**/ >> +EFI_BOOT_MODE >> +ArmPlatformGetBootMode ( >> + VOID >> + ) >> +{ >> + return BOOT_WITH_FULL_CONFIGURATION; >> +} >> + >> +/** >> + Initialize controllers that must setup in the normal world >> + >> + This function is called by the ArmPlatformPkg/PrePi or ArmPlatformPkg/PlatformPei >> + in the PEI phase. >> + >> +**/ >> +EFI_STATUS >> +ArmPlatformInitialize ( >> + IN UINTN MpId >> + ) >> +{ >> + RETURN_STATUS Status; >> + UINT64 BaudRate; >> + UINT32 ReceiveFifoDepth; >> + EFI_PARITY_TYPE Parity; >> + UINT8 DataBits; >> + EFI_STOP_BITS_TYPE StopBits; >> + >> + Status = EFI_SUCCESS; >> + >> + if (FixedPcdGet64 (PcdSerialRegisterBase) != 0) { >> + /* Debug port should use the same parameters with console */ >> + BaudRate = FixedPcdGet64 (PcdUartDefaultBaudRate); >> + ReceiveFifoDepth = FixedPcdGet32 (PcdUartDefaultReceiveFifoDepth); >> + Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity); >> + DataBits = FixedPcdGet8 (PcdUartDefaultDataBits); >> + StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits); >> + >> + /* Initialize uart debug port */ >> + Status = PL011UartInitializePort ( >> + (UINTN)FixedPcdGet64 (PcdSerialRegisterBase), >> + FixedPcdGet32 (PL011UartClkInHz), >> + &BaudRate, >> + &ReceiveFifoDepth, >> + &Parity, >> + &DataBits, >> + &StopBits >> + ); >> + } >> + >> + return Status; >> +} >> + >> +EFI_STATUS >> +PrePeiCoreGetMpCoreInfo ( >> + OUT UINTN *CoreCount, >> + OUT ARM_CORE_INFO **ArmCoreTable >> + ) >> +{ >> + UINTN mArmPlatformCoreCount; >> + UINTN ClusterId; >> + UINTN SocketId; >> + UINTN Index; >> + >> + ASSERT (CoreCount != NULL); >> + ASSERT (ArmCoreTable != NULL); >> + ASSERT (*ArmCoreTable != NULL); >> + >> + mArmPlatformCoreCount = 0; >> + for (Index = 0; Index < PLATFORM_CPU_MAX_NUM_CORES; Index++) { >> + if (!IsCpuEnabled (Index)) { >> + continue; >> + } >> + SocketId = SOCKET_ID (Index); >> + ClusterId = CLUSTER_ID (Index); >> + mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].ClusterId = SocketId; >> + mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].CoreId = >> + (ClusterId << 8) | (Index % PLATFORM_CPU_NUM_CORES_PER_CPM); >> + mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxClearAddress = 0; >> + mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxClearValue = 0; >> + mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxGetAddress = 0; >> + mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxSetAddress = 0; >> + mArmPlatformCoreCount++; >> + } >> + >> + *CoreCount = mArmPlatformCoreCount; >> + >> + *ArmCoreTable = mArmPlatformMpCoreInfoTable; >> + ASSERT (*ArmCoreTable != NULL); >> + >> + return EFI_SUCCESS; >> +} >> + >> +// Needs to be declared in the file. Otherwise gArmMpCoreInfoPpiGuid is undefined in the contect of PrePeiCore >> +EFI_GUID mArmMpCoreInfoPpiGuid = ARM_MP_CORE_INFO_PPI_GUID; >> +ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo }; >> + >> +EFI_PEI_PPI_DESCRIPTOR gPlatformPpiTable[] = { >> + { >> + EFI_PEI_PPI_DESCRIPTOR_PPI, >> + &mArmMpCoreInfoPpiGuid, >> + &mMpCoreInfoPpi >> + }, >> +}; >> + >> +/** >> + Return the Platform specific PPIs >> + >> + This function exposes the Platform Specific PPIs. They can be used by any PrePi modules or passed >> + to the PeiCore by PrePeiCore. >> + >> + @param[out] PpiListSize Size in Bytes of the Platform PPI List >> + @param[out] PpiList Platform PPI List >> + >> +**/ >> +VOID >> +ArmPlatformGetPlatformPpiList ( >> + OUT UINTN *PpiListSize, >> + OUT EFI_PEI_PPI_DESCRIPTOR **PpiList >> + ) >> +{ >> + ASSERT (PpiListSize != NULL); >> + ASSERT (PpiList != NULL); >> + ASSERT (*PpiList != NULL); >> + >> + if (ArmIsMpCore ()) { >> + *PpiListSize = sizeof (gPlatformPpiTable); >> + *PpiList = gPlatformPpiTable; >> + } else { >> + *PpiListSize = 0; >> + *PpiList = NULL; >> + } >> +} >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c >> new file mode 100644 >> index 000000000000..117c9cc56ac2 >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c >> @@ -0,0 +1,399 @@ >> +/** @file >> + >> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
>> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#include >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +/* Number of Virtual Memory Map Descriptors */ >> +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 50 >> + >> +/* DDR attributes */ >> +#define DDR_ATTRIBUTES_CACHED ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK >> +#define DDR_ATTRIBUTES_UNCACHED ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED >> + >> +/** >> + Return the Virtual Memory Map of your platform >> + >> + This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform. >> + >> + @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to- >> + Virtual Memory mapping. This array must be ended by a zero-filled >> + entry >> + >> +**/ >> +VOID >> +ArmPlatformGetVirtualMemoryMap ( >> + OUT ARM_MEMORY_REGION_DESCRIPTOR **VirtualMemoryMap >> + ) >> +{ >> + UINTN Index = 0; >> + ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; >> + UINT32 NumRegion; >> + UINTN Count; >> + VOID *Hob; >> + PLATFORM_INFO_HOB *PlatformHob; >> + >> + Hob = GetFirstGuidHob (&gPlatformHobGuid); >> + ASSERT (Hob != NULL); >> + if (Hob == NULL) { >> + return; >> + } >> + >> + PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob); >> + >> + ASSERT (VirtualMemoryMap != NULL); >> + >> + VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR *)AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS)); >> + if (VirtualMemoryTable == NULL) { >> + return; >> + } >> + >> + /* For Address space 0x1000_0000_0000 to 0x1001_00FF_FFFF >> + * - Device memory >> + */ >> + VirtualMemoryTable[Index].PhysicalBase = 0x100000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x100000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x102000000ULL; > Please move all of these live-coded addresses/sizes to a private .h > and use symbolic names here. > >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* For Address space 0x5000_0000_0000 to 0x5001_00FF_FFFF >> + * - Device memory >> + */ >> + if (IsSlaveSocketActive ()) >> + { >> + VirtualMemoryTable[++Index].PhysicalBase = 0x500000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x500000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x101000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + } >> + >> + /* >> + * - PCIe RCA0 Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x300000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x300000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x40000000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - 2P/PCIe Socket0 RCA0 32-bit Device memory >> + * - 1P/PCIe consolidated to RCB2 32-bit Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x20000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x20000000ULL; >> + VirtualMemoryTable[Index].Length = 0x8000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - PCIe RCA1 Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x340000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x340000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x40000000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - 2P/PCIe Socket0 RCA1 32-bit Device memory >> + * - 1P/PCIe consolidated to RCB2 32-bit Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x28000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x28000000ULL; >> + VirtualMemoryTable[Index].Length = 0x8000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - PCIe RCA2 Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x380000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x380000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x40000000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - 2P/PCIe Socket0 RCA2 32-bit Device memory >> + * - 1P/PCIe consolidated to RCB3 32-bit Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x30000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x30000000ULL; >> + VirtualMemoryTable[Index].Length = 0x8000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - PCIe RCA3 Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x3C0000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x3C0000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x40000000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - 2P/PCIe Socket0 RCA3 32-bit Device memory >> + * - 1P/PCIe consolidated to RCB3 32-bit Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x38000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x38000000ULL; >> + VirtualMemoryTable[Index].Length = 0x8000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - PCIe RCB0 Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x200000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x200000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x40000000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - 2P/PCIe Socket0 RCB0 32-bit Device memory >> + * - 1P/PCIe consolidated to RCB0 32-bit Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x00000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x00000000ULL; >> + VirtualMemoryTable[Index].Length = 0x8000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - PCIe RCB1 Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x240000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x240000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x40000000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - 2P/PCIe Socket0 RCB1 32-bit Device memory >> + * - 1P/PCIe consolidated to RCB0 32-bit Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x08000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x08000000ULL; >> + VirtualMemoryTable[Index].Length = 0x8000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - PCIe RCB2 Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x280000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x280000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x40000000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - 2P/PCIe Socket0 RCB2 32-bit Device memory >> + * - 1P/PCIe consolidated to RCB1 32-bit Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x10000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x10000000ULL; >> + VirtualMemoryTable[Index].Length = 0x8000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - PCIe RCB3 Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x2C0000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x2C0000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x40000000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - 2P/PCIe Socket0 RCB3 32-bit Device memory >> + * - 1P/PCIe consolidated to RCB1 32-bit Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x18000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x18000000ULL; >> + VirtualMemoryTable[Index].Length = 0x8000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + if (IsSlaveSocketActive ()) { >> + // Slave socket exist >> + /* >> + * - PCIe RCA0 Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x700000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x700000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x40000000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - PCIe RCA1 Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x740000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x740000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x40000000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - PCIe RCA2 Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x780000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x780000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x40000000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - PCIe RCA3 Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x7C0000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x7C0000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x40000000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - PCIe RCB0 Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x600000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x600000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x40000000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - PCIe RCB1 Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x640000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x640000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x40000000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - PCIe RCB2 Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x680000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x680000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x40000000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - PCIe RCB3 Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x6C0000000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x6C0000000000ULL; >> + VirtualMemoryTable[Index].Length = 0x40000000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + } >> + >> + /* >> + * - 2P/PCIe Socket1 RCA0 32-bit Device memory >> + * - 1P/PCIe consolidated to RCA2 32-bit Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x60000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x60000000ULL; >> + VirtualMemoryTable[Index].Length = 0x8000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - 2P/PCIe Socket1 RCA1 32-bit Device memory >> + * - 1P/PCIe consolidated to RCA2 32-bit Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x68000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x68000000ULL; >> + VirtualMemoryTable[Index].Length = 0x8000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - 2P/PCIe Socket1 RCA2 32-bit Device memory >> + * - 1P/PCIe consolidated to RCA3 32-bit Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x70000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x70000000ULL; >> + VirtualMemoryTable[Index].Length = 0x8000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - 2P/PCIe Socket1 RCA3 32-bit Device memory >> + * - 1P/PCIe consolidated to RCA3 32-bit Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x78000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x78000000ULL; >> + VirtualMemoryTable[Index].Length = 0x8000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - 2P/PCIe Socket1 RCB0 32-bit Device memory >> + * - 1P/PCIe consolidated to RCA0 32-bit Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x40000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x40000000ULL; >> + VirtualMemoryTable[Index].Length = 0x8000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - 2P/PCIe Socket1 RCB1 32-bit Device memory >> + * - 1P/PCIe consolidated to RCA0 32-bit Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x48000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x48000000ULL; >> + VirtualMemoryTable[Index].Length = 0x8000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - 2P/PCIe Socket1 RCB2 32-bit Device memory >> + * - 1P/PCIe consolidated to RCA1 32-bit Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x50000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x50000000ULL; >> + VirtualMemoryTable[Index].Length = 0x8000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - 2P/PCIe Socket1 RCB3 32-bit Device memory >> + * - 1P/PCIe consolidated to RCA1 32-bit Device memory >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x58000000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x58000000ULL; >> + VirtualMemoryTable[Index].Length = 0x8000000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - BERT memory region >> + */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0x88230000ULL; >> + VirtualMemoryTable[Index].VirtualBase = 0x88230000ULL; >> + VirtualMemoryTable[Index].Length = 0x50000ULL; >> + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; >> + >> + /* >> + * - DDR memory region >> + */ >> + NumRegion = PlatformHob->DramInfo.NumRegion; >> + Count = 0; >> + while (NumRegion-- > 0) { >> + if (PlatformHob->DramInfo.NvdRegion[Count]) { /* Skip NVDIMM Region */ >> + Count++; >> + continue; >> + } >> + >> + VirtualMemoryTable[++Index].PhysicalBase = PlatformHob->DramInfo.Base[Count]; >> + VirtualMemoryTable[Index].VirtualBase = PlatformHob->DramInfo.Base[Count]; >> + VirtualMemoryTable[Index].Length = PlatformHob->DramInfo.Size[Count]; >> + VirtualMemoryTable[Index].Attributes = DDR_ATTRIBUTES_CACHED; >> + Count++; >> + } >> + >> + /* SPM MM NS Buffer for MmCommunicateDxe */ >> + VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdMmBufferBase); >> + VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdMmBufferBase); >> + VirtualMemoryTable[Index].Length = PcdGet64 (PcdMmBufferSize); >> + VirtualMemoryTable[Index].Attributes = DDR_ATTRIBUTES_CACHED; >> + >> + /* End of Table */ >> + VirtualMemoryTable[++Index].PhysicalBase = 0; >> + VirtualMemoryTable[Index].VirtualBase = 0; >> + VirtualMemoryTable[Index].Length = 0; >> + VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0; >> + >> + ASSERT ((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS); >> + >> + *VirtualMemoryMap = VirtualMemoryTable; >> +} > > >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c >> new file mode 100644 >> index 000000000000..0da1f90699f6 >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c >> @@ -0,0 +1,282 @@ >> +/** @file >> + The library implements the hardware Mailbox (Doorbell) interface for communication >> + between the Application Processor (ARMv8) and the System Control Processors (SMpro/PMpro). >> + >> + Copyright (c) 2021, Ampere Computing LLC. All rights reserved.
>> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#include >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +// >> +// Hardware Doorbells >> +// >> +#define SMPRO_DB0_IRQ_OFST 40 >> +#define SMPRO_DB0_BASE_ADDRESS (FixedPcdGet64 (PcdSmproDbBaseReg)) >> + >> +#define PMPRO_DB0_IRQ_OFST 56 >> +#define PMPRO_DB0_BASE_ADDRESS (FixedPcdGet64 (PcdPmproDbBaseReg)) >> + >> +#define SLAVE_SOCKET_BASE_ADDRESS_OFFSET 0x400000000000 >> + >> +// >> +// The base SPI interrupt number of the Slave socket >> +// >> +#define SLAVE_SOCKET_SPI_INTERRUPT 352 >> + >> +#define SLAVE_SOCKET_DOORBELL_INTERRUPT_BASE(Socket) ((Socket) * SLAVE_SOCKET_SPI_INTERRUPT - 32) >> + >> +// >> +// Doorbell base register stride size >> +// >> +#define DB_BASE_REG_STRIDE 0x00001000 >> + >> +#define SMPRO_DBx_ADDRESS(socket, db) \ >> + ((socket) * SLAVE_SOCKET_BASE_ADDRESS_OFFSET + SMPRO_DB0_BASE_ADDRESS + DB_BASE_REG_STRIDE * (db)) >> + >> +#define PMPRO_DBx_ADDRESS(socket, db) \ >> + ((socket) * SLAVE_SOCKET_BASE_ADDRESS_OFFSET + PMPRO_DB0_BASE_ADDRESS + DB_BASE_REG_STRIDE * (db)) >> + >> +// >> +// Doorbell Status Bits >> +// >> +#define DB_STATUS_AVAIL_BIT BIT16 >> +#define DB_STATUS_ACK_BIT BIT0 >> + >> +/** >> + Get the base address of a doorbell. >> + >> + @param[in] Socket Active socket index. >> + @param[in] Doorbell Doorbell channel for communication with the SMpro/PMpro. >> + >> + @retval UINT32 The base address of the doorbell. >> + The returned value is 0 indicate that the input parameters are invalid. >> + >> +**/ >> +UINTN >> +EFIAPI >> +MailboxGetDoorbellAddress ( >> + IN UINT8 Socket, >> + IN DOORBELL_CHANNELS Doorbell >> + ) >> +{ >> + UINTN DoorbellAddress; >> + >> + if (Socket >= GetNumberOfActiveSockets () >> + || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET) >> + { >> + return 0; >> + } > Coding style is > if () { > } > > This file gets it consistently wrong. I agree that it should be consistent. But that coding style conforms to "5.2.1.6 Each sub-expression of a complex predicate expression must be on a separate line" in EDK II Coding Standards Spec (https://edk2-docs.gitbook.io/edk-ii-c-coding-standards-specification/5_source_files/52_spacing#5-2-1-6-each-sub-expression-of-a-complex-predicate-expression-must-be-on-a-separate-line). "Predicate expressions containing multiple operators with sub-expressions joined by && or || must have each sub-expression on a separate line. The opening brace, '|{|' of the body shall be on a line by itself and aligned in the starting column of the associated keyword. while ( ( Code == MEETS_STANDARD)   && ( Code == FUNCTIONAL)) {   ShipIt(); } " However, I'm OK to change it as your suggestion. Thanks, Nhi > >> + >> + if (Doorbell >= SMproDoorbellChannel0) { >> + DoorbellAddress = SMPRO_DBx_ADDRESS (Socket, (UINT8)(Doorbell - SMproDoorbellChannel0)); >> + } else { >> + DoorbellAddress = PMPRO_DBx_ADDRESS (Socket, (UINT8)Doorbell); >> + } >> + >> + return DoorbellAddress; >> +} >> + >> +/** >> + Get the interrupt number of a doorbell. >> + >> + @param[in] Socket Active socket index. >> + @param[in] Doorbell Doorbell channel for communication with the SMpro/PMpro. >> + >> + @retval UINT32 The interrupt number. >> + The returned value is 0 indicate that the input parameters are invalid. >> + >> +**/ >> +UINT32 >> +EFIAPI >> +MailboxGetDoorbellInterruptNumber ( >> + IN UINT8 Socket, >> + IN DOORBELL_CHANNELS Doorbell >> + ) >> +{ >> + UINT32 DoorbellInterruptNumber; >> + >> + if (Socket >= GetNumberOfActiveSockets () >> + || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET) >> + { >> + return 0; >> + } >> + >> + DoorbellInterruptNumber = 0; >> + >> + if (Socket > 0) { >> + DoorbellInterruptNumber = SLAVE_SOCKET_DOORBELL_INTERRUPT_BASE (Socket); >> + } >> + >> + if (Doorbell >= SMproDoorbellChannel0) { >> + DoorbellInterruptNumber += SMPRO_DB0_IRQ_OFST + (UINT8)(Doorbell - SMproDoorbellChannel0); >> + } else { >> + DoorbellInterruptNumber += PMPRO_DB0_IRQ_OFST + (UINT8)Doorbell; >> + } >> + >> + return DoorbellInterruptNumber; >> +} >> + >> +/** >> + Read a message via the hardware Doorbell interface. >> + >> + @param[in] Socket Active socket index. >> + @param[in] Doorbell Doorbell channel for communication with the SMpro/PMpro. >> + @param[out] Message Pointer to the Mailbox message. >> + >> + @retval EFI_SUCCESS Read the message successfully. >> + @retval EFI_TIMEOUT Timeout occurred when waiting for available message in the mailbox. >> + @retval EFI_INVALID_PARAMETER A parameter is invalid. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +MailboxRead ( >> + IN UINT8 Socket, >> + IN DOORBELL_CHANNELS Doorbell, >> + OUT MAILBOX_MESSAGE_DATA *Message >> + ) >> +{ >> + UINTN TimeoutCount; >> + UINTN DoorbellAddress; >> + >> + if (Socket >= GetNumberOfActiveSockets () >> + || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET >> + || Message == NULL) >> + { >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + TimeoutCount = MAILBOX_POLL_COUNT; >> + >> + DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell); >> + ASSERT (DoorbellAddress != 0); >> + >> + // >> + // Polling Doorbell status >> + // >> + while ((MmioRead32 ((DoorbellAddress + DB_STATUS_REG_OFST)) & DB_STATUS_AVAIL_BIT) == 0) { >> + MicroSecondDelay (MAILBOX_POLL_INTERVAL_US); >> + if (--TimeoutCount == 0) { >> + return EFI_TIMEOUT; >> + } >> + } >> + >> + Message->ExtendedData[0] = MmioRead32 (DoorbellAddress + DB_DIN0_REG_OFST); >> + Message->ExtendedData[1] = MmioRead32 (DoorbellAddress + DB_DIN1_REG_OFST); >> + Message->Data = MmioRead32 (DoorbellAddress + DB_IN_REG_OFST); >> + >> + // >> + // Write 1 to clear the AVAIL status >> + // >> + MmioWrite32 (DoorbellAddress + DB_STATUS_REG_OFST, DB_STATUS_AVAIL_BIT); >> + >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + Write a message via the hardware Doorbell interface. >> + >> + @param[in] Socket Active socket index. >> + @param[in] Doorbell Doorbel channel for communication with the SMpro/PMpro. >> + @param[in] Message Pointer to the Mailbox message. >> + >> + @retval EFI_SUCCESS Write the message successfully. >> + @retval EFI_TIMEOUT Timeout occurred when waiting for acknowledge signal from the mailbox. >> + @retval EFI_INVALID_PARAMETER A parameter is invalid. >> +**/ >> +EFI_STATUS >> +EFIAPI >> +MailboxWrite ( >> + IN UINT8 Socket, >> + IN DOORBELL_CHANNELS Doorbell, >> + IN MAILBOX_MESSAGE_DATA *Message >> + ) >> +{ >> + UINTN TimeoutCount; >> + UINTN DoorbellAddress; >> + >> + if (Socket >= GetNumberOfActiveSockets () >> + || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET >> + || Message == NULL) >> + { >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + TimeoutCount = MAILBOX_POLL_COUNT; >> + >> + DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell); >> + ASSERT (DoorbellAddress != 0); >> + >> + // >> + // Clear previous pending ack if any >> + // >> + if ((MmioRead32 (DoorbellAddress + DB_STATUS_REG_OFST) & DB_STATUS_ACK_BIT) != 0) { >> + MmioWrite32 (DoorbellAddress + DB_STATUS_REG_OFST, DB_STATUS_ACK_BIT); >> + } >> + >> + // >> + // Send message >> + // >> + MmioWrite32 (DoorbellAddress + DB_DOUT0_REG_OFST, Message->ExtendedData[0]); >> + MmioWrite32 (DoorbellAddress + DB_DOUT1_REG_OFST, Message->ExtendedData[1]); >> + MmioWrite32 (DoorbellAddress + DB_OUT_REG_OFST, Message->Data); >> + >> + // >> + // Wait for ACK >> + // >> + while ((MmioRead32 (DoorbellAddress + DB_STATUS_REG_OFST) & DB_STATUS_ACK_BIT) == 0) { >> + MicroSecondDelay (MAILBOX_POLL_INTERVAL_US); >> + if (--TimeoutCount == 0) { >> + return EFI_TIMEOUT; >> + } >> + } >> + >> + // >> + // Write 1 to clear the ACK status >> + // >> + MmioWrite32 (DoorbellAddress + DB_STATUS_REG_OFST, DB_STATUS_ACK_BIT); >> + >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + Unmask the Doorbell interrupt status. >> + >> + @param Socket Active socket index. >> + @param Doorbell Doorbel channel for communication with the SMpro/PMpro. >> + >> + @retval EFI_SUCCESS Unmask the Doorbell interrupt successfully. >> + @retval EFI_INVALID_PARAMETER A parameter is invalid. >> + >> +**/ >> +EFI_STATUS >> +EFIAPI >> +MailboxUnmaskInterrupt ( >> + IN UINT8 Socket, >> + IN UINT16 Doorbell >> + ) >> +{ >> + UINTN DoorbellAddress; >> + >> + if (Socket >= GetNumberOfActiveSockets () >> + || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET) >> + { >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell); >> + ASSERT (DoorbellAddress != 0); >> + >> + MmioWrite32 (DoorbellAddress + DB_STATUS_MASK_REG_OFST, ~DB_STATUS_AVAIL_BIT); >> + >> + return EFI_SUCCESS; >> +} > >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c >> new file mode 100644 >> index 000000000000..bf400ec0a835 >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c >> @@ -0,0 +1,184 @@ >> +/** @file >> + >> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
>> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +// >> +// Address, Length of the pre-allocated buffer for communication with the secure >> +// world. >> +// >> +STATIC ARM_MEMORY_REGION_DESCRIPTOR mNsCommBuffMemRegion; >> + >> +EFI_STATUS >> +EFIAPI >> +MmCommunicationLibConstructor ( >> + VOID >> + ) >> +{ >> + mNsCommBuffMemRegion.PhysicalBase = PcdGet64 (PcdMmBufferBase); >> + // During boot , Virtual and Physical are same > Ideally, use UEFI-defined terms. "During boot" is quite ambiguous. > > >> + mNsCommBuffMemRegion.VirtualBase = mNsCommBuffMemRegion.PhysicalBase; >> + mNsCommBuffMemRegion.Length = PcdGet64 (PcdMmBufferSize); >> + >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + Communicates with a registered handler. >> + >> + This function provides an interface to send and receive messages to the >> + Standalone MM environment in UEFI PEI phase. >> + >> + @param[in, out] CommBuffer A pointer to the buffer to convey >> + into MMRAM. >> + @param[in, out] CommSize The size of the data buffer being >> + passed in. This is optional. >> + >> + @retval EFI_SUCCESS The message was successfully posted. >> + @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. >> + @retval EFI_BAD_BUFFER_SIZE The buffer size is incorrect for the MM >> + implementation. If this error is >> + returned, the MessageLength field in >> + the CommBuffer header or the integer >> + pointed by CommSize are updated to reflect >> + the maximum payload size the >> + implementation can accommodate. >> + @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter >> + or CommSize parameter, if not omitted, >> + are in address range that cannot be >> + accessed by the MM environment >> +**/ >> +EFI_STATUS >> +EFIAPI >> +MmCommunicationCommunicate ( >> + IN OUT VOID *CommBuffer, >> + IN OUT UINTN *CommSize OPTIONAL >> + ) >> +{ >> + EFI_MM_COMMUNICATE_HEADER *CommunicateHeader; >> + ARM_SMC_ARGS CommunicateSmcArgs; >> + EFI_STATUS Status; >> + UINTN BufferSize; >> + >> + Status = EFI_ACCESS_DENIED; >> + BufferSize = 0; >> + >> + ZeroMem (&CommunicateSmcArgs, sizeof (ARM_SMC_ARGS)); >> + >> + // >> + // Check parameters >> + // >> + if (CommBuffer == NULL) { >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + CommunicateHeader = CommBuffer; >> + // CommBuffer is a mandatory parameter. Hence, Rely on >> + // MessageLength + Header to ascertain the >> + // total size of the communication payload rather than >> + // rely on optional CommSize parameter >> + BufferSize = CommunicateHeader->MessageLength + >> + sizeof (CommunicateHeader->HeaderGuid) + >> + sizeof (CommunicateHeader->MessageLength); >> + >> + // If the length of the CommBuffer is 0 then return the expected length. >> + if (CommSize != NULL) { >> + // This case can be used by the consumer of this driver to find out the >> + // max size that can be used for allocating CommBuffer. >> + if ((*CommSize == 0) || >> + (*CommSize > mNsCommBuffMemRegion.Length)) >> + { > { at end of preceding line. > Please address throughout this file. > >> + *CommSize = mNsCommBuffMemRegion.Length; >> + return EFI_BAD_BUFFER_SIZE; >> + } >> + // >> + // CommSize must match MessageLength + sizeof (EFI_MM_COMMUNICATE_HEADER); >> + // >> + if (*CommSize != BufferSize) { >> + return EFI_INVALID_PARAMETER; >> + } >> + } >> + >> + // >> + // If the buffer size is 0 or greater than what can be tolerated by the MM >> + // environment then return the expected size. >> + // >> + if ((BufferSize == 0) || >> + (BufferSize > mNsCommBuffMemRegion.Length)) >> + { >> + CommunicateHeader->MessageLength = mNsCommBuffMemRegion.Length - >> + sizeof (CommunicateHeader->HeaderGuid) - >> + sizeof (CommunicateHeader->MessageLength); >> + return EFI_BAD_BUFFER_SIZE; >> + } >> + >> + // SMC Function ID >> + CommunicateSmcArgs.Arg0 = ARM_SMC_ID_MM_COMMUNICATE_AARCH64; >> + >> + // Cookie >> + CommunicateSmcArgs.Arg1 = 0; >> + >> + // Copy Communication Payload >> + CopyMem ((VOID *)mNsCommBuffMemRegion.VirtualBase, CommBuffer, BufferSize); >> + >> + // comm_buffer_address (64-bit physical address) >> + CommunicateSmcArgs.Arg2 = (UINTN)mNsCommBuffMemRegion.PhysicalBase; >> + >> + // comm_size_address (not used, indicated by setting to zero) >> + CommunicateSmcArgs.Arg3 = 0; >> + >> + // Call the Standalone MM environment. >> + ArmCallSmc (&CommunicateSmcArgs); >> + >> + switch (CommunicateSmcArgs.Arg0) { >> + case ARM_SMC_MM_RET_SUCCESS: >> + ZeroMem (CommBuffer, BufferSize); >> + // On successful return, the size of data being returned is inferred from >> + // MessageLength + Header. >> + CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mNsCommBuffMemRegion.VirtualBase; >> + BufferSize = CommunicateHeader->MessageLength + >> + sizeof (CommunicateHeader->HeaderGuid) + >> + sizeof (CommunicateHeader->MessageLength); >> + >> + CopyMem ( >> + CommBuffer, >> + (VOID *)mNsCommBuffMemRegion.VirtualBase, >> + BufferSize >> + ); >> + Status = EFI_SUCCESS; >> + break; >> + >> + case ARM_SMC_MM_RET_INVALID_PARAMS: >> + Status = EFI_INVALID_PARAMETER; >> + break; >> + >> + case ARM_SMC_MM_RET_DENIED: >> + Status = EFI_ACCESS_DENIED; >> + break; >> + >> + case ARM_SMC_MM_RET_NO_MEMORY: >> + // Unexpected error since the CommSize was checked for zero length >> + // prior to issuing the SMC >> + Status = EFI_OUT_OF_RESOURCES; >> + ASSERT (0); >> + break; >> + >> + default: >> + Status = EFI_ACCESS_DENIED; >> + ASSERT (0); >> + } >> + >> + return Status; >> +} >> diff --git a/Platform/Ampere/JadePkg/JadeBoardSetting.cfg b/Platform/Ampere/JadePkg/JadeBoardSetting.cfg >> new file mode 100644 >> index 000000000000..5a67e8fc6a75 >> --- /dev/null >> +++ b/Platform/Ampere/JadePkg/JadeBoardSetting.cfg >> @@ -0,0 +1,209 @@ >> +# Sample board setting >> +# >> +# This is a sample board setting as used for the >> +# Ampere Altra reference design. > What is a board setting? > >> +# >> +# Name, offset (hex), value >> +# value can be hex or decimal >> +# >> + >> +NV_SI_RO_BOARD_VENDOR, 0x0000, 0x0000CD3A >> +NV_SI_RO_BOARD_TYPE, 0x0008, 0x00000000 >> +NV_SI_RO_BOARD_REV, 0x0010, 0x00000000 >> +NV_SI_RO_BOARD_CFG, 0x0018, 0x00000000 >> +NV_SI_RO_BOARD_S0_DIMM_AVAIL, 0x0020, 0x0000FFFF >> +NV_SI_RO_BOARD_S1_DIMM_AVAIL, 0x0028, 0x0000FFFF >> +NV_SI_RO_BOARD_SPI0CS0_FREQ_KHZ, 0x0030, 0x000080E8 >> +NV_SI_RO_BOARD_SPI0CS1_FREQ_KHZ, 0x0038, 0x000080E8 >> +NV_SI_RO_BOARD_SPI1CS0_FREQ_KHZ, 0x0040, 0x00002710 >> +NV_SI_RO_BOARD_SPI1CS1_FREQ_KHZ, 0x0048, 0x00002710 >> +NV_SI_RO_BOARD_TPM_LOC, 0x0050, 0x00000000 >> +NV_SI_RO_BOARD_I2C0_FREQ_KHZ, 0x0058, 0x00000190 >> +NV_SI_RO_BOARD_I2C1_FREQ_KHZ, 0x0060, 0x00000190 >> +NV_SI_RO_BOARD_I2C2_10_FREQ_KHZ, 0x0068, 0x00000190 >> +NV_SI_RO_BOARD_I2C3_FREQ_KHZ, 0x0070, 0x00000190 >> +NV_SI_RO_BOARD_I2C9_FREQ_KHZ, 0x0078, 0x00000190 >> +NV_SI_RO_BOARD_2P_CFG, 0x0080, 0xFFFFFF01 >> +NV_SI_RO_BOARD_S0_RCA0_CFG, 0x0088, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCA1_CFG, 0x0090, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCA2_CFG, 0x0098, 0x00000004 >> +NV_SI_RO_BOARD_S0_RCA3_CFG, 0x00A0, 0x00000004 >> +NV_SI_RO_BOARD_S0_RCB0_LO_CFG, 0x00A8, 0x00020002 >> +NV_SI_RO_BOARD_S0_RCB0_HI_CFG, 0x00B0, 0x00020002 >> +NV_SI_RO_BOARD_S0_RCB1_LO_CFG, 0x00B8, 0x00020002 >> +NV_SI_RO_BOARD_S0_RCB1_HI_CFG, 0x00C0, 0x00020002 >> +NV_SI_RO_BOARD_S0_RCB2_LO_CFG, 0x00C8, 0x00020002 >> +NV_SI_RO_BOARD_S0_RCB2_HI_CFG, 0x00D0, 0x00000003 >> +NV_SI_RO_BOARD_S0_RCB3_LO_CFG, 0x00D8, 0x00000003 >> +NV_SI_RO_BOARD_S0_RCB3_HI_CFG, 0x00E0, 0x00020002 >> +NV_SI_RO_BOARD_S1_RCA0_CFG, 0x00E8, 0x00000000 >> +NV_SI_RO_BOARD_S1_RCA1_CFG, 0x00F0, 0x00000000 >> +NV_SI_RO_BOARD_S1_RCA2_CFG, 0x00F8, 0x02020202 >> +NV_SI_RO_BOARD_S1_RCA3_CFG, 0x0100, 0x00030003 >> +NV_SI_RO_BOARD_S1_RCB0_LO_CFG, 0x0108, 0x00000003 >> +NV_SI_RO_BOARD_S1_RCB0_HI_CFG, 0x0110, 0x00020002 >> +NV_SI_RO_BOARD_S1_RCB1_LO_CFG, 0x0118, 0x00020002 >> +NV_SI_RO_BOARD_S1_RCB1_HI_CFG, 0x0120, 0x00000003 >> +NV_SI_RO_BOARD_S1_RCB2_LO_CFG, 0x0128, 0x00020002 >> +NV_SI_RO_BOARD_S1_RCB2_HI_CFG, 0x0130, 0x00020002 >> +NV_SI_RO_BOARD_S1_RCB3_LO_CFG, 0x0138, 0x00020002 >> +NV_SI_RO_BOARD_S1_RCB3_HI_CFG, 0x0140, 0x00020002 >> +NV_SI_RO_BOARD_T_LTLM_DELTA_P0, 0x0148, 0x00000001 >> +NV_SI_RO_BOARD_T_LTLM_DELTA_P1, 0x0150, 0x00000002 >> +NV_SI_RO_BOARD_T_LTLM_DELTA_P2, 0x0158, 0x00000003 >> +NV_SI_RO_BOARD_T_LTLM_DELTA_P3, 0x0160, 0x00000004 >> +NV_SI_RO_BOARD_T_LTLM_DELTA_M1, 0x0168, 0xFFFFFFFF >> +NV_SI_RO_BOARD_T_LTLM_DELTA_M2, 0x0170, 0xFFFFFFFE >> +NV_SI_RO_BOARD_T_LTLM_DELTA_M3, 0x0178, 0xFFFFFFFD >> +NV_SI_RO_BOARD_P_LM_PID_P, 0x0180, 0x00000000 >> +NV_SI_RO_BOARD_P_LM_PID_I, 0x0188, 0x00000000 >> +NV_SI_RO_BOARD_P_LM_PID_I_L_THOLD, 0x0190, 0x00000000 >> +NV_SI_RO_BOARD_P_LM_PID_I_H_THOLD, 0x0198, 0x00000000 >> +NV_SI_RO_BOARD_P_LM_PID_D, 0x01A0, 0x00000000 >> +NV_SI_RO_BOARD_P_LM_EXP_SMOOTH_CONST, 0x01A8, 0x00000000 >> +NV_SI_RO_BOARD_TPM_ALG_ID, 0x01B0, 0x00000002 >> +NV_SI_RO_BOARD_DDR_SPEED_GRADE, 0x01B8, 0x00000C80 >> +NV_SI_RO_BOARD_DDR_S0_RTT_WR, 0x01C0, 0x00020000 >> +NV_SI_RO_BOARD_DDR_S1_RTT_WR, 0x01C8, 0x00020000 >> +NV_SI_RO_BOARD_DDR_S0_RTT_NOM, 0x01D0, 0xFF060177 >> +NV_SI_RO_BOARD_DDR_S1_RTT_NOM, 0x01D8, 0xFF060177 >> +NV_SI_RO_BOARD_DDR_S0_RTT_PARK, 0x01E0, 0x00060070 >> +NV_SI_RO_BOARD_DDR_S1_RTT_PARK, 0x01E8, 0x00060070 >> +NV_SI_RO_BOARD_DDR_CS0_RDODT_MASK_1DPC, 0x01F0, 0x00000000 >> +NV_SI_RO_BOARD_DDR_CS1_RDODT_MASK_1DPC, 0x01F8, 0x00000000 >> +NV_SI_RO_BOARD_DDR_CS2_RDODT_MASK_1DPC, 0x0200, 0x00000000 >> +NV_SI_RO_BOARD_DDR_CS3_RDODT_MASK_1DPC, 0x0208, 0x00000000 >> +NV_SI_RO_BOARD_DDR_CS0_RDODT_MASK_2DPC, 0x0210, 0x000C0CCC >> +NV_SI_RO_BOARD_DDR_CS1_RDODT_MASK_2DPC, 0x0218, 0x000C0CCC >> +NV_SI_RO_BOARD_DDR_CS2_RDODT_MASK_2DPC, 0x0220, 0x00030333 >> +NV_SI_RO_BOARD_DDR_CS3_RDODT_MASK_2DPC, 0x0228, 0x00030333 >> +NV_SI_RO_BOARD_DDR_CS0_WRODT_MASK_1DPC, 0x0230, 0x00030333 >> +NV_SI_RO_BOARD_DDR_CS1_WRODT_MASK_1DPC, 0x0238, 0x00030333 >> +NV_SI_RO_BOARD_DDR_CS2_WRODT_MASK_1DPC, 0x0240, 0x00030333 >> +NV_SI_RO_BOARD_DDR_CS3_WRODT_MASK_1DPC, 0x0248, 0x00030333 >> +NV_SI_RO_BOARD_DDR_CS0_WRODT_MASK_2DPC, 0x0250, 0x000EDEED >> +NV_SI_RO_BOARD_DDR_CS1_WRODT_MASK_2DPC, 0x0258, 0x000DEDDE >> +NV_SI_RO_BOARD_DDR_CS2_WRODT_MASK_2DPC, 0x0260, 0x000B7BB7 >> +NV_SI_RO_BOARD_DDR_CS3_WRODT_MASK_2DPC, 0x0268, 0x0007B77B >> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_CTRL_1DPC, 0x0270, 0x00000005 >> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_VAL_1DPC, 0x0278, 0x0090DD90 >> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_CTRL_1DPC, 0x0280, 0x00000005 >> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_VAL_1DPC, 0x0288, 0x0090DD90 >> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_CTRL_2DPC, 0x0290, 0x00000005 >> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_VAL_2DPC, 0x0298, 0x0090DD90 >> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_CTRL_2DPC, 0x02A0, 0x00000005 >> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_VAL_2DPC, 0x02A8, 0x0090DD90 >> +NV_SI_RO_BOARD_DDR_PHY_VREFDQ_RANGE_VAL_1DPC, 0x02B0, 0x00000024 >> +NV_SI_RO_BOARD_DDR_DRAM_VREFDQ_RANGE_VAL_1DPC, 0x02B8, 0x0000001A >> +NV_SI_RO_BOARD_DDR_PHY_VREFDQ_RANGE_VAL_2DPC, 0x02C0, 0x00000050 >> +NV_SI_RO_BOARD_DDR_DRAM_VREFDQ_RANGE_VAL_2DPC, 0x02C8, 0x00000020 >> +NV_SI_RO_BOARD_DDR_CLK_WRDQ_DLY_DEFAULT, 0x02D0, 0x02800280 >> +NV_SI_RO_BOARD_DDR_RDDQS_DQ_DLY_DEFAULT, 0x02D8, 0x90909090 >> +NV_SI_RO_BOARD_DDR_WRDQS_SHIFT_DEFAULT, 0x02E0, 0x00000000 >> +NV_SI_RO_BOARD_DDR_ADCMD_DLY_DEFAULT, 0x02E8, 0x00C000C0 >> +NV_SI_RO_BOARD_DDR_CLK_WRDQ_DLY_ADJ, 0x02F0, 0x00000000 >> +NV_SI_RO_BOARD_DDR_RDDQS_DQ_DLY_ADJ, 0x02F8, 0x00000000 >> +NV_SI_RO_BOARD_DDR_PHY_VREF_ADJ, 0x0300, 0x00000000 >> +NV_SI_RO_BOARD_DDR_DRAM_VREF_ADJ, 0x0308, 0x00000000 >> +NV_SI_RO_BOARD_DDR_WR_PREAMBLE_CYCLE, 0x0310, 0x02010201 >> +NV_SI_RO_BOARD_DDR_ADCMD_2T_MODE, 0x0318, 0x00000000 >> +NV_SI_RO_BOARD_I2C_VRD_CONFIG_INFO, 0x0320, 0x00000000 >> +NV_SI_RO_BOARD_DDR_PHY_FEATURE_CTRL, 0x0328, 0x00000000 >> +NV_SI_RO_BOARD_BMC_HANDSHAKE_SPI_ACCESS, 0x0330, 0x01050106 >> +NV_SI_RO_BOARD_DIMM_TEMP_THRESHOLD, 0x0338, 0x000005F4 >> +NV_SI_RO_BOARD_DIMM_SPD_COMPARE_DISABLE, 0x0340, 0x00000000 >> +NV_SI_RO_BOARD_S0_PCIE_CLK_CFG, 0x0348, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCA4_CFG, 0x0350, 0x02020202 >> +NV_SI_RO_BOARD_S0_RCA5_CFG, 0x0358, 0x02020202 >> +NV_SI_RO_BOARD_S0_RCA6_CFG, 0x0360, 0x02020202 >> +NV_SI_RO_BOARD_S0_RCA7_CFG, 0x0368, 0x02020003 >> +NV_SI_RO_BOARD_S0_RCA0_TXRX_G3PRESET, 0x0370, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCA1_TXRX_G3PRESET, 0x0378, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCA2_TXRX_G3PRESET, 0x0380, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCA3_TXRX_G3PRESET, 0x0388, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCB0A_TXRX_G3PRESET, 0x0390, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCB0B_TXRX_G3PRESET, 0x0398, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCB1A_TXRX_G3PRESET, 0x03A0, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCB1B_TXRX_G3PRESET, 0x03A8, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCB2A_TXRX_G3PRESET, 0x03B0, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCB2B_TXRX_G3PRESET, 0x03B8, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCB3A_TXRX_G3PRESET, 0x03C0, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCB3B_TXRX_G3PRESET, 0x03C8, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCA4_TXRX_G3PRESET, 0x03D0, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCA5_TXRX_G3PRESET, 0x03D8, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCA6_TXRX_G3PRESET, 0x03E0, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCA7_TXRX_G3PRESET, 0x03E8, 0x00000000 >> +NV_SI_RO_BOARD_S0_RCA0_TXRX_G4PRESET, 0x03F0, 0x57575757 >> +NV_SI_RO_BOARD_S0_RCA1_TXRX_G4PRESET, 0x03F8, 0x57575757 >> +NV_SI_RO_BOARD_S0_RCA2_TXRX_G4PRESET, 0x0400, 0x57575757 >> +NV_SI_RO_BOARD_S0_RCA3_TXRX_G4PRESET, 0x0408, 0x57575757 >> +NV_SI_RO_BOARD_S0_RCB0A_TXRX_G4PRESET, 0x0410, 0x57575757 >> +NV_SI_RO_BOARD_S0_RCB0B_TXRX_G4PRESET, 0x0418, 0x57575757 >> +NV_SI_RO_BOARD_S0_RCB1A_TXRX_G4PRESET, 0x0420, 0x57575757 >> +NV_SI_RO_BOARD_S0_RCB1B_TXRX_G4PRESET, 0x0428, 0x57575757 >> +NV_SI_RO_BOARD_S0_RCB2A_TXRX_G4PRESET, 0x0430, 0x57575757 >> +NV_SI_RO_BOARD_S0_RCB2B_TXRX_G4PRESET, 0x0438, 0x57575757 >> +NV_SI_RO_BOARD_S0_RCB3A_TXRX_G4PRESET, 0x0440, 0x57575757 >> +NV_SI_RO_BOARD_S0_RCB3B_TXRX_G4PRESET, 0x0448, 0x57575757 >> +NV_SI_RO_BOARD_S0_RCA4_TXRX_G4PRESET, 0x0450, 0x57575757 >> +NV_SI_RO_BOARD_S0_RCA5_TXRX_G4PRESET, 0x0458, 0x57575757 >> +NV_SI_RO_BOARD_S0_RCA6_TXRX_G4PRESET, 0x0460, 0x57575757 >> +NV_SI_RO_BOARD_S0_RCA7_TXRX_G4PRESET, 0x0468, 0x57575757 >> +NV_SI_RO_BOARD_S1_PCIE_CLK_CFG, 0x0470, 0x00000000 >> +NV_SI_RO_BOARD_S1_RCA4_CFG, 0x0478, 0x02020202 >> +NV_SI_RO_BOARD_S1_RCA5_CFG, 0x0480, 0x02020202 >> +NV_SI_RO_BOARD_S1_RCA6_CFG, 0x0488, 0x02020202 >> +NV_SI_RO_BOARD_S1_RCA7_CFG, 0x0490, 0x02020003 >> +NV_SI_RO_BOARD_S1_RCA2_TXRX_G3PRESET, 0x0498, 0x00000000 >> +NV_SI_RO_BOARD_S1_RCA3_TXRX_G3PRESET, 0x04A0, 0x00000000 >> +NV_SI_RO_BOARD_S1_RCB0A_TXRX_G3PRESET, 0x04A8, 0x00000000 >> +NV_SI_RO_BOARD_S1_RCB0B_TXRX_G3PRESET, 0x04B0, 0x00000000 >> +NV_SI_RO_BOARD_S1_RCB1A_TXRX_G3PRESET, 0x04B8, 0x00000000 >> +NV_SI_RO_BOARD_S1_RCB1B_TXRX_G3PRESET, 0x04C0, 0x00000000 >> +NV_SI_RO_BOARD_S1_RCB2A_TXRX_G3PRESET, 0x04C8, 0x00000000 >> +NV_SI_RO_BOARD_S1_RCB2B_TXRX_G3PRESET, 0x04D0, 0x00000000 >> +NV_SI_RO_BOARD_S1_RCB3A_TXRX_G3PRESET, 0x04D8, 0x00000000 >> +NV_SI_RO_BOARD_S1_RCB3B_TXRX_G3PRESET, 0x04E0, 0x00000000 >> +NV_SI_RO_BOARD_S1_RCA4_TXRX_G3PRESET, 0x04E8, 0x00000000 >> +NV_SI_RO_BOARD_S1_RCA5_TXRX_G3PRESET, 0x04F0, 0x00000000 >> +NV_SI_RO_BOARD_S1_RCA6_TXRX_G3PRESET, 0x04F8, 0x00000000 >> +NV_SI_RO_BOARD_S1_RCA7_TXRX_G3PRESET, 0x0500, 0x00000000 >> +NV_SI_RO_BOARD_S1_RCA2_TXRX_G4PRESET, 0x0508, 0x57575757 >> +NV_SI_RO_BOARD_S1_RCA3_TXRX_G4PRESET, 0x0510, 0x57575757 >> +NV_SI_RO_BOARD_S1_RCB0A_TXRX_G4PRESET, 0x0518, 0x57575757 >> +NV_SI_RO_BOARD_S1_RCB0B_TXRX_G4PRESET, 0x0520, 0x57575757 >> +NV_SI_RO_BOARD_S1_RCB1A_TXRX_G4PRESET, 0x0528, 0x57575757 >> +NV_SI_RO_BOARD_S1_RCB1B_TXRX_G4PRESET, 0x0530, 0x57575757 >> +NV_SI_RO_BOARD_S1_RCB2A_TXRX_G4PRESET, 0x0538, 0x57575757 >> +NV_SI_RO_BOARD_S1_RCB2B_TXRX_G4PRESET, 0x0540, 0x57575757 >> +NV_SI_RO_BOARD_S1_RCB3A_TXRX_G4PRESET, 0x0548, 0x57575757 >> +NV_SI_RO_BOARD_S1_RCB3B_TXRX_G4PRESET, 0x0550, 0x57575757 >> +NV_SI_RO_BOARD_S1_RCA4_TXRX_G4PRESET, 0x0558, 0x57575757 >> +NV_SI_RO_BOARD_S1_RCA5_TXRX_G4PRESET, 0x0560, 0x57575757 >> +NV_SI_RO_BOARD_S1_RCA6_TXRX_G4PRESET, 0x0568, 0x57575757 >> +NV_SI_RO_BOARD_S1_RCA7_TXRX_G4PRESET, 0x0570, 0x57575757 >> +NV_SI_RO_BOARD_2P_CE_MASK_THRESHOLD, 0x0578, 0x00000003 >> +NV_SI_RO_BOARD_2P_CE_MASK_INTERVAL, 0x0580, 0x000001A4 >> +NV_SI_RO_BOARD_SX_PHY_CFG_SETTING, 0x0588, 0x00000000 >> +NV_SI_RO_BOARD_DDR_PHY_DC_CLK, 0x0590, 0x00018000 >> +NV_SI_RO_BOARD_DDR_PHY_DC_DATA, 0x0598, 0x80018000 >> +NV_SI_RO_BOARD_SX_RCA0_TXRX_20GPRESET, 0x05A0, 0x00000000 >> +NV_SI_RO_BOARD_SX_RCA1_TXRX_20GPRESET, 0x05A8, 0x00000000 >> +NV_SI_RO_BOARD_SX_RCA2_TXRX_20GPRESET, 0x05B0, 0x00000000 >> +NV_SI_RO_BOARD_SX_RCA3_TXRX_20GPRESET, 0x05B8, 0x00000000 >> +NV_SI_RO_BOARD_SX_RCA0_TXRX_25GPRESET, 0x05C0, 0x00000000 >> +NV_SI_RO_BOARD_SX_RCA1_TXRX_25GPRESET, 0x05C8, 0x00000000 >> +NV_SI_RO_BOARD_SX_RCA2_TXRX_25GPRESET, 0x05D0, 0x00000000 >> +NV_SI_RO_BOARD_SX_RCA3_TXRX_25GPRESET, 0x05D8, 0x00000000 >> +NV_SI_RO_BOARD_DDR_2X_REFRESH_TEMP_THRESHOLD, 0x05E0, 0x00550055 >> +NV_SI_RO_BOARD_PCP_VRD_VOUT_WAIT_US, 0x05E8, 0x00000064 >> +NV_SI_RO_BOARD_PCP_VRD_VOUT_RESOLUTION_MV, 0x05F0, 0x00000005 >> +NV_SI_RO_BOARD_DVFS_VOLT_READ_BACK_EN, 0x05F8, 0x00000001 >> +NV_SI_RO_BOARD_DVFS_VOLT_READ_BACK_TIME, 0x0600, 0x00000002 >> +NV_SI_RO_BOARD_DVFS_VOUT_20MV_RAMP_TIME_US, 0x0608, 0x00000005 >> +NV_SI_RO_BOARD_PCIE_AER_FW_FIRST, 0x0610, 0x00000000 >> +NV_SI_RO_BOARD_RTC_GPI_LOCK_BYPASS, 0x0618, 0x00000000 >> +NV_SI_RO_BOARD_TPM_DISABLE, 0x0620, 0x00000000 >> +NV_SI_RO_BOARD_MESH_S0_CXG_RC_STRONG_ORDERING_EN, 0x0628, 0x00000000 >> +NV_SI_RO_BOARD_MESH_S1_CXG_RC_STRONG_ORDERING_EN, 0x0630, 0x00000000 >> +NV_SI_RO_BOARD_GPIO_SW_WATCHDOG_EN, 0x0638, 0x00000000 > There was also a few things in this patch where I felt names had > insufficient namespace - such as starting with TRNG_ or NV_. > I'm not going to insist on adding prefixes to those, I'm just going to > say I have warned you, and those might get you in trouble in the > future :) > > Best Regards, > > Leif