162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2012,2013 - ARM Ltd 462306a36Sopenharmony_ci * Author: Marc Zyngier <marc.zyngier@arm.com> 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#ifndef __ARM_KVM_INIT_H__ 862306a36Sopenharmony_ci#define __ARM_KVM_INIT_H__ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#ifndef __ASSEMBLY__ 1162306a36Sopenharmony_ci#error Assembly-only header 1262306a36Sopenharmony_ci#endif 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <asm/kvm_arm.h> 1562306a36Sopenharmony_ci#include <asm/ptrace.h> 1662306a36Sopenharmony_ci#include <asm/sysreg.h> 1762306a36Sopenharmony_ci#include <linux/irqchip/arm-gic-v3.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci.macro __init_el2_sctlr 2062306a36Sopenharmony_ci mov_q x0, INIT_SCTLR_EL2_MMU_OFF 2162306a36Sopenharmony_ci msr sctlr_el2, x0 2262306a36Sopenharmony_ci isb 2362306a36Sopenharmony_ci.endm 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci.macro __init_el2_hcrx 2662306a36Sopenharmony_ci mrs x0, id_aa64mmfr1_el1 2762306a36Sopenharmony_ci ubfx x0, x0, #ID_AA64MMFR1_EL1_HCX_SHIFT, #4 2862306a36Sopenharmony_ci cbz x0, .Lskip_hcrx_\@ 2962306a36Sopenharmony_ci mov_q x0, HCRX_HOST_FLAGS 3062306a36Sopenharmony_ci msr_s SYS_HCRX_EL2, x0 3162306a36Sopenharmony_ci.Lskip_hcrx_\@: 3262306a36Sopenharmony_ci.endm 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci/* Check if running in host at EL2 mode, i.e., (h)VHE. Jump to fail if not. */ 3562306a36Sopenharmony_ci.macro __check_hvhe fail, tmp 3662306a36Sopenharmony_ci mrs \tmp, hcr_el2 3762306a36Sopenharmony_ci and \tmp, \tmp, #HCR_E2H 3862306a36Sopenharmony_ci cbz \tmp, \fail 3962306a36Sopenharmony_ci.endm 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci/* 4262306a36Sopenharmony_ci * Allow Non-secure EL1 and EL0 to access physical timer and counter. 4362306a36Sopenharmony_ci * This is not necessary for VHE, since the host kernel runs in EL2, 4462306a36Sopenharmony_ci * and EL0 accesses are configured in the later stage of boot process. 4562306a36Sopenharmony_ci * Note that when HCR_EL2.E2H == 1, CNTHCTL_EL2 has the same bit layout 4662306a36Sopenharmony_ci * as CNTKCTL_EL1, and CNTKCTL_EL1 accessing instructions are redefined 4762306a36Sopenharmony_ci * to access CNTHCTL_EL2. This allows the kernel designed to run at EL1 4862306a36Sopenharmony_ci * to transparently mess with the EL0 bits via CNTKCTL_EL1 access in 4962306a36Sopenharmony_ci * EL2. 5062306a36Sopenharmony_ci */ 5162306a36Sopenharmony_ci.macro __init_el2_timers 5262306a36Sopenharmony_ci mov x0, #3 // Enable EL1 physical timers 5362306a36Sopenharmony_ci __check_hvhe .LnVHE_\@, x1 5462306a36Sopenharmony_ci lsl x0, x0, #10 5562306a36Sopenharmony_ci.LnVHE_\@: 5662306a36Sopenharmony_ci msr cnthctl_el2, x0 5762306a36Sopenharmony_ci msr cntvoff_el2, xzr // Clear virtual offset 5862306a36Sopenharmony_ci.endm 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci.macro __init_el2_debug 6162306a36Sopenharmony_ci mrs x1, id_aa64dfr0_el1 6262306a36Sopenharmony_ci sbfx x0, x1, #ID_AA64DFR0_EL1_PMUVer_SHIFT, #4 6362306a36Sopenharmony_ci cmp x0, #1 6462306a36Sopenharmony_ci b.lt .Lskip_pmu_\@ // Skip if no PMU present 6562306a36Sopenharmony_ci mrs x0, pmcr_el0 // Disable debug access traps 6662306a36Sopenharmony_ci ubfx x0, x0, #11, #5 // to EL2 and allow access to 6762306a36Sopenharmony_ci.Lskip_pmu_\@: 6862306a36Sopenharmony_ci csel x2, xzr, x0, lt // all PMU counters from EL1 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci /* Statistical profiling */ 7162306a36Sopenharmony_ci ubfx x0, x1, #ID_AA64DFR0_EL1_PMSVer_SHIFT, #4 7262306a36Sopenharmony_ci cbz x0, .Lskip_spe_\@ // Skip if SPE not present 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci mrs_s x0, SYS_PMBIDR_EL1 // If SPE available at EL2, 7562306a36Sopenharmony_ci and x0, x0, #(1 << PMBIDR_EL1_P_SHIFT) 7662306a36Sopenharmony_ci cbnz x0, .Lskip_spe_el2_\@ // then permit sampling of physical 7762306a36Sopenharmony_ci mov x0, #(1 << PMSCR_EL2_PCT_SHIFT | \ 7862306a36Sopenharmony_ci 1 << PMSCR_EL2_PA_SHIFT) 7962306a36Sopenharmony_ci msr_s SYS_PMSCR_EL2, x0 // addresses and physical counter 8062306a36Sopenharmony_ci.Lskip_spe_el2_\@: 8162306a36Sopenharmony_ci mov x0, #(MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT) 8262306a36Sopenharmony_ci orr x2, x2, x0 // If we don't have VHE, then 8362306a36Sopenharmony_ci // use EL1&0 translation. 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci.Lskip_spe_\@: 8662306a36Sopenharmony_ci /* Trace buffer */ 8762306a36Sopenharmony_ci ubfx x0, x1, #ID_AA64DFR0_EL1_TraceBuffer_SHIFT, #4 8862306a36Sopenharmony_ci cbz x0, .Lskip_trace_\@ // Skip if TraceBuffer is not present 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci mrs_s x0, SYS_TRBIDR_EL1 9162306a36Sopenharmony_ci and x0, x0, TRBIDR_EL1_P 9262306a36Sopenharmony_ci cbnz x0, .Lskip_trace_\@ // If TRBE is available at EL2 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci mov x0, #(MDCR_EL2_E2TB_MASK << MDCR_EL2_E2TB_SHIFT) 9562306a36Sopenharmony_ci orr x2, x2, x0 // allow the EL1&0 translation 9662306a36Sopenharmony_ci // to own it. 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci.Lskip_trace_\@: 9962306a36Sopenharmony_ci msr mdcr_el2, x2 // Configure debug traps 10062306a36Sopenharmony_ci.endm 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci/* LORegions */ 10362306a36Sopenharmony_ci.macro __init_el2_lor 10462306a36Sopenharmony_ci mrs x1, id_aa64mmfr1_el1 10562306a36Sopenharmony_ci ubfx x0, x1, #ID_AA64MMFR1_EL1_LO_SHIFT, 4 10662306a36Sopenharmony_ci cbz x0, .Lskip_lor_\@ 10762306a36Sopenharmony_ci msr_s SYS_LORC_EL1, xzr 10862306a36Sopenharmony_ci.Lskip_lor_\@: 10962306a36Sopenharmony_ci.endm 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci/* Stage-2 translation */ 11262306a36Sopenharmony_ci.macro __init_el2_stage2 11362306a36Sopenharmony_ci msr vttbr_el2, xzr 11462306a36Sopenharmony_ci.endm 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci/* GICv3 system register access */ 11762306a36Sopenharmony_ci.macro __init_el2_gicv3 11862306a36Sopenharmony_ci mrs x0, id_aa64pfr0_el1 11962306a36Sopenharmony_ci ubfx x0, x0, #ID_AA64PFR0_EL1_GIC_SHIFT, #4 12062306a36Sopenharmony_ci cbz x0, .Lskip_gicv3_\@ 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci mrs_s x0, SYS_ICC_SRE_EL2 12362306a36Sopenharmony_ci orr x0, x0, #ICC_SRE_EL2_SRE // Set ICC_SRE_EL2.SRE==1 12462306a36Sopenharmony_ci orr x0, x0, #ICC_SRE_EL2_ENABLE // Set ICC_SRE_EL2.Enable==1 12562306a36Sopenharmony_ci msr_s SYS_ICC_SRE_EL2, x0 12662306a36Sopenharmony_ci isb // Make sure SRE is now set 12762306a36Sopenharmony_ci mrs_s x0, SYS_ICC_SRE_EL2 // Read SRE back, 12862306a36Sopenharmony_ci tbz x0, #0, .Lskip_gicv3_\@ // and check that it sticks 12962306a36Sopenharmony_ci msr_s SYS_ICH_HCR_EL2, xzr // Reset ICH_HCR_EL2 to defaults 13062306a36Sopenharmony_ci.Lskip_gicv3_\@: 13162306a36Sopenharmony_ci.endm 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci.macro __init_el2_hstr 13462306a36Sopenharmony_ci msr hstr_el2, xzr // Disable CP15 traps to EL2 13562306a36Sopenharmony_ci.endm 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci/* Virtual CPU ID registers */ 13862306a36Sopenharmony_ci.macro __init_el2_nvhe_idregs 13962306a36Sopenharmony_ci mrs x0, midr_el1 14062306a36Sopenharmony_ci mrs x1, mpidr_el1 14162306a36Sopenharmony_ci msr vpidr_el2, x0 14262306a36Sopenharmony_ci msr vmpidr_el2, x1 14362306a36Sopenharmony_ci.endm 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci/* Coprocessor traps */ 14662306a36Sopenharmony_ci.macro __init_el2_cptr 14762306a36Sopenharmony_ci __check_hvhe .LnVHE_\@, x1 14862306a36Sopenharmony_ci mov x0, #(CPACR_EL1_FPEN_EL1EN | CPACR_EL1_FPEN_EL0EN) 14962306a36Sopenharmony_ci msr cpacr_el1, x0 15062306a36Sopenharmony_ci b .Lskip_set_cptr_\@ 15162306a36Sopenharmony_ci.LnVHE_\@: 15262306a36Sopenharmony_ci mov x0, #0x33ff 15362306a36Sopenharmony_ci msr cptr_el2, x0 // Disable copro. traps to EL2 15462306a36Sopenharmony_ci.Lskip_set_cptr_\@: 15562306a36Sopenharmony_ci.endm 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci/* Disable any fine grained traps */ 15862306a36Sopenharmony_ci.macro __init_el2_fgt 15962306a36Sopenharmony_ci mrs x1, id_aa64mmfr0_el1 16062306a36Sopenharmony_ci ubfx x1, x1, #ID_AA64MMFR0_EL1_FGT_SHIFT, #4 16162306a36Sopenharmony_ci cbz x1, .Lskip_fgt_\@ 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci mov x0, xzr 16462306a36Sopenharmony_ci mrs x1, id_aa64dfr0_el1 16562306a36Sopenharmony_ci ubfx x1, x1, #ID_AA64DFR0_EL1_PMSVer_SHIFT, #4 16662306a36Sopenharmony_ci cmp x1, #3 16762306a36Sopenharmony_ci b.lt .Lset_debug_fgt_\@ 16862306a36Sopenharmony_ci /* Disable PMSNEVFR_EL1 read and write traps */ 16962306a36Sopenharmony_ci orr x0, x0, #(1 << 62) 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci.Lset_debug_fgt_\@: 17262306a36Sopenharmony_ci msr_s SYS_HDFGRTR_EL2, x0 17362306a36Sopenharmony_ci msr_s SYS_HDFGWTR_EL2, x0 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci mov x0, xzr 17662306a36Sopenharmony_ci mrs x1, id_aa64pfr1_el1 17762306a36Sopenharmony_ci ubfx x1, x1, #ID_AA64PFR1_EL1_SME_SHIFT, #4 17862306a36Sopenharmony_ci cbz x1, .Lset_pie_fgt_\@ 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci /* Disable nVHE traps of TPIDR2 and SMPRI */ 18162306a36Sopenharmony_ci orr x0, x0, #HFGxTR_EL2_nSMPRI_EL1_MASK 18262306a36Sopenharmony_ci orr x0, x0, #HFGxTR_EL2_nTPIDR2_EL0_MASK 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci.Lset_pie_fgt_\@: 18562306a36Sopenharmony_ci mrs_s x1, SYS_ID_AA64MMFR3_EL1 18662306a36Sopenharmony_ci ubfx x1, x1, #ID_AA64MMFR3_EL1_S1PIE_SHIFT, #4 18762306a36Sopenharmony_ci cbz x1, .Lset_fgt_\@ 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci /* Disable trapping of PIR_EL1 / PIRE0_EL1 */ 19062306a36Sopenharmony_ci orr x0, x0, #HFGxTR_EL2_nPIR_EL1 19162306a36Sopenharmony_ci orr x0, x0, #HFGxTR_EL2_nPIRE0_EL1 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci.Lset_fgt_\@: 19462306a36Sopenharmony_ci msr_s SYS_HFGRTR_EL2, x0 19562306a36Sopenharmony_ci msr_s SYS_HFGWTR_EL2, x0 19662306a36Sopenharmony_ci msr_s SYS_HFGITR_EL2, xzr 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci mrs x1, id_aa64pfr0_el1 // AMU traps UNDEF without AMU 19962306a36Sopenharmony_ci ubfx x1, x1, #ID_AA64PFR0_EL1_AMU_SHIFT, #4 20062306a36Sopenharmony_ci cbz x1, .Lskip_fgt_\@ 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci msr_s SYS_HAFGRTR_EL2, xzr 20362306a36Sopenharmony_ci.Lskip_fgt_\@: 20462306a36Sopenharmony_ci.endm 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci.macro __init_el2_nvhe_prepare_eret 20762306a36Sopenharmony_ci mov x0, #INIT_PSTATE_EL1 20862306a36Sopenharmony_ci msr spsr_el2, x0 20962306a36Sopenharmony_ci.endm 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci/** 21262306a36Sopenharmony_ci * Initialize EL2 registers to sane values. This should be called early on all 21362306a36Sopenharmony_ci * cores that were booted in EL2. Note that everything gets initialised as 21462306a36Sopenharmony_ci * if VHE was not available. The kernel context will be upgraded to VHE 21562306a36Sopenharmony_ci * if possible later on in the boot process 21662306a36Sopenharmony_ci * 21762306a36Sopenharmony_ci * Regs: x0, x1 and x2 are clobbered. 21862306a36Sopenharmony_ci */ 21962306a36Sopenharmony_ci.macro init_el2_state 22062306a36Sopenharmony_ci __init_el2_sctlr 22162306a36Sopenharmony_ci __init_el2_hcrx 22262306a36Sopenharmony_ci __init_el2_timers 22362306a36Sopenharmony_ci __init_el2_debug 22462306a36Sopenharmony_ci __init_el2_lor 22562306a36Sopenharmony_ci __init_el2_stage2 22662306a36Sopenharmony_ci __init_el2_gicv3 22762306a36Sopenharmony_ci __init_el2_hstr 22862306a36Sopenharmony_ci __init_el2_nvhe_idregs 22962306a36Sopenharmony_ci __init_el2_cptr 23062306a36Sopenharmony_ci __init_el2_fgt 23162306a36Sopenharmony_ci.endm 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci#ifndef __KVM_NVHE_HYPERVISOR__ 23462306a36Sopenharmony_ci// This will clobber tmp1 and tmp2, and expect tmp1 to contain 23562306a36Sopenharmony_ci// the id register value as read from the HW 23662306a36Sopenharmony_ci.macro __check_override idreg, fld, width, pass, fail, tmp1, tmp2 23762306a36Sopenharmony_ci ubfx \tmp1, \tmp1, #\fld, #\width 23862306a36Sopenharmony_ci cbz \tmp1, \fail 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci adr_l \tmp1, \idreg\()_override 24162306a36Sopenharmony_ci ldr \tmp2, [\tmp1, FTR_OVR_VAL_OFFSET] 24262306a36Sopenharmony_ci ldr \tmp1, [\tmp1, FTR_OVR_MASK_OFFSET] 24362306a36Sopenharmony_ci ubfx \tmp2, \tmp2, #\fld, #\width 24462306a36Sopenharmony_ci ubfx \tmp1, \tmp1, #\fld, #\width 24562306a36Sopenharmony_ci cmp \tmp1, xzr 24662306a36Sopenharmony_ci and \tmp2, \tmp2, \tmp1 24762306a36Sopenharmony_ci csinv \tmp2, \tmp2, xzr, ne 24862306a36Sopenharmony_ci cbnz \tmp2, \pass 24962306a36Sopenharmony_ci b \fail 25062306a36Sopenharmony_ci.endm 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci// This will clobber tmp1 and tmp2 25362306a36Sopenharmony_ci.macro check_override idreg, fld, pass, fail, tmp1, tmp2 25462306a36Sopenharmony_ci mrs \tmp1, \idreg\()_el1 25562306a36Sopenharmony_ci __check_override \idreg \fld 4 \pass \fail \tmp1 \tmp2 25662306a36Sopenharmony_ci.endm 25762306a36Sopenharmony_ci#else 25862306a36Sopenharmony_ci// This will clobber tmp 25962306a36Sopenharmony_ci.macro __check_override idreg, fld, width, pass, fail, tmp, ignore 26062306a36Sopenharmony_ci ldr_l \tmp, \idreg\()_el1_sys_val 26162306a36Sopenharmony_ci ubfx \tmp, \tmp, #\fld, #\width 26262306a36Sopenharmony_ci cbnz \tmp, \pass 26362306a36Sopenharmony_ci b \fail 26462306a36Sopenharmony_ci.endm 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci.macro check_override idreg, fld, pass, fail, tmp, ignore 26762306a36Sopenharmony_ci __check_override \idreg \fld 4 \pass \fail \tmp \ignore 26862306a36Sopenharmony_ci.endm 26962306a36Sopenharmony_ci#endif 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci.macro finalise_el2_state 27262306a36Sopenharmony_ci check_override id_aa64pfr0, ID_AA64PFR0_EL1_SVE_SHIFT, .Linit_sve_\@, .Lskip_sve_\@, x1, x2 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci.Linit_sve_\@: /* SVE register access */ 27562306a36Sopenharmony_ci __check_hvhe .Lcptr_nvhe_\@, x1 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci // (h)VHE case 27862306a36Sopenharmony_ci mrs x0, cpacr_el1 // Disable SVE traps 27962306a36Sopenharmony_ci orr x0, x0, #(CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN) 28062306a36Sopenharmony_ci msr cpacr_el1, x0 28162306a36Sopenharmony_ci b .Lskip_set_cptr_\@ 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci.Lcptr_nvhe_\@: // nVHE case 28462306a36Sopenharmony_ci mrs x0, cptr_el2 // Disable SVE traps 28562306a36Sopenharmony_ci bic x0, x0, #CPTR_EL2_TZ 28662306a36Sopenharmony_ci msr cptr_el2, x0 28762306a36Sopenharmony_ci.Lskip_set_cptr_\@: 28862306a36Sopenharmony_ci isb 28962306a36Sopenharmony_ci mov x1, #ZCR_ELx_LEN_MASK // SVE: Enable full vector 29062306a36Sopenharmony_ci msr_s SYS_ZCR_EL2, x1 // length for EL1. 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci.Lskip_sve_\@: 29362306a36Sopenharmony_ci check_override id_aa64pfr1, ID_AA64PFR1_EL1_SME_SHIFT, .Linit_sme_\@, .Lskip_sme_\@, x1, x2 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci.Linit_sme_\@: /* SME register access and priority mapping */ 29662306a36Sopenharmony_ci __check_hvhe .Lcptr_nvhe_sme_\@, x1 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci // (h)VHE case 29962306a36Sopenharmony_ci mrs x0, cpacr_el1 // Disable SME traps 30062306a36Sopenharmony_ci orr x0, x0, #(CPACR_EL1_SMEN_EL0EN | CPACR_EL1_SMEN_EL1EN) 30162306a36Sopenharmony_ci msr cpacr_el1, x0 30262306a36Sopenharmony_ci b .Lskip_set_cptr_sme_\@ 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci.Lcptr_nvhe_sme_\@: // nVHE case 30562306a36Sopenharmony_ci mrs x0, cptr_el2 // Disable SME traps 30662306a36Sopenharmony_ci bic x0, x0, #CPTR_EL2_TSM 30762306a36Sopenharmony_ci msr cptr_el2, x0 30862306a36Sopenharmony_ci.Lskip_set_cptr_sme_\@: 30962306a36Sopenharmony_ci isb 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci mrs x1, sctlr_el2 31262306a36Sopenharmony_ci orr x1, x1, #SCTLR_ELx_ENTP2 // Disable TPIDR2 traps 31362306a36Sopenharmony_ci msr sctlr_el2, x1 31462306a36Sopenharmony_ci isb 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci mov x0, #0 // SMCR controls 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci // Full FP in SM? 31962306a36Sopenharmony_ci mrs_s x1, SYS_ID_AA64SMFR0_EL1 32062306a36Sopenharmony_ci __check_override id_aa64smfr0, ID_AA64SMFR0_EL1_FA64_SHIFT, 1, .Linit_sme_fa64_\@, .Lskip_sme_fa64_\@, x1, x2 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci.Linit_sme_fa64_\@: 32362306a36Sopenharmony_ci orr x0, x0, SMCR_ELx_FA64_MASK 32462306a36Sopenharmony_ci.Lskip_sme_fa64_\@: 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci // ZT0 available? 32762306a36Sopenharmony_ci mrs_s x1, SYS_ID_AA64SMFR0_EL1 32862306a36Sopenharmony_ci __check_override id_aa64smfr0, ID_AA64SMFR0_EL1_SMEver_SHIFT, 4, .Linit_sme_zt0_\@, .Lskip_sme_zt0_\@, x1, x2 32962306a36Sopenharmony_ci.Linit_sme_zt0_\@: 33062306a36Sopenharmony_ci orr x0, x0, SMCR_ELx_EZT0_MASK 33162306a36Sopenharmony_ci.Lskip_sme_zt0_\@: 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci orr x0, x0, #SMCR_ELx_LEN_MASK // Enable full SME vector 33462306a36Sopenharmony_ci msr_s SYS_SMCR_EL2, x0 // length for EL1. 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci mrs_s x1, SYS_SMIDR_EL1 // Priority mapping supported? 33762306a36Sopenharmony_ci ubfx x1, x1, #SMIDR_EL1_SMPS_SHIFT, #1 33862306a36Sopenharmony_ci cbz x1, .Lskip_sme_\@ 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci msr_s SYS_SMPRIMAP_EL2, xzr // Make all priorities equal 34162306a36Sopenharmony_ci.Lskip_sme_\@: 34262306a36Sopenharmony_ci.endm 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci#endif /* __ARM_KVM_INIT_H__ */ 345