From dff720276a3ee19af0cb658340ac8514ffce8359 Mon Sep 17 00:00:00 2001 From: Olivier Martin Date: Wed, 25 Feb 2015 19:14:26 +0000 Subject: ArmPlatformPkg/ArmVExpressDxe: Identify the current platform Add a function to ArmVExpressDxe to identify the current platform we are running on. This includes ARM32 and AArch64 models and hardware. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16931 6f19259b-4bc3-4df7-8a09-765794883524 --- .../ArmVExpressDxe/AArch64/ArmFvpDxeAArch64.c | 75 ++++++++++++++++++ .../ArmVExpressDxe/Arm/ArmFvpDxeArm.c | 85 ++++++++++++++++++++ .../ArmVExpressPkg/ArmVExpressDxe/ArmFvpDxe.c | 5 +- .../ArmVExpressPkg/ArmVExpressDxe/ArmFvpDxe.inf | 13 ++- .../ArmVExpressPkg/ArmVExpressDxe/ArmHwDxe.c | 37 ++++++++- .../ArmVExpressPkg/ArmVExpressDxe/ArmHwDxe.inf | 4 +- .../ArmVExpressDxe/ArmVExpressCommon.c | 48 +++++++++++ .../ArmVExpressDxe/ArmVExpressInternal.h | 92 ++++++++++++++++++++++ .../Library/ArmVExpressLibRTSM/RTSM.c | 5 -- .../Library/ArmVExpressLibRTSM/RTSMFoundation.c | 6 -- ArmPlatformPkg/Include/Library/ArmPlatformLib.h | 13 +++ 11 files changed, 365 insertions(+), 18 deletions(-) create mode 100644 ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/AArch64/ArmFvpDxeAArch64.c create mode 100644 ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/Arm/ArmFvpDxeArm.c create mode 100644 ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmVExpressCommon.c create mode 100644 ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmVExpressInternal.h diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/AArch64/ArmFvpDxeAArch64.c b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/AArch64/ArmFvpDxeAArch64.c new file mode 100644 index 0000000000..2c7c5fa5cc --- /dev/null +++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/AArch64/ArmFvpDxeAArch64.c @@ -0,0 +1,75 @@ +/** @file + + Copyright (c) 2014-2015, ARM Ltd. All rights reserved. + + This program and the accompanying materials are licensed and made available + under the terms and conditions of the BSD License which accompanies this + distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "ArmVExpressInternal.h" + +// +// Description of the two AARCH64 model platforms : +// just the platform id for the time being. +// Platform ids are defined in ArmVExpressInternal.h for +// all "ArmVExpress-like" platforms (AARCH64 or ARM architecture, +// model or hardware platforms). +// +CONST ARM_VEXPRESS_PLATFORM ArmVExpressPlatforms[] = { + { ARM_FVP_VEXPRESS_AEMv8x4 }, + { ARM_FVP_BASE_AEMv8x4_AEMv8x4 }, + { ARM_FVP_FOUNDATION }, + { ARM_FVP_VEXPRESS_UNKNOWN } +}; + +/** + Get information about the VExpress platform the firmware is running on. + + @param[out] Platform Address where the pointer to the platform information + (type ARM_VEXPRESS_PLATFORM*) should be stored. + The returned pointer does not point to an allocated + memory area. + + @retval EFI_SUCCESS The platform information was returned. + @retval EFI_NOT_FOUND The platform was not recognised. + +**/ +EFI_STATUS +ArmVExpressGetPlatform ( + OUT CONST ARM_VEXPRESS_PLATFORM** Platform + ) +{ + EFI_STATUS Status; + UINT32 SysId; + + ASSERT (Platform != NULL); + + Status = EFI_NOT_FOUND; + + SysId = MmioRead32 (ARM_VE_SYS_ID_REG); + if (SysId != ARM_RTSM_SYS_ID) { + // Take out the FVP GIC variant to reduce the permutations. The GIC driver + // detects the version and does the right thing. + SysId &= ~ARM_FVP_SYS_ID_VARIANT_MASK; + if (SysId == (ARM_FVP_BASE_SYS_ID & ~ARM_FVP_SYS_ID_VARIANT_MASK)) { + Status = ArmVExpressGetPlatformFromId (ARM_FVP_BASE_AEMv8x4_AEMv8x4, Platform); + } else if (SysId == (ARM_FVP_FOUNDATION_SYS_ID & ~ARM_FVP_SYS_ID_VARIANT_MASK)) { + Status = ArmVExpressGetPlatformFromId (ARM_FVP_FOUNDATION, Platform); + } + } else { + Status = ArmVExpressGetPlatformFromId (ARM_FVP_VEXPRESS_AEMv8x4, Platform); + } + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Unsupported AArch64 RTSM (SysId:0x%X).\n", SysId)); + ASSERT_EFI_ERROR (Status); + } + + return Status; +} diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/Arm/ArmFvpDxeArm.c b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/Arm/ArmFvpDxeArm.c new file mode 100644 index 0000000000..7ac89ad90a --- /dev/null +++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/Arm/ArmFvpDxeArm.c @@ -0,0 +1,85 @@ +/** @file + + Copyright (c) 2014, ARM Ltd. All rights reserved. + + This program and the accompanying materials are licensed and made available + under the terms and conditions of the BSD License which accompanies this + distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "ArmVExpressInternal.h" +#include // To get Core Count + +// +// Description of the four ARM model platforms : +// just the platform id for the time being. +// Platform ids are defined in ArmVExpressInternal.h for +// all "ArmVExpress-like" platforms (AARCH64 or ARM architecture, +// model or hardware platforms). +// +CONST ARM_VEXPRESS_PLATFORM ArmVExpressPlatforms[] = { + { ARM_FVP_VEXPRESS_A9x4 }, + { ARM_FVP_VEXPRESS_A15x1 }, + { ARM_FVP_VEXPRESS_A15x2 }, + { ARM_FVP_VEXPRESS_A15x4 }, + { ARM_FVP_VEXPRESS_UNKNOWN } +}; + +/** + Get information about the VExpress platform the firmware is running on. + + @param[out] Platform Address where the pointer to the platform information + (type ARM_VEXPRESS_PLATFORM*) should be stored. + The returned pointer does not point to an allocated + memory area. + + @retval EFI_SUCCESS The platform information was returned. + @retval EFI_NOT_FOUND The platform was not recognised. + +**/ +EFI_STATUS +ArmVExpressGetPlatform ( + OUT CONST ARM_VEXPRESS_PLATFORM** Platform + ) +{ + UINT32 SysId; + UINTN CpuType; + EFI_STATUS Status; + UINTN CoreCount; + + ASSERT (Platform != NULL); + + CpuType = 0; + Status = EFI_NOT_FOUND; + *Platform = NULL; + + SysId = MmioRead32 (ARM_VE_SYS_ID_REG); + if (SysId == ARM_RTSM_SYS_ID) { + // Get the Cortex-A version + CpuType = (ArmReadMidr () >> 4) & ARM_CPU_TYPE_MASK; + if (CpuType == ARM_CPU_TYPE_A9) { + Status = ArmVExpressGetPlatformFromId (ARM_FVP_VEXPRESS_A9x4, Platform); + } else if (CpuType == ARM_CPU_TYPE_A15) { + CoreCount = ArmGetCpuCountPerCluster (); + if (CoreCount == 1) { + Status = ArmVExpressGetPlatformFromId (ARM_FVP_VEXPRESS_A15x1, Platform); + } else if (CoreCount == 2) { + Status = ArmVExpressGetPlatformFromId (ARM_FVP_VEXPRESS_A15x2, Platform); + } else if (CoreCount == 4) { + Status = ArmVExpressGetPlatformFromId (ARM_FVP_VEXPRESS_A15x4, Platform); + } + } + } + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Unsupported platform (SysId:0x%X, CpuType:0x%X)\n", SysId, CpuType)); + ASSERT_EFI_ERROR (Status); + } + + return Status; +} diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmFvpDxe.c b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmFvpDxe.c index 64e4158053..6a3d350382 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmFvpDxe.c +++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmFvpDxe.c @@ -12,10 +12,9 @@ **/ -#include +#include "ArmVExpressInternal.h" + #include -#include -#include #include #define ARM_FVP_BASE_VIRTIO_BLOCK_BASE 0x1c130000 diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmFvpDxe.inf b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmFvpDxe.inf index 7112144095..8a096baae2 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmFvpDxe.inf +++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmFvpDxe.inf @@ -22,15 +22,26 @@ [Sources.common] ArmFvpDxe.c + ArmVExpressCommon.c + +[Sources.ARM] + Arm/ArmFvpDxeArm.c + +[Sources.AARCH64] + AArch64/ArmFvpDxeAArch64.c [Packages] MdePkg/MdePkg.dec + ArmPkg/ArmPkg.dec ArmPlatformPkg/ArmPlatformPkg.dec + ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec OvmfPkg/OvmfPkg.dec [LibraryClasses] ArmShellCmdRunAxfLib + ArmLib + ArmPlatformLib + BaseMemoryLib UefiDriverEntryPoint UefiBootServicesTableLib VirtioMmioDeviceLib - BaseMemoryLib diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmHwDxe.c b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmHwDxe.c index 7ed5c61059..66ec9963ca 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmHwDxe.c +++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmHwDxe.c @@ -12,10 +12,43 @@ **/ -#include -#include +#include "ArmVExpressInternal.h" #include +// +// Description of the four hardware platforms : +// just the platform id for the time being. +// Platform ids are defined in ArmVExpressInternal.h for +// all "ArmVExpress-like" platforms (AARCH64 or ARM architecture, +// model or hardware platforms). +// +CONST ARM_VEXPRESS_PLATFORM ArmVExpressPlatforms[] = { + { ARM_HW_A9x4 }, + { ARM_HW_A15x2_A7x3 }, + { ARM_HW_A15 }, + { ARM_HW_A5 }, + { ARM_FVP_VEXPRESS_UNKNOWN } +}; + +/** + Get information about the VExpress platform the firmware is running on. + + @param[out] Platform Address where the pointer to the platform information + (type ARM_VEXPRESS_PLATFORM*) should be stored. + The returned pointer does not point to an allocated + memory area. Not used here. + + @retval EFI_NOT_FOUND The platform was not recognised. + +**/ +EFI_STATUS +ArmVExpressGetPlatform ( + OUT CONST ARM_VEXPRESS_PLATFORM** Platform + ) +{ + return EFI_NOT_FOUND; +} + EFI_STATUS EFIAPI ArmHwInitialise ( diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmHwDxe.inf b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmHwDxe.inf index 3bcdbd06fb..92a193f8a0 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmHwDxe.inf +++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmHwDxe.inf @@ -22,10 +22,12 @@ [Sources.common] ArmHwDxe.c + ArmVExpressCommon.c [Packages] - MdePkg/MdePkg.dec + ArmPkg/ArmPkg.dec ArmPlatformPkg/ArmPlatformPkg.dec + MdePkg/MdePkg.dec [LibraryClasses] ArmShellCmdRunAxfLib diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmVExpressCommon.c b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmVExpressCommon.c new file mode 100644 index 0000000000..e1cac7fb37 --- /dev/null +++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmVExpressCommon.c @@ -0,0 +1,48 @@ +/** @file + + Copyright (c) 2014, ARM Ltd. All rights reserved. + + This program and the accompanying materials are licensed and made available + under the terms and conditions of the BSD License which accompanies this + distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "ArmVExpressInternal.h" + +/** + Get information about the VExpress platform the firmware is running on given its Id. + + @param[in] PlatformId Id of the VExpress platform. + @param[out] Platform Address where the pointer to the platform information + (type ARM_VEXPRESS_PLATFORM*) should be stored. + The returned pointer does not point to an allocated + memory area. + + @retval EFI_SUCCESS The platform information was returned. + @retval EFI_NOT_FOUND The platform was not recognised. + +**/ +EFI_STATUS +ArmVExpressGetPlatformFromId ( + IN CONST ARM_VEXPRESS_PLATFORM_ID PlatformId, + OUT CONST ARM_VEXPRESS_PLATFORM** Platform + ) +{ + UINTN Index; + + ASSERT (Platform != NULL); + + for (Index = 0; ArmVExpressPlatforms[Index].Id != ARM_FVP_VEXPRESS_UNKNOWN; Index++) { + if (ArmVExpressPlatforms[Index].Id == PlatformId) { + *Platform = &ArmVExpressPlatforms[Index]; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmVExpressInternal.h b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmVExpressInternal.h new file mode 100644 index 0000000000..2e9335047a --- /dev/null +++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmVExpressInternal.h @@ -0,0 +1,92 @@ +/** @file + + Copyright (c) 2014, ARM Ltd. All rights reserved. + + This program and the accompanying materials are licensed and made available + under the terms and conditions of the BSD License which accompanies this + distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __ARM_VEXPRESS_INTERNAL_H__ +#define __ARM_VEXPRESS_INTERNAL_H__ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +// This 'enum' is needed as variations based on existing platform exist +typedef enum { + ARM_FVP_VEXPRESS_UNKNOWN = 0, + ARM_FVP_VEXPRESS_A9x4, + ARM_FVP_VEXPRESS_A15x1, + ARM_FVP_VEXPRESS_A15x2, + ARM_FVP_VEXPRESS_A15x4, + ARM_FVP_VEXPRESS_A15x1_A7x1, + ARM_FVP_VEXPRESS_A15x4_A7x4, + ARM_FVP_VEXPRESS_AEMv8x4, + ARM_FVP_BASE_AEMv8x4_AEMv8x4, + ARM_FVP_FOUNDATION, + ARM_HW_A9x4, + ARM_HW_A15x2_A7x3, + ARM_HW_A15, + ARM_HW_A5 +} ARM_VEXPRESS_PLATFORM_ID; + +typedef struct { + ARM_VEXPRESS_PLATFORM_ID Id; + // Will be extended with platform specific information +} ARM_VEXPRESS_PLATFORM; + +// Array that contains the list of the VExpress based platform supported by this DXE driver +extern CONST ARM_VEXPRESS_PLATFORM ArmVExpressPlatforms[]; + +/** + Get information about the VExpress platform the firmware is running on given its Id. + + @param[in] PlatformId Id of the VExpress platform. + @param[out] Platform Address where the pointer to the platform information + (type ARM_VEXPRESS_PLATFORM*) should be stored. + The returned pointer does not point to an allocated + memory area. + + @retval EFI_SUCCESS The platform information was returned. + @retval EFI_NOT_FOUND The platform was not recognised. + +**/ +EFI_STATUS +ArmVExpressGetPlatformFromId ( + IN CONST ARM_VEXPRESS_PLATFORM_ID PlatformId, + OUT CONST ARM_VEXPRESS_PLATFORM** Platform + ); + +/** + + Get information about the VExpress platform the firmware is running on. + + @param[out] Platform Address where the pointer to the platform information + (type ARM_VEXPRESS_PLATFORM*) should be stored. + The returned pointer does not point to an allocated + memory area. + + @retval EFI_SUCCESS The platform information was returned. + @retval EFI_NOT_FOUND The platform was not recognised. + +**/ +EFI_STATUS +ArmVExpressGetPlatform ( + OUT CONST ARM_VEXPRESS_PLATFORM** Platform + ); + +#endif // __ARM_VEXPRESS_INTERNAL_H__ diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/RTSM.c b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/RTSM.c index ea73f62956..6ec512bfb7 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/RTSM.c +++ b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/RTSM.c @@ -21,11 +21,6 @@ #include -UINTN -ArmGetCpuCountPerCluster ( - VOID - ); - ARM_CORE_INFO mVersatileExpressMpCoreInfoTable[] = { { // Cluster 0, Core 0 diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/RTSMFoundation.c b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/RTSMFoundation.c index 1b1671a867..33bef8366d 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/RTSMFoundation.c +++ b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/RTSMFoundation.c @@ -21,12 +21,6 @@ #include - -UINTN -ArmGetCpuCountPerCluster ( - VOID - ); - ARM_CORE_INFO mVersatileExpressMpCoreInfoTable[] = { { // Cluster 0, Core 0 diff --git a/ArmPlatformPkg/Include/Library/ArmPlatformLib.h b/ArmPlatformPkg/Include/Library/ArmPlatformLib.h index 77561a3d05..fe3bc4bb8e 100644 --- a/ArmPlatformPkg/Include/Library/ArmPlatformLib.h +++ b/ArmPlatformPkg/Include/Library/ArmPlatformLib.h @@ -40,6 +40,19 @@ typedef struct { UINT64 NumberOfBytes; } ARM_SYSTEM_MEMORY_REGION_DESCRIPTOR; +/** + Return the core per cluster. The method may differ per core type + + This function might be called from assembler before any stack is set. + + @return Return the core count per cluster + +**/ +UINTN +ArmGetCpuCountPerCluster ( + VOID + ); + /** Return the core position from the value of its MpId register -- cgit v1.2.3