blob: 25d84335d26f381cfd6864a1dcd8292be4e0d9ec [file] [log] [blame]
Soby Mathewb4c6df42022-11-09 11:13:29 +00001/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4 */
5
6#ifndef ARCH_FEATURES_H
7#define ARCH_FEATURES_H
8
9#include <arch_helpers.h>
10#include <stdbool.h>
11
Javier Almansa Sobrinocfd32542024-10-09 19:38:56 +010012#define DEFINE_CONDITIONAL_SYSREG_READ_FUNC_(_name, _cond_name, \
13 _cond_checker, _default) \
14static inline u_register_t read_ ## _name ## _ ## _cond_name(void) \
15{ \
16 if (_cond_checker() == true) { \
17 return read_ ## _name(); \
18 } \
19 return _default; \
20}
21
22#define DEFINE_CONDITIONAL_SYSREG_WRITE_FUNC_(_name, _cond_name, \
23 _cond_checker) \
24static inline void write_ ## _name ## _ ## _cond_name(u_register_t v) \
25{ \
26 if (_cond_checker() == true) { \
27 write_ ## _name(v); \
28 } \
29}
30
31/* Define conditional read function for system register */
32#define DEFINE_CONDITIONAL_SYSREG_READ_FUNC(_name, _cond_name, \
33 _cond_checker, _default) \
34 DEFINE_CONDITIONAL_SYSREG_READ_FUNC_(_name, _cond_name, \
35 _cond_checker, _default)
36
37/* Define conditional read & write functions for system register */
38#define DEFINE_CONDITIONAL_SYSREG_RW_FUNCS(_name, _cond_name, \
39 _cond_checker, _default) \
40 DEFINE_CONDITIONAL_SYSREG_READ_FUNC_(_name, _cond_name, \
41 _cond_checker, _default) \
42 DEFINE_CONDITIONAL_SYSREG_WRITE_FUNC_(_name, _cond_name, _cond_checker)
43
Soby Mathewb4c6df42022-11-09 11:13:29 +000044static inline bool is_armv8_4_ttst_present(void)
45{
AlexeiFedorov537bee02023-02-02 13:38:23 +000046 return (EXTRACT(ID_AA64MMFR2_EL1_ST,
47 read_id_aa64mmfr2_el1()) == 1U);
Soby Mathewb4c6df42022-11-09 11:13:29 +000048}
49
50/*
51 * Check if SVE is enabled
52 * ID_AA64PFR0_EL1.SVE, bits [35:32]:
53 * 0b0000 SVE architectural state and programmers' model are not implemented.
54 * 0b0001 SVE architectural state and programmers' model are implemented.
55 */
56static inline bool is_feat_sve_present(void)
57{
AlexeiFedorov537bee02023-02-02 13:38:23 +000058 return (EXTRACT(ID_AA64PFR0_EL1_SVE,
59 read_id_aa64pfr0_el1()) != 0UL);
Soby Mathewb4c6df42022-11-09 11:13:29 +000060}
61
62/*
Arunachalam Ganapathy83f46ca2023-08-15 18:13:27 +010063 * Check if SME is enabled
64 * ID_AA64PFR1_EL1.SME, bits [27:24]:
65 * 0b0000 SME architectural state and programmers' model are not implemented.
66 * 0b0001 SME architectural state and programmers' model are implemented.
67 * 0b0010 SME2 implemented. As 0b0001, plus the SME2 ZT0 register.
68 */
69static inline bool is_feat_sme_present(void)
70{
71 return (EXTRACT(ID_AA64PFR1_EL1_SME, read_id_aa64pfr1_el1()) != 0UL);
72}
73
74/*
Soby Mathewb4c6df42022-11-09 11:13:29 +000075 * Check if RNDR is available
76 */
77static inline bool is_feat_rng_present(void)
78{
AlexeiFedorov537bee02023-02-02 13:38:23 +000079 return (EXTRACT(ID_AA64ISAR0_EL1_RNDR,
80 read_id_aa64isar0_el1()) != 0UL);
Soby Mathewb4c6df42022-11-09 11:13:29 +000081}
82
83/*
84 * Check if FEAT_VMID16 is implemented
85 * ID_AA64MMFR1_EL1.VMIDBits, bits [7:4]:
86 * 0b0000 8 bits.
87 * 0b0010 16 bits.
88 * All other values are reserved.
89 */
90static inline bool is_feat_vmid16_present(void)
91{
AlexeiFedorov537bee02023-02-02 13:38:23 +000092 return (EXTRACT(ID_AA64MMFR1_EL1_VMIDBits,
93 read_id_aa64mmfr1_el1()) == ID_AA64MMFR1_EL1_VMIDBits_16);
Soby Mathewb4c6df42022-11-09 11:13:29 +000094}
95
96/*
Javier Almansa Sobrino765a3162023-04-27 17:42:58 +010097 * Check if FEAT_LPA2 is implemented for stage 1.
98 * 4KB granule at stage 1 supports 52-bit input and output addresses:
99 * ID_AA64MMFR0_EL1.TGran4 bits [31:28]: 0b0001
Soby Mathewb4c6df42022-11-09 11:13:29 +0000100 */
101static inline bool is_feat_lpa2_4k_present(void)
102{
Javier Almansa Sobrino765a3162023-04-27 17:42:58 +0100103 return (EXTRACT(ID_AA64MMFR0_EL1_TGRAN4,
104 read_id_aa64mmfr0_el1()) == ID_AA64MMFR0_EL1_TGRAN4_LPA2);
105}
106
107/*
108 * Check if FEAT_LPA2 is implemented for stage 2.
109 * 4KB granule at stage 2 supports 52-bit input and output addresses:
110 * ID_AA64MMFR0_EL1.TGran4_2 bits [43:40]: 0b0011 ||
111 * (ID_AA64MMFR0_EL1.TGran4_2 bits [43:40]: 0b0000 &&
112 * ID_AA64MMFR0_EL1.TGran4 bits [31:28]: 0b0001 &&
113 */
114static inline bool is_feat_lpa2_4k_2_present(void)
115{
116 u_register_t id_aa64mmfr0_el1 = read_id_aa64mmfr0_el1();
117
118 return ((EXTRACT(ID_AA64MMFR0_EL1_TGRAN4_2, id_aa64mmfr0_el1) ==
119 ID_AA64MMFR0_EL1_TGRAN4_2_LPA2) ||
120 ((EXTRACT(ID_AA64MMFR0_EL1_TGRAN4_2, id_aa64mmfr0_el1) ==
121 ID_AA64MMFR0_EL1_TGRAN4_2_TGRAN4) && is_feat_lpa2_4k_present()));
Soby Mathewb4c6df42022-11-09 11:13:29 +0000122}
123
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000124/*
125 * Returns Performance Monitors Extension version.
126 * ID_AA64DFR0_EL1.PMUVer, bits [11:8]:
127 * 0b0000: Performance Monitors Extension not implemented
128 */
129static inline unsigned int read_pmu_version(void)
130{
AlexeiFedorov3f24ea72023-08-29 13:59:55 +0100131 return (unsigned int)EXTRACT(ID_AA64DFR0_EL1_PMUVer,
132 read_id_aa64dfr0_el1());
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000133}
134
AlexeiFedorov25164e32023-09-12 11:47:34 +0100135/*
136 * Check if FEAT_HPMN0 is implemented.
137 * ID_AA64DFR0_EL1.HPMN0, bits [63:60]:
138 * 0b0001: Setting MDCR_EL2.HPMN to zero has defined behavior
139 */
140static inline bool is_feat_hpmn0_present(void)
141{
142 return (EXTRACT(ID_AA64DFR0_EL1_HPMN0,
143 read_id_aa64dfr0_el1()) == 1UL);
144}
145
Javier Almansa Sobrinocfd32542024-10-09 19:38:56 +0100146/*
147 * Check if FEAT_DoubleFault2 is implemented.
148 * ID_AA64PFR1_EL1.DF2, bits [59:56]:
149 * 0b0000: FEAT_DoubleFault2 is not implemented
150 * 0b0001: FEAT_DoubleFault2 is implemented
151 * All other values: Reserved
152 */
153static inline bool is_feat_double_fault2_present(void)
154{
155 return (EXTRACT(ID_AA64PFR1_EL1_DF2,
156 read_id_aa64pfr1_el1()) == 1UL);
157}
158
159/*
160 * Check if FEAT_SCTLR2X is implemented.
161 * ID_AA64MMFR3_EL1.SCTLRX, bits [7:4]:
162 * 0b0000: FEAT_SCTLR2X is not implemented.
163 * 0b0001: FEAT_SCTLR2X is implemented.
164 * All other values: Reserved.
165 */
166static inline bool is_feat_sctlr2x_present(void)
167{
168 return (EXTRACT(ID_AA64MMFR3_EL1_SCTLRX,
169 read_id_aa64mmfr3_el1()) == 1UL);
170}
171
172DEFINE_CONDITIONAL_SYSREG_RW_FUNCS(sctlr2_el12, if_present, \
173 is_feat_sctlr2x_present, 0UL)
174
Soby Mathewb4c6df42022-11-09 11:13:29 +0000175unsigned int arch_feat_get_pa_width(void);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000176
177#endif /* ARCH_FEATURES_H */