arm64: add CHECK_CPU_FEAT() for checking feature support in assembly

Add a new macro under asm.h to check whether a given CPU feature is
supported. There are a number of existing places where an ID register is
checked, and these have been updated in this change. These are for GIC
special registers, HAFDBS and HCX.

When calling, pass a temporary registers who's value is not important,
the name of the ID register (minus the exception level), the name of the
feature, and a label to jump to should the feature not be present. The
feature name should match with the macros defined in armreg.h or
hypervisor.h. Any feature-specific instructions can then be placed
between the macro and the label.

Reviewed by:	andrew
Sponsored by:	Arm Ltd
Differential Revision:	https://reviews.freebsd.org/D48813
Signed-off-by: Harry Moulton <[email protected]>
This commit is contained in:
Harry Moulton authored and Andrew Turner committed 2025-02-17 16:07:35 +00:00
1 parent 90a3b6a7a4
commit 05f6f65c3b
2 files changed
+14 -13

No files matched your search

+4 -13
View File
@@ -403,10 +403,7 @@ LENTRY(enter_kernel_el)
* Configure the Extended Hypervisor register. This is only valid if
* FEAT_HCX is enabled.
*/
mrs x2, id_aa64mmfr1_el1
ubfx x2, x2, #ID_AA64MMFR1_HCX_SHIFT, #ID_AA64MMFR1_HCX_WIDTH
cbz x2, 2f
CHECK_CPU_FEAT(x2, ID_AA64MMFR1, HCX, 2f)
/* Extended Hypervisor Configuration */
mov x2, xzr
msr HCRX_EL2_REG, x2
@@ -422,12 +419,8 @@ LENTRY(enter_kernel_el)
/* Zero vttbr_el2 so a hypervisor can tell the host and guest apart */
msr vttbr_el2, xzr
/* Configure GICv3 CPU interface */
mrs x2, id_aa64pfr0_el1
/* Extract GIC bits from the register */
ubfx x2, x2, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_BITS
/* GIC[3:0] != 0000 - GIC CPU interface via special regs. supported */
cbz x2, 3f
/* Check the CPU supports GIC, and configure the CPU interface */
CHECK_CPU_FEAT(x2, ID_AA64PFR0, GIC, 3f)
mrs x2, icc_sre_el2
orr x2, x2, #ICC_SRE_EL2_EN /* Enable access from insecure EL1 */
@@ -958,9 +951,7 @@ LENTRY(start_mmu)
* HW management of dirty state is set in C code as it may
* need to be disabled because of CPU errata.
*/
mrs x3, id_aa64mmfr1_el1
and x3, x3, #(ID_AA64MMFR1_HAFDBS_MASK)
cbz x3, 1f
CHECK_CPU_FEAT(x3, ID_AA64MMFR1, HAFDBS, 1f)
orr x2, x2, #(TCR_HA)
1:
+10
View File
@@ -72,6 +72,16 @@
/* Alias for link register x30 */
#define lr x30
/*
* Check whether a given cpu feature is present, in the case it is not we jump
* to the given label. The tmp register should be a register able to hold the
* temporary data.
*/
#define CHECK_CPU_FEAT(tmp, feat_reg, feat, label) \
mrs tmp, ##feat_reg##_el1; \
ubfx tmp, tmp, ##feat_reg##_##feat##_SHIFT, ##feat_reg##_##feat##_WIDTH; \
cbz tmp, label
/*
* Sets the trap fault handler. The exception handler will return to the
* address in the handler register on a data abort or the xzr register to