1*10465441SEvalZero/* 2*10465441SEvalZero * Copyright (c) 2006-2018, RT-Thread Development Team 3*10465441SEvalZero * 4*10465441SEvalZero * SPDX-License-Identifier: Apache-2.0 5*10465441SEvalZero * 6*10465441SEvalZero * Change Logs: 7*10465441SEvalZero * Date Author Notes 8*10465441SEvalZero * 2018/10/28 Bernard The unify RISC-V porting implementation 9*10465441SEvalZero * 2018/12/27 Jesven Add SMP support 10*10465441SEvalZero */ 11*10465441SEvalZero 12*10465441SEvalZero#include "cpuport.h" 13*10465441SEvalZero 14*10465441SEvalZero#ifdef RT_USING_SMP 15*10465441SEvalZero#define rt_hw_interrupt_disable rt_hw_local_irq_disable 16*10465441SEvalZero#define rt_hw_interrupt_enable rt_hw_local_irq_enable 17*10465441SEvalZero#endif 18*10465441SEvalZero 19*10465441SEvalZero/* 20*10465441SEvalZero * rt_base_t rt_hw_interrupt_disable(void); 21*10465441SEvalZero */ 22*10465441SEvalZero .globl rt_hw_interrupt_disable 23*10465441SEvalZerort_hw_interrupt_disable: 24*10465441SEvalZero csrrci a0, mstatus, 8 25*10465441SEvalZero ret 26*10465441SEvalZero 27*10465441SEvalZero/* 28*10465441SEvalZero * void rt_hw_interrupt_enable(rt_base_t level); 29*10465441SEvalZero */ 30*10465441SEvalZero .globl rt_hw_interrupt_enable 31*10465441SEvalZerort_hw_interrupt_enable: 32*10465441SEvalZero csrw mstatus, a0 33*10465441SEvalZero ret 34*10465441SEvalZero 35*10465441SEvalZero/* 36*10465441SEvalZero * #ifdef RT_USING_SMP 37*10465441SEvalZero * void rt_hw_context_switch_to(rt_ubase_t to, stuct rt_thread *to_thread); 38*10465441SEvalZero * #else 39*10465441SEvalZero * void rt_hw_context_switch_to(rt_ubase_t to); 40*10465441SEvalZero * #endif 41*10465441SEvalZero * a0 --> to 42*10465441SEvalZero * a1 --> to_thread 43*10465441SEvalZero */ 44*10465441SEvalZero .globl rt_hw_context_switch_to 45*10465441SEvalZerort_hw_context_switch_to: 46*10465441SEvalZero LOAD sp, (a0) 47*10465441SEvalZero 48*10465441SEvalZero#ifdef RT_USING_SMP 49*10465441SEvalZero mv a0, a1 50*10465441SEvalZero jal rt_cpus_lock_status_restore 51*10465441SEvalZero#endif 52*10465441SEvalZero 53*10465441SEvalZero /* load epc from stack */ 54*10465441SEvalZero LOAD a0, 0 * REGBYTES(sp) 55*10465441SEvalZero csrw mepc, a0 56*10465441SEvalZero LOAD x1, 1 * REGBYTES(sp) 57*10465441SEvalZero /* load mstatus from stack */ 58*10465441SEvalZero LOAD a0, 2 * REGBYTES(sp) 59*10465441SEvalZero csrw mstatus, a0 60*10465441SEvalZero LOAD x4, 4 * REGBYTES(sp) 61*10465441SEvalZero LOAD x5, 5 * REGBYTES(sp) 62*10465441SEvalZero LOAD x6, 6 * REGBYTES(sp) 63*10465441SEvalZero LOAD x7, 7 * REGBYTES(sp) 64*10465441SEvalZero LOAD x8, 8 * REGBYTES(sp) 65*10465441SEvalZero LOAD x9, 9 * REGBYTES(sp) 66*10465441SEvalZero LOAD x10, 10 * REGBYTES(sp) 67*10465441SEvalZero LOAD x11, 11 * REGBYTES(sp) 68*10465441SEvalZero LOAD x12, 12 * REGBYTES(sp) 69*10465441SEvalZero LOAD x13, 13 * REGBYTES(sp) 70*10465441SEvalZero LOAD x14, 14 * REGBYTES(sp) 71*10465441SEvalZero LOAD x15, 15 * REGBYTES(sp) 72*10465441SEvalZero LOAD x16, 16 * REGBYTES(sp) 73*10465441SEvalZero LOAD x17, 17 * REGBYTES(sp) 74*10465441SEvalZero LOAD x18, 18 * REGBYTES(sp) 75*10465441SEvalZero LOAD x19, 19 * REGBYTES(sp) 76*10465441SEvalZero LOAD x20, 20 * REGBYTES(sp) 77*10465441SEvalZero LOAD x21, 21 * REGBYTES(sp) 78*10465441SEvalZero LOAD x22, 22 * REGBYTES(sp) 79*10465441SEvalZero LOAD x23, 23 * REGBYTES(sp) 80*10465441SEvalZero LOAD x24, 24 * REGBYTES(sp) 81*10465441SEvalZero LOAD x25, 25 * REGBYTES(sp) 82*10465441SEvalZero LOAD x26, 26 * REGBYTES(sp) 83*10465441SEvalZero LOAD x27, 27 * REGBYTES(sp) 84*10465441SEvalZero LOAD x28, 28 * REGBYTES(sp) 85*10465441SEvalZero LOAD x29, 29 * REGBYTES(sp) 86*10465441SEvalZero LOAD x30, 30 * REGBYTES(sp) 87*10465441SEvalZero LOAD x31, 31 * REGBYTES(sp) 88*10465441SEvalZero 89*10465441SEvalZero addi sp, sp, 32 * REGBYTES 90*10465441SEvalZero mret 91*10465441SEvalZero 92*10465441SEvalZero/* 93*10465441SEvalZero * #ifdef RT_USING_SMP 94*10465441SEvalZero * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread); 95*10465441SEvalZero * #else 96*10465441SEvalZero * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to); 97*10465441SEvalZero * #endif 98*10465441SEvalZero * 99*10465441SEvalZero * a0 --> from 100*10465441SEvalZero * a1 --> to 101*10465441SEvalZero * a2 --> to_thread 102*10465441SEvalZero */ 103*10465441SEvalZero .globl rt_hw_context_switch 104*10465441SEvalZerort_hw_context_switch: 105*10465441SEvalZero 106*10465441SEvalZero /* saved from thread context 107*10465441SEvalZero * x1/ra -> sp(0) 108*10465441SEvalZero * x1/ra -> sp(1) 109*10465441SEvalZero * mstatus.mie -> sp(2) 110*10465441SEvalZero * x(i) -> sp(i-4) 111*10465441SEvalZero */ 112*10465441SEvalZero addi sp, sp, -32 * REGBYTES 113*10465441SEvalZero STORE sp, (a0) 114*10465441SEvalZero 115*10465441SEvalZero STORE x1, 0 * REGBYTES(sp) 116*10465441SEvalZero STORE x1, 1 * REGBYTES(sp) 117*10465441SEvalZero 118*10465441SEvalZero csrr a0, mstatus 119*10465441SEvalZero andi a0, a0, 8 120*10465441SEvalZero beqz a0, save_mpie 121*10465441SEvalZero li a0, 0x80 122*10465441SEvalZerosave_mpie: 123*10465441SEvalZero STORE a0, 2 * REGBYTES(sp) 124*10465441SEvalZero 125*10465441SEvalZero STORE x4, 4 * REGBYTES(sp) 126*10465441SEvalZero STORE x5, 5 * REGBYTES(sp) 127*10465441SEvalZero STORE x6, 6 * REGBYTES(sp) 128*10465441SEvalZero STORE x7, 7 * REGBYTES(sp) 129*10465441SEvalZero STORE x8, 8 * REGBYTES(sp) 130*10465441SEvalZero STORE x9, 9 * REGBYTES(sp) 131*10465441SEvalZero STORE x10, 10 * REGBYTES(sp) 132*10465441SEvalZero STORE x11, 11 * REGBYTES(sp) 133*10465441SEvalZero STORE x12, 12 * REGBYTES(sp) 134*10465441SEvalZero STORE x13, 13 * REGBYTES(sp) 135*10465441SEvalZero STORE x14, 14 * REGBYTES(sp) 136*10465441SEvalZero STORE x15, 15 * REGBYTES(sp) 137*10465441SEvalZero STORE x16, 16 * REGBYTES(sp) 138*10465441SEvalZero STORE x17, 17 * REGBYTES(sp) 139*10465441SEvalZero STORE x18, 18 * REGBYTES(sp) 140*10465441SEvalZero STORE x19, 19 * REGBYTES(sp) 141*10465441SEvalZero STORE x20, 20 * REGBYTES(sp) 142*10465441SEvalZero STORE x21, 21 * REGBYTES(sp) 143*10465441SEvalZero STORE x22, 22 * REGBYTES(sp) 144*10465441SEvalZero STORE x23, 23 * REGBYTES(sp) 145*10465441SEvalZero STORE x24, 24 * REGBYTES(sp) 146*10465441SEvalZero STORE x25, 25 * REGBYTES(sp) 147*10465441SEvalZero STORE x26, 26 * REGBYTES(sp) 148*10465441SEvalZero STORE x27, 27 * REGBYTES(sp) 149*10465441SEvalZero STORE x28, 28 * REGBYTES(sp) 150*10465441SEvalZero STORE x29, 29 * REGBYTES(sp) 151*10465441SEvalZero STORE x30, 30 * REGBYTES(sp) 152*10465441SEvalZero STORE x31, 31 * REGBYTES(sp) 153*10465441SEvalZero 154*10465441SEvalZero /* restore to thread context 155*10465441SEvalZero * sp(0) -> epc; 156*10465441SEvalZero * sp(1) -> ra; 157*10465441SEvalZero * sp(i) -> x(i+2) 158*10465441SEvalZero */ 159*10465441SEvalZero LOAD sp, (a1) 160*10465441SEvalZero 161*10465441SEvalZero#ifdef RT_USING_SMP 162*10465441SEvalZero mv a0, a2 163*10465441SEvalZero jal rt_cpus_lock_status_restore 164*10465441SEvalZero#endif /*RT_USING_SMP*/ 165*10465441SEvalZero 166*10465441SEvalZero /* resw ra to mepc */ 167*10465441SEvalZero LOAD a1, 0 * REGBYTES(sp) 168*10465441SEvalZero csrw mepc, a1 169*10465441SEvalZero LOAD x1, 1 * REGBYTES(sp) 170*10465441SEvalZero 171*10465441SEvalZero /* force to machin mode(MPP=11) */ 172*10465441SEvalZero li a1, 0x00001800; 173*10465441SEvalZero csrs mstatus, a1 174*10465441SEvalZero LOAD a1, 2 * REGBYTES(sp) 175*10465441SEvalZero csrs mstatus, a1 176*10465441SEvalZero 177*10465441SEvalZero LOAD x4, 4 * REGBYTES(sp) 178*10465441SEvalZero LOAD x5, 5 * REGBYTES(sp) 179*10465441SEvalZero LOAD x6, 6 * REGBYTES(sp) 180*10465441SEvalZero LOAD x7, 7 * REGBYTES(sp) 181*10465441SEvalZero LOAD x8, 8 * REGBYTES(sp) 182*10465441SEvalZero LOAD x9, 9 * REGBYTES(sp) 183*10465441SEvalZero LOAD x10, 10 * REGBYTES(sp) 184*10465441SEvalZero LOAD x11, 11 * REGBYTES(sp) 185*10465441SEvalZero LOAD x12, 12 * REGBYTES(sp) 186*10465441SEvalZero LOAD x13, 13 * REGBYTES(sp) 187*10465441SEvalZero LOAD x14, 14 * REGBYTES(sp) 188*10465441SEvalZero LOAD x15, 15 * REGBYTES(sp) 189*10465441SEvalZero LOAD x16, 16 * REGBYTES(sp) 190*10465441SEvalZero LOAD x17, 17 * REGBYTES(sp) 191*10465441SEvalZero LOAD x18, 18 * REGBYTES(sp) 192*10465441SEvalZero LOAD x19, 19 * REGBYTES(sp) 193*10465441SEvalZero LOAD x20, 20 * REGBYTES(sp) 194*10465441SEvalZero LOAD x21, 21 * REGBYTES(sp) 195*10465441SEvalZero LOAD x22, 22 * REGBYTES(sp) 196*10465441SEvalZero LOAD x23, 23 * REGBYTES(sp) 197*10465441SEvalZero LOAD x24, 24 * REGBYTES(sp) 198*10465441SEvalZero LOAD x25, 25 * REGBYTES(sp) 199*10465441SEvalZero LOAD x26, 26 * REGBYTES(sp) 200*10465441SEvalZero LOAD x27, 27 * REGBYTES(sp) 201*10465441SEvalZero LOAD x28, 28 * REGBYTES(sp) 202*10465441SEvalZero LOAD x29, 29 * REGBYTES(sp) 203*10465441SEvalZero LOAD x30, 30 * REGBYTES(sp) 204*10465441SEvalZero LOAD x31, 31 * REGBYTES(sp) 205*10465441SEvalZero 206*10465441SEvalZero addi sp, sp, 32 * REGBYTES 207*10465441SEvalZero mret 208*10465441SEvalZero 209*10465441SEvalZero#ifdef RT_USING_SMP 210*10465441SEvalZero/* 211*10465441SEvalZero * void rt_hw_context_switch_interrupt(void *context, rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread); 212*10465441SEvalZero * 213*10465441SEvalZero * a0 --> context 214*10465441SEvalZero * a1 --> from 215*10465441SEvalZero * a2 --> to 216*10465441SEvalZero * a3 --> to_thread 217*10465441SEvalZero */ 218*10465441SEvalZero .globl rt_hw_context_switch_interrupt 219*10465441SEvalZerort_hw_context_switch_interrupt: 220*10465441SEvalZero 221*10465441SEvalZero STORE a0, 0(a1) 222*10465441SEvalZero 223*10465441SEvalZero csrr a1, mepc 224*10465441SEvalZero STORE a1, 0 * REGBYTES(a0) 225*10465441SEvalZero 226*10465441SEvalZero csrr a1, mstatus 227*10465441SEvalZero STORE a1, 2 * REGBYTES(a0) 228*10465441SEvalZero 229*10465441SEvalZero LOAD sp, 0(a2) 230*10465441SEvalZero move a0, a3 231*10465441SEvalZero call rt_cpus_lock_status_restore 232*10465441SEvalZero 233*10465441SEvalZero /* resw ra to mepc */ 234*10465441SEvalZero LOAD a1, 0 * REGBYTES(sp) 235*10465441SEvalZero csrw mepc, a1 236*10465441SEvalZero LOAD x1, 1 * REGBYTES(sp) 237*10465441SEvalZero 238*10465441SEvalZero /* force to machin mode(MPP=11) */ 239*10465441SEvalZero li a1, 0x00001800; 240*10465441SEvalZero csrs mstatus, a1 241*10465441SEvalZero LOAD a1, 2 * REGBYTES(sp) 242*10465441SEvalZero csrs mstatus, a1 243*10465441SEvalZero 244*10465441SEvalZero LOAD x4, 4 * REGBYTES(sp) 245*10465441SEvalZero LOAD x5, 5 * REGBYTES(sp) 246*10465441SEvalZero LOAD x6, 6 * REGBYTES(sp) 247*10465441SEvalZero LOAD x7, 7 * REGBYTES(sp) 248*10465441SEvalZero LOAD x8, 8 * REGBYTES(sp) 249*10465441SEvalZero LOAD x9, 9 * REGBYTES(sp) 250*10465441SEvalZero LOAD x10, 10 * REGBYTES(sp) 251*10465441SEvalZero LOAD x11, 11 * REGBYTES(sp) 252*10465441SEvalZero LOAD x12, 12 * REGBYTES(sp) 253*10465441SEvalZero LOAD x13, 13 * REGBYTES(sp) 254*10465441SEvalZero LOAD x14, 14 * REGBYTES(sp) 255*10465441SEvalZero LOAD x15, 15 * REGBYTES(sp) 256*10465441SEvalZero LOAD x16, 16 * REGBYTES(sp) 257*10465441SEvalZero LOAD x17, 17 * REGBYTES(sp) 258*10465441SEvalZero LOAD x18, 18 * REGBYTES(sp) 259*10465441SEvalZero LOAD x19, 19 * REGBYTES(sp) 260*10465441SEvalZero LOAD x20, 20 * REGBYTES(sp) 261*10465441SEvalZero LOAD x21, 21 * REGBYTES(sp) 262*10465441SEvalZero LOAD x22, 22 * REGBYTES(sp) 263*10465441SEvalZero LOAD x23, 23 * REGBYTES(sp) 264*10465441SEvalZero LOAD x24, 24 * REGBYTES(sp) 265*10465441SEvalZero LOAD x25, 25 * REGBYTES(sp) 266*10465441SEvalZero LOAD x26, 26 * REGBYTES(sp) 267*10465441SEvalZero LOAD x27, 27 * REGBYTES(sp) 268*10465441SEvalZero LOAD x28, 28 * REGBYTES(sp) 269*10465441SEvalZero LOAD x29, 29 * REGBYTES(sp) 270*10465441SEvalZero LOAD x30, 30 * REGBYTES(sp) 271*10465441SEvalZero LOAD x31, 31 * REGBYTES(sp) 272*10465441SEvalZero 273*10465441SEvalZero addi sp, sp, 32 * REGBYTES 274*10465441SEvalZero mret 275*10465441SEvalZero 276*10465441SEvalZero#endif 277