1/* 2 * Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved. 3 * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this list of 9 * conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 * of conditions and the following disclaimer in the documentation and/or other materials 13 * provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 16 * to endorse or promote products derived from this software without specific prior written 17 * permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include "soc.h" 33#include "soc_common.h" 34 35.global __wrap_HalStartToRun 36.global __wrap_HalTaskContextSwitch 37.extern __irq_stack_top 38.section .interrupt.text 39 40.macro PUSH_ALL_REG 41 addi sp, sp, -(32 * REGBYTES) 42 SREG t6, 2 * REGBYTES(sp) 43 SREG t5, 3 * REGBYTES(sp) 44 SREG t4, 4 * REGBYTES(sp) 45 SREG t3, 5 * REGBYTES(sp) 46 SREG t2, 6 * REGBYTES(sp) 47 SREG t1, 7 * REGBYTES(sp) 48 SREG t0, 8 * REGBYTES(sp) 49 SREG s11, 9 * REGBYTES(sp) 50 SREG s10, 10 * REGBYTES(sp) 51 SREG s9, 11 * REGBYTES(sp) 52 SREG s8, 12 * REGBYTES(sp) 53 SREG s7, 13 * REGBYTES(sp) 54 SREG s6, 14 * REGBYTES(sp) 55 SREG s5, 15 * REGBYTES(sp) 56 SREG a7, 18 * REGBYTES(sp) 57 SREG a6, 19 * REGBYTES(sp) 58 SREG a5, 20 * REGBYTES(sp) 59 SREG a4, 21 * REGBYTES(sp) 60 SREG a3, 22 * REGBYTES(sp) 61 SREG a2, 23 * REGBYTES(sp) 62 SREG a1, 24 * REGBYTES(sp) 63 SREG a0, 25 * REGBYTES(sp) 64 SREG s4, 26 * REGBYTES(sp) 65 SREG s3, 27 * REGBYTES(sp) 66 SREG s2, 28 * REGBYTES(sp) 67 SREG s1, 29 * REGBYTES(sp) 68 SREG s0, 30 * REGBYTES(sp) 69 SREG ra, 31 * REGBYTES(sp) 70.endm 71 72.macro POP_ALL_REG 73 LREG t6, 2 * REGBYTES(sp) 74 LREG t5, 3 * REGBYTES(sp) 75 LREG t4, 4 * REGBYTES(sp) 76 LREG t3, 5 * REGBYTES(sp) 77 LREG t2, 6 * REGBYTES(sp) 78 LREG t1, 7 * REGBYTES(sp) 79 LREG t0, 8 * REGBYTES(sp) 80 LREG s11, 9 * REGBYTES(sp) 81 LREG s10, 10 * REGBYTES(sp) 82 LREG s9, 11 * REGBYTES(sp) 83 LREG s8, 12 * REGBYTES(sp) 84 LREG s7, 13 * REGBYTES(sp) 85 LREG s6, 14 * REGBYTES(sp) 86 LREG s5, 15 * REGBYTES(sp) 87 LREG a7, 18 * REGBYTES(sp) 88 LREG a6, 19 * REGBYTES(sp) 89 LREG a5, 20 * REGBYTES(sp) 90 LREG a4, 21 * REGBYTES(sp) 91 LREG a3, 22 * REGBYTES(sp) 92 LREG a2, 23 * REGBYTES(sp) 93 LREG a1, 24 * REGBYTES(sp) 94 LREG a0, 25 * REGBYTES(sp) 95 LREG s4, 26 * REGBYTES(sp) 96 LREG s3, 27 * REGBYTES(sp) 97 LREG s2, 28 * REGBYTES(sp) 98 LREG s1, 29 * REGBYTES(sp) 99 LREG s0, 30 * REGBYTES(sp) 100 LREG ra, 31 * REGBYTES(sp) 101 addi sp, sp, 32 * REGBYTES 102.endm 103.macro PUSH_ALL_F_REG 104 addi sp, sp, -(FPU_CONTEXT_SIZE * REGBYTES) /* Make room for the FPU registers. */ 105 106 #ifdef __riscv_dsp 107 csrr t0, ucode 108 SREG t0, 0 * REGBYTES( sp ) 109 #endif 110 111 #ifdef __riscv_flen 112 frcsr t0 113 SREG t0, 1 * REGBYTES( sp ) 114 F_SREG f0, ( 2 * REGBYTES + 0 * FREGBYTES )( sp ) 115 F_SREG f1, ( 2 * REGBYTES + 1 * FREGBYTES )( sp ) 116 F_SREG f2, ( 2 * REGBYTES + 2 * FREGBYTES )( sp ) 117 F_SREG f3, ( 2 * REGBYTES + 3 * FREGBYTES )( sp ) 118 F_SREG f4, ( 2 * REGBYTES + 4 * FREGBYTES )( sp ) 119 F_SREG f5, ( 2 * REGBYTES + 5 * FREGBYTES )( sp ) 120 F_SREG f6, ( 2 * REGBYTES + 6 * FREGBYTES )( sp ) 121 F_SREG f7, ( 2 * REGBYTES + 7 * FREGBYTES )( sp ) 122 F_SREG f8, ( 2 * REGBYTES + 8 * FREGBYTES )( sp ) 123 F_SREG f9, ( 2 * REGBYTES + 9 * FREGBYTES )( sp ) 124 F_SREG f10, ( 2 * REGBYTES + 10 * FREGBYTES )( sp ) 125 F_SREG f11, ( 2 * REGBYTES + 11 * FREGBYTES )( sp ) 126 F_SREG f12, ( 2 * REGBYTES + 12 * FREGBYTES )( sp ) 127 F_SREG f13, ( 2 * REGBYTES + 13 * FREGBYTES )( sp ) 128 F_SREG f14, ( 2 * REGBYTES + 14 * FREGBYTES )( sp ) 129 F_SREG f15, ( 2 * REGBYTES + 15 * FREGBYTES )( sp ) 130 F_SREG f16, ( 2 * REGBYTES + 16 * FREGBYTES )( sp ) 131 F_SREG f17, ( 2 * REGBYTES + 17 * FREGBYTES )( sp ) 132 F_SREG f18, ( 2 * REGBYTES + 18 * FREGBYTES )( sp ) 133 F_SREG f19, ( 2 * REGBYTES + 19 * FREGBYTES )( sp ) 134 F_SREG f20, ( 2 * REGBYTES + 20 * FREGBYTES )( sp ) 135 F_SREG f21, ( 2 * REGBYTES + 21 * FREGBYTES )( sp ) 136 F_SREG f22, ( 2 * REGBYTES + 22 * FREGBYTES )( sp ) 137 F_SREG f23, ( 2 * REGBYTES + 23 * FREGBYTES )( sp ) 138 F_SREG f24, ( 2 * REGBYTES + 24 * FREGBYTES )( sp ) 139 F_SREG f25, ( 2 * REGBYTES + 25 * FREGBYTES )( sp ) 140 F_SREG f26, ( 2 * REGBYTES + 26 * FREGBYTES )( sp ) 141 F_SREG f27, ( 2 * REGBYTES + 27 * FREGBYTES )( sp ) 142 F_SREG f28, ( 2 * REGBYTES + 28 * FREGBYTES )( sp ) 143 F_SREG f29, ( 2 * REGBYTES + 29 * FREGBYTES )( sp ) 144 F_SREG f30, ( 2 * REGBYTES + 30 * FREGBYTES )( sp ) 145 F_SREG f31, ( 2 * REGBYTES + 31 * FREGBYTES )( sp ) 146 #endif 147.endm 148 149.macro POP_ALL_F_REG 150 #ifdef __riscv_dsp 151 LREG t0, 0 * REGBYTES( sp ) 152 csrw ucode, t0 153 #endif 154 155 #ifdef __riscv_flen 156 LREG t0, 1 * REGBYTES( sp ) 157 fscsr t0 158 F_LREG f0, ( 2 * REGBYTES + 0 * FREGBYTES )( sp ) 159 F_LREG f1, ( 2 * REGBYTES + 1 * FREGBYTES )( sp ) 160 F_LREG f2, ( 2 * REGBYTES + 2 * FREGBYTES )( sp ) 161 F_LREG f3, ( 2 * REGBYTES + 3 * FREGBYTES )( sp ) 162 F_LREG f4, ( 2 * REGBYTES + 4 * FREGBYTES )( sp ) 163 F_LREG f5, ( 2 * REGBYTES + 5 * FREGBYTES )( sp ) 164 F_LREG f6, ( 2 * REGBYTES + 6 * FREGBYTES )( sp ) 165 F_LREG f7, ( 2 * REGBYTES + 7 * FREGBYTES )( sp ) 166 F_LREG f8, ( 2 * REGBYTES + 8 * FREGBYTES )( sp ) 167 F_LREG f9, ( 2 * REGBYTES + 9 * FREGBYTES )( sp ) 168 F_LREG f10, ( 2 * REGBYTES + 10 * FREGBYTES )( sp ) 169 F_LREG f11, ( 2 * REGBYTES + 11 * FREGBYTES )( sp ) 170 F_LREG f12, ( 2 * REGBYTES + 12 * FREGBYTES )( sp ) 171 F_LREG f13, ( 2 * REGBYTES + 13 * FREGBYTES )( sp ) 172 F_LREG f14, ( 2 * REGBYTES + 14 * FREGBYTES )( sp ) 173 F_LREG f15, ( 2 * REGBYTES + 15 * FREGBYTES )( sp ) 174 F_LREG f16, ( 2 * REGBYTES + 16 * FREGBYTES )( sp ) 175 F_LREG f17, ( 2 * REGBYTES + 17 * FREGBYTES )( sp ) 176 F_LREG f18, ( 2 * REGBYTES + 18 * FREGBYTES )( sp ) 177 F_LREG f19, ( 2 * REGBYTES + 19 * FREGBYTES )( sp ) 178 F_LREG f20, ( 2 * REGBYTES + 20 * FREGBYTES )( sp ) 179 F_LREG f21, ( 2 * REGBYTES + 21 * FREGBYTES )( sp ) 180 F_LREG f22, ( 2 * REGBYTES + 22 * FREGBYTES )( sp ) 181 F_LREG f23, ( 2 * REGBYTES + 23 * FREGBYTES )( sp ) 182 F_LREG f24, ( 2 * REGBYTES + 24 * FREGBYTES )( sp ) 183 F_LREG f25, ( 2 * REGBYTES + 25 * FREGBYTES )( sp ) 184 F_LREG f26, ( 2 * REGBYTES + 26 * FREGBYTES )( sp ) 185 F_LREG f27, ( 2 * REGBYTES + 27 * FREGBYTES )( sp ) 186 F_LREG f28, ( 2 * REGBYTES + 28 * FREGBYTES )( sp ) 187 F_LREG f29, ( 2 * REGBYTES + 29 * FREGBYTES )( sp ) 188 F_LREG f30, ( 2 * REGBYTES + 30 * FREGBYTES )( sp ) 189 F_LREG f31, ( 2 * REGBYTES + 31 * FREGBYTES )( sp ) 190 #endif 191 192 addi sp, sp, (FPU_CONTEXT_SIZE * REGBYTES) /* Remove space added for FPU registers. */ 193.endm 194 195__wrap_HalTaskContextSwitch: 196 PUSH_ALL_REG 197 198 // clear mpie 199 li a2, RISCV_MSTATUS_MPIE 200 not a2, a2 201 and a0, a0, a2 202 203 // get mie 204 andi a1, a0, RISCV_MSTATUS_MIE 205 206 // must be in machine mode 207 ori a1, a1, 0x180 208 slli a1, a1, 0x4 209 or a0, a0, a1 210 211 // clear mie 212 li a2, RISCV_MSTATUS_MIE 213 not a2, a2 214 and a0, a0, a2 215 216 SREG a0, 16 * REGBYTES(sp) 217 SREG ra, 17 * REGBYTES(sp) 218 219 // save the FPU registers 220 PUSH_ALL_F_REG 221 222 la a1, g_losTask 223 lw a0, 0(a1) 224 sw sp, TASK_CB_KERNEL_SP(a0) 225 226 lw a0, 4(a1) 227 sw a0, 0(a1) 228 229__wrap_HalStartToRun: 230 la a1, g_losTask 231 lw a0, 4(a1) 232 233// retireve stack pointer 234 lw sp, TASK_CB_KERNEL_SP(a0) 235 236// retrieve the FPU registers 237 POP_ALL_F_REG 238 239// enable global interrupts 240 lw t0, 16 * REGBYTES(sp) 241 csrw mstatus, t0 242 243// retrieve the address at which exception happened 244 lw t0, 17 * REGBYTES(sp) 245 csrw mepc, t0 246 247// retrieve the registers 248 POP_ALL_REG 249 250 mret 251 252