1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * FP/SIMD state saving and restoring 4 * 5 * Copyright (C) 2012 ARM Ltd. 6 * Author: Catalin Marinas <catalin.marinas@arm.com> 7 */ 8 9#include <linux/linkage.h> 10 11#include <asm/assembler.h> 12#include <asm/fpsimdmacros.h> 13 14/* 15 * Save the FP registers. 16 * 17 * x0 - pointer to struct fpsimd_state 18 */ 19SYM_FUNC_START(fpsimd_save_state) 20 fpsimd_save x0, 8 21 ret 22SYM_FUNC_END(fpsimd_save_state) 23 24/* 25 * Load the FP registers. 26 * 27 * x0 - pointer to struct fpsimd_state 28 */ 29SYM_FUNC_START(fpsimd_load_state) 30 fpsimd_restore x0, 8 31 ret 32SYM_FUNC_END(fpsimd_load_state) 33 34#ifdef CONFIG_ARM64_SVE 35 36/* 37 * Save the SVE state 38 * 39 * x0 - pointer to buffer for state 40 * x1 - pointer to storage for FPSR 41 */ 42SYM_FUNC_START(sve_save_state) 43 sve_save 0, x1, 2 44 ret 45SYM_FUNC_END(sve_save_state) 46 47/* 48 * Load the SVE state 49 * 50 * x0 - pointer to buffer for state 51 * x1 - pointer to storage for FPSR 52 * x2 - VQ-1 53 */ 54SYM_FUNC_START(sve_load_state) 55 sve_load 0, x1, x2, 3, x4 56 ret 57SYM_FUNC_END(sve_load_state) 58 59SYM_FUNC_START(sve_get_vl) 60 _sve_rdvl 0, 1 61 ret 62SYM_FUNC_END(sve_get_vl) 63 64SYM_FUNC_START(sve_set_vq) 65 sve_load_vq x0, x1, x2 66 ret 67SYM_FUNC_END(sve_set_vq) 68 69/* 70 * Load SVE state from FPSIMD state. 71 * 72 * x0 = pointer to struct fpsimd_state 73 * x1 = VQ - 1 74 * 75 * Each SVE vector will be loaded with the first 128-bits taken from FPSIMD 76 * and the rest zeroed. All the other SVE registers will be zeroed. 77 */ 78SYM_FUNC_START(sve_load_from_fpsimd_state) 79 sve_load_vq x1, x2, x3 80 fpsimd_restore x0, 8 81 sve_flush_p_ffr 82 ret 83SYM_FUNC_END(sve_load_from_fpsimd_state) 84 85/* 86 * Zero all SVE registers but the first 128-bits of each vector 87 * 88 * VQ must already be configured by caller, any further updates of VQ 89 * will need to ensure that the register state remains valid. 90 * 91 * x0 = VQ - 1 92 */ 93SYM_FUNC_START(sve_flush_live) 94 cbz x0, 1f // A VQ-1 of 0 is 128 bits so no extra Z state 95 sve_flush_z 961: sve_flush_p_ffr 97 ret 98SYM_FUNC_END(sve_flush_live) 99 100#endif /* CONFIG_ARM64_SVE */ 101