/* SPDX-License-Identifier: GPL-2.0 */ /* * Author: Qi Hu <huqi@loongson.cn> * Huacai Chen <chenhuacai@loongson.cn> * * Copyright (C) 2020-2023 Loongson Technology Corporation Limited */ #include <asm/asm.h> #include <asm/asmmacro.h> #include <asm/asm-extable.h> #include <asm/asm-offsets.h> #include <asm/errno.h> #include <asm/regdef.h> #define SCR_REG_WIDTH 8 .macro EX insn, reg, src, offs .ex\@: \insn \reg, \src, \offs _asm_extable .ex\@, .L_lbt_fault .endm /* * Save a thread's lbt context. */ SYM_FUNC_START(_save_lbt) movscr2gr t1, $scr0 # save scr stptr.d t1, a0, THREAD_SCR0 movscr2gr t1, $scr1 stptr.d t1, a0, THREAD_SCR1 movscr2gr t1, $scr2 stptr.d t1, a0, THREAD_SCR2 movscr2gr t1, $scr3 stptr.d t1, a0, THREAD_SCR3 x86mfflag t1, 0x3f # save eflags stptr.d t1, a0, THREAD_EFLAGS jr ra SYM_FUNC_END(_save_lbt) EXPORT_SYMBOL(_save_lbt) /* * Restore a thread's lbt context. */ SYM_FUNC_START(_restore_lbt) ldptr.d t1, a0, THREAD_SCR0 # restore scr movgr2scr $scr0, t1 ldptr.d t1, a0, THREAD_SCR1 movgr2scr $scr1, t1 ldptr.d t1, a0, THREAD_SCR2 movgr2scr $scr2, t1 ldptr.d t1, a0, THREAD_SCR3 movgr2scr $scr3, t1 ldptr.d t1, a0, THREAD_EFLAGS # restore eflags x86mtflag t1, 0x3f jr ra SYM_FUNC_END(_restore_lbt) EXPORT_SYMBOL(_restore_lbt) /* * Load scr/eflag with zero. */ SYM_FUNC_START(_init_lbt) movgr2scr $scr0, zero movgr2scr $scr1, zero movgr2scr $scr2, zero movgr2scr $scr3, zero x86mtflag zero, 0x3f jr ra SYM_FUNC_END(_init_lbt) /* * a0: scr * a1: eflag */ SYM_FUNC_START(_save_lbt_context) movscr2gr t1, $scr0 # save scr EX st.d t1, a0, (0 * SCR_REG_WIDTH) movscr2gr t1, $scr1 EX st.d t1, a0, (1 * SCR_REG_WIDTH) movscr2gr t1, $scr2 EX st.d t1, a0, (2 * SCR_REG_WIDTH) movscr2gr t1, $scr3 EX st.d t1, a0, (3 * SCR_REG_WIDTH) x86mfflag t1, 0x3f # save eflags EX st.w t1, a1, 0 li.w a0, 0 # success jr ra SYM_FUNC_END(_save_lbt_context) /* * a0: scr * a1: eflag */ SYM_FUNC_START(_restore_lbt_context) EX ld.d t1, a0, (0 * SCR_REG_WIDTH) # restore scr movgr2scr $scr0, t1 EX ld.d t1, a0, (1 * SCR_REG_WIDTH) movgr2scr $scr1, t1 EX ld.d t1, a0, (2 * SCR_REG_WIDTH) movgr2scr $scr2, t1 EX ld.d t1, a0, (3 * SCR_REG_WIDTH) movgr2scr $scr3, t1 EX ld.w t1, a1, 0 # restore eflags x86mtflag t1, 0x3f li.w a0, 0 # success jr ra SYM_FUNC_END(_restore_lbt_context) /* * a0: ftop */ SYM_FUNC_START(_save_ftop_context) x86mftop t1 st.w t1, a0, 0 li.w a0, 0 # success jr ra SYM_FUNC_END(_save_ftop_context) /* * a0: ftop */ SYM_FUNC_START(_restore_ftop_context) ld.w t1, a0, 0 andi t1, t1, 0x7 la.pcrel a0, 1f alsl.d a0, t1, a0, 3 jr a0 1: x86mttop 0 b 2f x86mttop 1 b 2f x86mttop 2 b 2f x86mttop 3 b 2f x86mttop 4 b 2f x86mttop 5 b 2f x86mttop 6 b 2f x86mttop 7 2: li.w a0, 0 # success jr ra SYM_FUNC_END(_restore_ftop_context) .L_lbt_fault: li.w a0, -EFAULT # failure jr ra