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) 93EXPORT_SYMBOL_GPL(_save_lbt_context) 94 95/* 96 * a0: scr 97 * a1: eflag 98 */ 99SYM_FUNC_START(_restore_lbt_context) 100 EX ld.d t1, a0, (0 * SCR_REG_WIDTH) # restore scr 101 movgr2scr $scr0, t1 102 EX ld.d t1, a0, (1 * SCR_REG_WIDTH) 103 movgr2scr $scr1, t1 104 EX ld.d t1, a0, (2 * SCR_REG_WIDTH) 105 movgr2scr $scr2, t1 106 EX ld.d t1, a0, (3 * SCR_REG_WIDTH) 107 movgr2scr $scr3, t1 108 109 EX ld.w t1, a1, 0 # restore eflags 110 x86mtflag t1, 0x3f 111 li.w a0, 0 # success 112 jr ra 113SYM_FUNC_END(_restore_lbt_context) 114EXPORT_SYMBOL_GPL(_restore_lbt_context) 115 116/* 117 * a0: ftop 118 */ 119SYM_FUNC_START(_save_ftop_context) 120 x86mftop t1 121 st.w t1, a0, 0 122 li.w a0, 0 # success 123 jr ra 124SYM_FUNC_END(_save_ftop_context) 125EXPORT_SYMBOL_GPL(_save_ftop_context) 126 127/* 128 * a0: ftop 129 */ 130SYM_FUNC_START(_restore_ftop_context) 131 ld.w t1, a0, 0 132 andi t1, t1, 0x7 133 la.pcrel a0, 1f 134 alsl.d a0, t1, a0, 3 135 jr a0 1361: 137 x86mttop 0 138 b 2f 139 x86mttop 1 140 b 2f 141 x86mttop 2 142 b 2f 143 x86mttop 3 144 b 2f 145 x86mttop 4 146 b 2f 147 x86mttop 5 148 b 2f 149 x86mttop 6 150 b 2f 151 x86mttop 7 1522: 153 li.w a0, 0 # success 154 jr ra 155SYM_FUNC_END(_restore_ftop_context) 156EXPORT_SYMBOL_GPL(_restore_ftop_context) 157 158.L_lbt_fault: 159 li.w a0, -EFAULT # failure 160 jr ra 161 162STACK_FRAME_NON_STANDARD _restore_ftop_context 163