1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Author: Qi Hu <huqi@loongson.cn> 4 * Huacai Chen <chenhuacai@loongson.cn> 5 * 6 * Copyright (C) 2020-2023 Loongson Technology Corporation Limited 7 */ 8#include <asm/asm.h> 9#include <asm/asmmacro.h> 10#include <asm/asm-extable.h> 11#include <asm/asm-offsets.h> 12#include <asm/errno.h> 13#include <asm/regdef.h> 14#include <asm/unwind_hints.h> 15 16#define SCR_REG_WIDTH 8 17 18 .macro EX insn, reg, src, offs 19.ex\@: \insn \reg, \src, \offs 20 _asm_extable .ex\@, .L_lbt_fault 21 .endm 22 23/* 24 * Save a thread's lbt context. 25 */ 26SYM_FUNC_START(_save_lbt) 27 movscr2gr t1, $scr0 # save scr 28 stptr.d t1, a0, THREAD_SCR0 29 movscr2gr t1, $scr1 30 stptr.d t1, a0, THREAD_SCR1 31 movscr2gr t1, $scr2 32 stptr.d t1, a0, THREAD_SCR2 33 movscr2gr t1, $scr3 34 stptr.d t1, a0, THREAD_SCR3 35 36 x86mfflag t1, 0x3f # save eflags 37 stptr.d t1, a0, THREAD_EFLAGS 38 jr ra 39SYM_FUNC_END(_save_lbt) 40EXPORT_SYMBOL(_save_lbt) 41 42/* 43 * Restore a thread's lbt context. 44 */ 45SYM_FUNC_START(_restore_lbt) 46 ldptr.d t1, a0, THREAD_SCR0 # restore scr 47 movgr2scr $scr0, t1 48 ldptr.d t1, a0, THREAD_SCR1 49 movgr2scr $scr1, t1 50 ldptr.d t1, a0, THREAD_SCR2 51 movgr2scr $scr2, t1 52 ldptr.d t1, a0, THREAD_SCR3 53 movgr2scr $scr3, t1 54 55 ldptr.d t1, a0, THREAD_EFLAGS # restore eflags 56 x86mtflag t1, 0x3f 57 jr ra 58SYM_FUNC_END(_restore_lbt) 59EXPORT_SYMBOL(_restore_lbt) 60 61/* 62 * Load scr/eflag with zero. 63 */ 64SYM_FUNC_START(_init_lbt) 65 movgr2scr $scr0, zero 66 movgr2scr $scr1, zero 67 movgr2scr $scr2, zero 68 movgr2scr $scr3, zero 69 70 x86mtflag zero, 0x3f 71 jr ra 72SYM_FUNC_END(_init_lbt) 73 74/* 75 * a0: scr 76 * a1: eflag 77 */ 78SYM_FUNC_START(_save_lbt_context) 79 movscr2gr t1, $scr0 # save scr 80 EX st.d t1, a0, (0 * SCR_REG_WIDTH) 81 movscr2gr t1, $scr1 82 EX st.d t1, a0, (1 * SCR_REG_WIDTH) 83 movscr2gr t1, $scr2 84 EX st.d t1, a0, (2 * SCR_REG_WIDTH) 85 movscr2gr t1, $scr3 86 EX st.d t1, a0, (3 * SCR_REG_WIDTH) 87 88 x86mfflag t1, 0x3f # save eflags 89 EX st.w t1, a1, 0 90 li.w a0, 0 # success 91 jr ra 92SYM_FUNC_END(_save_lbt_context) 93 94/* 95 * a0: scr 96 * a1: eflag 97 */ 98SYM_FUNC_START(_restore_lbt_context) 99 EX ld.d t1, a0, (0 * SCR_REG_WIDTH) # restore scr 100 movgr2scr $scr0, t1 101 EX ld.d t1, a0, (1 * SCR_REG_WIDTH) 102 movgr2scr $scr1, t1 103 EX ld.d t1, a0, (2 * SCR_REG_WIDTH) 104 movgr2scr $scr2, t1 105 EX ld.d t1, a0, (3 * SCR_REG_WIDTH) 106 movgr2scr $scr3, t1 107 108 EX ld.w t1, a1, 0 # restore eflags 109 x86mtflag t1, 0x3f 110 li.w a0, 0 # success 111 jr ra 112SYM_FUNC_END(_restore_lbt_context) 113 114/* 115 * a0: ftop 116 */ 117SYM_FUNC_START(_save_ftop_context) 118 x86mftop t1 119 st.w t1, a0, 0 120 li.w a0, 0 # success 121 jr ra 122SYM_FUNC_END(_save_ftop_context) 123 124/* 125 * a0: ftop 126 */ 127SYM_FUNC_START(_restore_ftop_context) 128 ld.w t1, a0, 0 129 andi t1, t1, 0x7 130 la.pcrel a0, 1f 131 alsl.d a0, t1, a0, 3 132 jr a0 1331: 134 x86mttop 0 135 b 2f 136 x86mttop 1 137 b 2f 138 x86mttop 2 139 b 2f 140 x86mttop 3 141 b 2f 142 x86mttop 4 143 b 2f 144 x86mttop 5 145 b 2f 146 x86mttop 6 147 b 2f 148 x86mttop 7 1492: 150 li.w a0, 0 # success 151 jr ra 152SYM_FUNC_END(_restore_ftop_context) 153 154.L_lbt_fault: 155 li.w a0, -EFAULT # failure 156 jr ra 157 158STACK_FRAME_NON_STANDARD _restore_ftop_context 159