Add macro definitions and helper functions to access AArch64 capabilities described in the AA64Isar0 register.
Signed-off-by: Pierre Gondois <pierre.gond...@arm.com> --- ArmPkg/Include/Chipset/AArch64.h | 60 +++- ArmPkg/Include/Library/ArmLib.h | 228 ++++++++++++- ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c | 367 +++++++++++++++++++++ 3 files changed, 653 insertions(+), 2 deletions(-) diff --git a/ArmPkg/Include/Chipset/AArch64.h b/ArmPkg/Include/Chipset/AArch64.h index 5390bf0a2774..97c20e71a811 100644 --- a/ArmPkg/Include/Chipset/AArch64.h +++ b/ArmPkg/Include/Chipset/AArch64.h @@ -1,7 +1,7 @@ /** @file Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> - Copyright (c) 2011 - 2021, Arm Limited. All rights reserved.<BR> + Copyright (c) 2011 - 2023, Arm Limited. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent @@ -127,6 +127,64 @@ // build for ARMv8.0, we need to define the register here. #define ID_AA64MMFR2_EL1 S3_0_C0_C7_2 +// +// Bit shifts for the ID_AA64ISAR0_EL1 register. +// +#define ARM_ID_AA64ISAR0_EL1_AES_SHIFT (4U) +#define ARM_ID_AA64ISAR0_EL1_SHA1_SHIFT (8U) +#define ARM_ID_AA64ISAR0_EL1_SHA2_SHIFT (12U) +#define ARM_ID_AA64ISAR0_EL1_CRC32_SHIFT (16U) +#define ARM_ID_AA64ISAR0_EL1_ATOMIC_SHIFT (20U) +#define ARM_ID_AA64ISAR0_EL1_RDM_SHIFT (28U) +#define ARM_ID_AA64ISAR0_EL1_SHA3_SHIFT (32U) +#define ARM_ID_AA64ISAR0_EL1_SM3_SHIFT (36U) +#define ARM_ID_AA64ISAR0_EL1_SM4_SHIFT (40U) +#define ARM_ID_AA64ISAR0_EL1_DP_SHIFT (44U) +#define ARM_ID_AA64ISAR0_EL1_FHM_SHIFT (48U) +#define ARM_ID_AA64ISAR0_EL1_TS_SHIFT (52U) +#define ARM_ID_AA64ISAR0_EL1_TLB_SHIFT (56U) +#define ARM_ID_AA64ISAR0_EL1_RNDR_SHIFT (60U) + +// +// Bit masks for the ID_AA64ISAR0_EL1 fields. +// +#define ARM_ID_AA64ISAR0_EL1_AES_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_SHA1_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_SHA2_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_CRC32_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_ATOMIC_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_RDM_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_SHA3_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_SM3_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_SM4_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_DP_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_FHM_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_TS_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_TLB_MASK (0xFU) +#define ARM_ID_AA64ISAR0_EL1_RNDR_MASK (0xFU) + +// +// Bit masks for the ID_AA64ISAR0_EL1 field values. +// +#define ARM_ID_AA64ISAR0_EL1_AES_FEAT_AES_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_AES_FEAT_PMULL_MASK (0x2U) +#define ARM_ID_AA64ISAR0_EL1_SHA1_FEAT_SHA1_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_SHA2_FEAT_SHA256_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_SHA2_FEAT_SHA512_MASK (0x2U) +#define ARM_ID_AA64ISAR0_EL1_CRC32_HAVE_CRC32_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_ATOMIC_FEAT_LSE_MASK (0x2U) +#define ARM_ID_AA64ISAR0_EL1_RDM_FEAT_RDM_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_SHA3_FEAT_SHA3_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_SM3_FEAT_SM3_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_SM4_FEAT_SM4_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_DP_FEAT_DOTPROD_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_FHM_FEAT_FHM_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_TS_FEAT_FLAGM_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_TS_FEAT_FLAGM2_MASK (0x2U) +#define ARM_ID_AA64ISAR0_EL1_TLB_FEAT_TLBIOS_MASK (0x1U) +#define ARM_ID_AA64ISAR0_EL1_TLB_FEAT_TLBIRANGE_MASK (0x2U) +#define ARM_ID_AA64ISAR0_EL1_RNDR_FEAT_RNG_MASK (0x1U) + #define VECTOR_BASE(tbl) \ .section .text.##tbl##,"ax"; \ .align 11; \ diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h index 6aa8a48f07f3..a176fcd7bf0a 100644 --- a/ArmPkg/Include/Library/ArmLib.h +++ b/ArmPkg/Include/Library/ArmLib.h @@ -1,7 +1,7 @@ /** @file Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> - Copyright (c) 2011 - 2016, ARM Ltd. All rights reserved.<BR> + Copyright (c) 2011 - 2023, Arm Limited. All rights reserved.<BR> Copyright (c) 2020 - 2021, NUVIA Inc. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent @@ -805,6 +805,232 @@ ArmHasEte ( VOID ); +/** Read AA64Isar0 register. + + @return AA64Isar0's register value. +**/ +UINTN +EFIAPI +ArmReadIdAA64Isar0 ( + VOID + ); + +/** + Checks whether the CPU implements FEAT_AES. + + @retval TRUE FEAT_AES is implemented. + @retval FALSE FEAT_AES is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasAes ( + VOID + ); + +/** + Checks whether the CPU implements FEAT_PMULL. + + @retval TRUE FEAT_PMULL is implemented. + @retval FALSE FEAT_PMULL is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasPmull ( + VOID + ); + +/** + Checks whether the CPU implements FEAT_SHA1. + + @retval TRUE FEAT_SHA1 is implemented. + @retval FALSE FEAT_SHA1 is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasSha1 ( + VOID + ); + +/** + Checks whether the CPU implements FEAT_SHA256. + + @retval TRUE FEAT_SHA256 is implemented. + @retval FALSE FEAT_SHA256 is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasSha256 ( + VOID + ); + +/** + Checks whether the CPU implements FEAT_SHA512. + + @retval TRUE FEAT_SHA512 is implemented. + @retval FALSE FEAT_SHA512 is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasSha512 ( + VOID + ); + +/** + Checks whether the CPU implements CRC32 instruction. + + @retval TRUE CRC32 instruction is implemented. + @retval FALSE CRC32 instruction is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasCrc32 ( + VOID + ); + +/** + Checks whether the CPU implements FEAT_LSE. + + @retval TRUE FEAT_LSE is implemented. + @retval FALSE FEAT_LSE is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasLse ( + VOID + ); + +/** + Checks whether the CPU implements FEAT_RDM. + + @retval TRUE FEAT_RDM is implemented. + @retval FALSE FEAT_RDM is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasRdm ( + VOID + ); + +/** + Checks whether the CPU implements FEAT_SHA3. + + @retval TRUE FEAT_SHA3 is implemented. + @retval FALSE FEAT_SHA3 is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasSha3 ( + VOID + ); + +/** + Checks whether the CPU implements FEAT_SM3. + + @retval TRUE FEAT_SM3 is implemented. + @retval FALSE FEAT_SM3 is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasSm3 ( + VOID + ); + +/** + Checks whether the CPU implements FEAT_SM4. + + @retval TRUE FEAT_SM4 is implemented. + @retval FALSE FEAT_SM4 is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasSm4 ( + VOID + ); + +/** + Checks whether the CPU implements FEAT_DotProd. + + @retval TRUE FEAT_DotProd is implemented. + @retval FALSE FEAT_DotProd is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasDp ( + VOID + ); + +/** + Checks whether the CPU implements FEAT_FHM. + + @retval TRUE FEAT_FHM is implemented. + @retval FALSE FEAT_FHM is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasFhm ( + VOID + ); + +/** + Checks whether the CPU implements FEAT_FlagM. + + @retval TRUE FEAT_FlagM is implemented. + @retval FALSE FEAT_FlagM is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasFlagm ( + VOID + ); + +/** + Checks whether the CPU implements FEAT_FlagM2. + + @retval TRUE FEAT_FlagM2 is implemented. + @retval FALSE FEAT_FlagM2 is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasFlagm2 ( + VOID + ); + +/** + Checks whether the CPU implements FEAT_TLBIOS. + + @retval TRUE FEAT_TLBIOS is implemented. + @retval FALSE FEAT_TLBIOS is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasTlbios ( + VOID + ); + +/** + Checks whether the CPU implements FEAT_TLBIRANGE. + + @retval TRUE FEAT_TLBIRANGE is implemented. + @retval FALSE FEAT_TLBIRANGE is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasTlbirange ( + VOID + ); + +/** + Checks whether the CPU implements FEAT_RNG. + + @retval TRUE FEAT_RNG is implemented. + @retval FALSE FEAT_RNG is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasRndr ( + VOID + ); + #endif // MDE_CPU_AARCH64 #ifdef MDE_CPU_ARM diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c index 87285465871d..c64c015844a6 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c @@ -18,6 +18,19 @@ #include "AArch64Lib.h" #include "ArmLibPrivate.h" +/** Get bits from a value. + + Shift the input value from 'shift' bits and apply 'mask'. + + @param value The value to get the bits from. + @param shift Index of the bits to read. + @param mask Mask to apply to the value once shifted. + + @return The desired bitfield from the value. +**/ +#define GET_BITFIELD(value, shift, mask) \ + ((value >> shift) & mask) + VOID AArch64DataCacheOperation ( IN AARCH64_CACHE_OPERATION DataCacheOperation @@ -150,3 +163,357 @@ ArmHasEte ( // The ID_AA64DFR0_EL1.TraceVer field identifies the presence of FEAT_ETE. return ((ArmReadIdAA64Dfr0 () & AARCH64_DFR0_TRACEVER) != 0); } + +/** + Checks whether the CPU implements FEAT_AES. + + @retval TRUE FEAT_AES is implemented. + @retval FALSE FEAT_AES is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasAes ( + VOID + ) +{ + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_AES_SHIFT, + ARM_ID_AA64ISAR0_EL1_AES_MASK + ) != 0; +} + +/** + Checks whether the CPU implements FEAT_PMULL. + + @retval TRUE FEAT_PMULL is implemented. + @retval FALSE FEAT_PMULL is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasPmull ( + VOID + ) +{ + // + // Only check BIT1 of AES field, bits [7:4] + // + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_AES_SHIFT, + ARM_ID_AA64ISAR0_EL1_AES_FEAT_PMULL_MASK + ) != 0; +} + +/** + Checks whether the CPU implements FEAT_SHA1. + + @retval TRUE FEAT_SHA1 is implemented. + @retval FALSE FEAT_SHA1 is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasSha1 ( + VOID + ) +{ + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_SHA1_SHIFT, + ARM_ID_AA64ISAR0_EL1_SHA1_MASK + ) != 0; +} + +/** + Checks whether the CPU implements FEAT_SHA256. + + @retval TRUE FEAT_SHA256 is implemented. + @retval FALSE FEAT_SHA256 is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasSha256 ( + VOID + ) +{ + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_SHA2_SHIFT, + ARM_ID_AA64ISAR0_EL1_SHA2_MASK + ) != 0; +} + +/** + Checks whether the CPU implements FEAT_SHA512. + + @retval TRUE FEAT_SHA512 is implemented. + @retval FALSE FEAT_SHA512 is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasSha512 ( + VOID + ) +{ + // + // Only check BIT1 of SHA2 field, bits [15:12] + // + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_SHA2_SHIFT, + ARM_ID_AA64ISAR0_EL1_SHA2_FEAT_SHA512_MASK + ) != 0; +} + +/** + Checks whether the CPU implements CRC32 instruction. + + @retval TRUE CRC32 instruction is implemented. + @retval FALSE CRC32 instruction is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasCrc32 ( + VOID + ) +{ + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_CRC32_SHIFT, + ARM_ID_AA64ISAR0_EL1_CRC32_MASK + ) != 0; +} + +/** + Checks whether the CPU implements FEAT_LSE. + + @retval TRUE FEAT_LSE is implemented. + @retval FALSE FEAT_LSE is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasLse ( + VOID + ) +{ + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_ATOMIC_SHIFT, + ARM_ID_AA64ISAR0_EL1_ATOMIC_MASK + ) != 0; +} + +/** + Checks whether the CPU implements FEAT_RDM. + + @retval TRUE FEAT_RDM is implemented. + @retval FALSE FEAT_RDM is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasRdm ( + VOID + ) +{ + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_RDM_SHIFT, + ARM_ID_AA64ISAR0_EL1_RDM_MASK + ) != 0; +} + +/** + Checks whether the CPU implements FEAT_SHA3. + + @retval TRUE FEAT_SHA3 is implemented. + @retval FALSE FEAT_SHA3 is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasSha3 ( + VOID + ) +{ + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_SHA3_SHIFT, + ARM_ID_AA64ISAR0_EL1_SHA3_MASK + ) != 0; +} + +/** + Checks whether the CPU implements FEAT_SM3. + + @retval TRUE FEAT_SM3 is implemented. + @retval FALSE FEAT_SM3 is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasSm3 ( + VOID + ) +{ + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_SM3_SHIFT, + ARM_ID_AA64ISAR0_EL1_SM3_MASK + ) != 0; +} + +/** + Checks whether the CPU implements FEAT_SM4. + + @retval TRUE FEAT_SM4 is implemented. + @retval FALSE FEAT_SM4 is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasSm4 ( + VOID + ) +{ + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_SM4_SHIFT, + ARM_ID_AA64ISAR0_EL1_SM4_MASK + ) != 0; +} + +/** + Checks whether the CPU implements FEAT_DotProd. + + @retval TRUE FEAT_DotProd is implemented. + @retval FALSE FEAT_DotProd is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasDp ( + VOID + ) +{ + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_DP_SHIFT, + ARM_ID_AA64ISAR0_EL1_DP_MASK + ) != 0; +} + +/** + Checks whether the CPU implements FEAT_FHM. + + @retval TRUE FEAT_FHM is implemented. + @retval FALSE FEAT_FHM is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasFhm ( + VOID + ) +{ + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_FHM_SHIFT, + ARM_ID_AA64ISAR0_EL1_FHM_MASK + ) != 0; +} + +/** + Checks whether the CPU implements FEAT_FlagM. + + @retval TRUE FEAT_FlagM is implemented. + @retval FALSE FEAT_FlagM is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasFlagm ( + VOID + ) +{ + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_TS_SHIFT, + ARM_ID_AA64ISAR0_EL1_TS_MASK + ) != 0; +} + +/** + Checks whether the CPU implements FEAT_FlagM2. + + @retval TRUE FEAT_FlagM2 is implemented. + @retval FALSE FEAT_FlagM2 is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasFlagm2 ( + VOID + ) +{ + // + // Only check BIT1 of TS field, bits [55:52] + // + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_TS_SHIFT, + ARM_ID_AA64ISAR0_EL1_TS_FEAT_FLAGM2_MASK + ) != 0; +} + +/** + Checks whether the CPU implements FEAT_TLBIOS. + + @retval TRUE FEAT_TLBIOS is implemented. + @retval FALSE FEAT_TLBIOS is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasTlbios ( + VOID + ) +{ + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_TLB_SHIFT, + ARM_ID_AA64ISAR0_EL1_TLB_MASK + ) != 0; +} + +/** + Checks whether the CPU implements FEAT_TLBIRANGE. + + @retval TRUE FEAT_TLBIRANGE is implemented. + @retval FALSE FEAT_TLBIRANGE is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasTlbirange ( + VOID + ) +{ + // + // Only check BIT1 of TLB field, bits [59:56] + // + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_TLB_SHIFT, + ARM_ID_AA64ISAR0_EL1_TLB_FEAT_TLBIRANGE_MASK + ) != 0; +} + +/** + Checks whether the CPU implements FEAT_RNG. + + @retval TRUE FEAT_RNG is implemented. + @retval FALSE FEAT_RNG is not implemented. +**/ +BOOLEAN +EFIAPI +ArmHasRndr ( + VOID + ) +{ + return GET_BITFIELD ( + ArmReadIdAA64Isar0 (), + ARM_ID_AA64ISAR0_EL1_RNDR_SHIFT, + ARM_ID_AA64ISAR0_EL1_RNDR_MASK + ) != 0; +} -- 2.25.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#111474): https://edk2.groups.io/g/devel/message/111474 Mute This Topic: https://groups.io/mt/102707262/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-