11a853370SDavid Cunado /* 2*0c5e7d1cSMax Shvetsov * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. 31a853370SDavid Cunado * 41a853370SDavid Cunado * SPDX-License-Identifier: BSD-3-Clause 51a853370SDavid Cunado */ 61a853370SDavid Cunado 709d40e0eSAntonio Nino Diaz #include <stdbool.h> 809d40e0eSAntonio Nino Diaz 91a853370SDavid Cunado #include <arch.h> 101a853370SDavid Cunado #include <arch_helpers.h> 1109d40e0eSAntonio Nino Diaz #include <lib/el3_runtime/pubsub.h> 1209d40e0eSAntonio Nino Diaz #include <lib/extensions/sve.h> 131a853370SDavid Cunado 14*0c5e7d1cSMax Shvetsov /* 15*0c5e7d1cSMax Shvetsov * Converts SVE vector size restriction in bytes to LEN according to ZCR_EL3 documentation. 16*0c5e7d1cSMax Shvetsov * VECTOR_SIZE = (LEN+1) * 128 17*0c5e7d1cSMax Shvetsov */ 18*0c5e7d1cSMax Shvetsov #define CONVERT_SVE_LENGTH(x) (((x / 128) - 1)) 19*0c5e7d1cSMax Shvetsov 20*0c5e7d1cSMax Shvetsov static bool sve_supported(void) 211a853370SDavid Cunado { 221a853370SDavid Cunado uint64_t features; 231a853370SDavid Cunado 241a853370SDavid Cunado features = read_id_aa64pfr0_el1() >> ID_AA64PFR0_SVE_SHIFT; 2540daecc1SAntonio Nino Diaz return (features & ID_AA64PFR0_SVE_MASK) == 1U; 262ff8fbf3SDimitris Papastamos } 272ff8fbf3SDimitris Papastamos 28*0c5e7d1cSMax Shvetsov void sve_enable(cpu_context_t *context) 292ff8fbf3SDimitris Papastamos { 30*0c5e7d1cSMax Shvetsov if (!sve_supported()) { 312ff8fbf3SDimitris Papastamos return; 321a853370SDavid Cunado } 331a853370SDavid Cunado 34*0c5e7d1cSMax Shvetsov u_register_t cptr_el3 = read_cptr_el3(); 35*0c5e7d1cSMax Shvetsov 36*0c5e7d1cSMax Shvetsov /* Enable access to SVE functionality for all ELs. */ 37*0c5e7d1cSMax Shvetsov cptr_el3 = (cptr_el3 | CPTR_EZ_BIT) & ~(TFP_BIT); 38*0c5e7d1cSMax Shvetsov write_ctx_reg(get_el3state_ctx(context), CTX_CPTR_EL3, cptr_el3); 39*0c5e7d1cSMax Shvetsov 40*0c5e7d1cSMax Shvetsov /* Restrict maximum SVE vector length (SVE_VECTOR_LENGTH+1) * 128. */ 41*0c5e7d1cSMax Shvetsov write_ctx_reg(get_el3state_ctx(context), CTX_ZCR_EL3, 42*0c5e7d1cSMax Shvetsov (ZCR_EL3_LEN_MASK & CONVERT_SVE_LENGTH(512))); 43*0c5e7d1cSMax Shvetsov } 44