11a853370SDavid Cunado /* 20c5e7d1cSMax 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 140c5e7d1cSMax Shvetsov /* 150c5e7d1cSMax Shvetsov * Converts SVE vector size restriction in bytes to LEN according to ZCR_EL3 documentation. 160c5e7d1cSMax Shvetsov * VECTOR_SIZE = (LEN+1) * 128 170c5e7d1cSMax Shvetsov */ 180c5e7d1cSMax Shvetsov #define CONVERT_SVE_LENGTH(x) (((x / 128) - 1)) 190c5e7d1cSMax Shvetsov 200c5e7d1cSMax 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 280c5e7d1cSMax Shvetsov void sve_enable(cpu_context_t *context) 292ff8fbf3SDimitris Papastamos { 30*68ac5ed0SArunachalam Ganapathy u_register_t cptr_el3; 31*68ac5ed0SArunachalam Ganapathy 320c5e7d1cSMax Shvetsov if (!sve_supported()) { 332ff8fbf3SDimitris Papastamos return; 341a853370SDavid Cunado } 351a853370SDavid Cunado 36*68ac5ed0SArunachalam Ganapathy cptr_el3 = read_ctx_reg(get_el3state_ctx(context), CTX_CPTR_EL3); 370c5e7d1cSMax Shvetsov 380c5e7d1cSMax Shvetsov /* Enable access to SVE functionality for all ELs. */ 390c5e7d1cSMax Shvetsov cptr_el3 = (cptr_el3 | CPTR_EZ_BIT) & ~(TFP_BIT); 400c5e7d1cSMax Shvetsov write_ctx_reg(get_el3state_ctx(context), CTX_CPTR_EL3, cptr_el3); 410c5e7d1cSMax Shvetsov 420c5e7d1cSMax Shvetsov /* Restrict maximum SVE vector length (SVE_VECTOR_LENGTH+1) * 128. */ 430c5e7d1cSMax Shvetsov write_ctx_reg(get_el3state_ctx(context), CTX_ZCR_EL3, 440c5e7d1cSMax Shvetsov (ZCR_EL3_LEN_MASK & CONVERT_SVE_LENGTH(512))); 450c5e7d1cSMax Shvetsov } 46