;/* ; * File : context_gcc.S ; * This file is part of RT-Thread RTOS ; * COPYRIGHT (C) 2018, RT-Thread Development Team ; * ; * This program is free software; you can redistribute it and/or modify ; * it under the terms of the GNU General Public License as published by ; * the Free Software Foundation; either version 2 of the License, or ; * (at your option) any later version. ; * ; * This program is distributed in the hope that it will be useful, ; * but WITHOUT ANY WARRANTY; without even the implied warranty of ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; * GNU General Public License for more details. ; * ; * You should have received a copy of the GNU General Public License along ; * with this program; if not, write to the Free Software Foundation, Inc., ; * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ; * ; * Change Logs: ; * Date Author Notes ; * 2017-07-16 zhangjun for hifive1 ; * 2018-05-29 tanek optimize rt_hw_interrupt_* ; * 2018-05-29 tanek add mie register to context ; */ /* * rt_base_t rt_hw_interrupt_disable(void); */ .globl rt_hw_interrupt_disable rt_hw_interrupt_disable: csrrci a0, mstatus, 8 ret /* * void rt_hw_interrupt_enable(rt_base_t level); */ .globl rt_hw_interrupt_enable rt_hw_interrupt_enable: csrw mstatus, a0 ret /* * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); * a0 --> from * a1 --> to */ .globl rt_hw_context_switch rt_hw_context_switch: /* saved from thread context * x1/ra -> sp(0) * x1/ra -> sp(1) * mstatus.mie -> sp(2) * x(i) -> sp(i-4) */ addi sp, sp, -32 * 4 sw sp, (a0) sw x1, 0 * 4(sp) sw x1, 1 * 4(sp) csrr a0, mstatus andi a0, a0, 8 beqz a0, save_mpie li a0, 0x80 save_mpie: sw a0, 2 * 4(sp) sw x4, 4 * 4(sp) sw x5, 5 * 4(sp) sw x6, 6 * 4(sp) sw x7, 7 * 4(sp) sw x8, 8 * 4(sp) sw x9, 9 * 4(sp) sw x10, 10 * 4(sp) sw x11, 11 * 4(sp) sw x12, 12 * 4(sp) sw x13, 13 * 4(sp) sw x14, 14 * 4(sp) sw x15, 15 * 4(sp) sw x16, 16 * 4(sp) sw x17, 17 * 4(sp) sw x18, 18 * 4(sp) sw x19, 19 * 4(sp) sw x20, 20 * 4(sp) sw x21, 21 * 4(sp) sw x22, 22 * 4(sp) sw x23, 23 * 4(sp) sw x24, 24 * 4(sp) sw x25, 25 * 4(sp) sw x26, 26 * 4(sp) sw x27, 27 * 4(sp) sw x28, 28 * 4(sp) sw x29, 29 * 4(sp) sw x30, 30 * 4(sp) sw x31, 31 * 4(sp) /* restore to thread context * sp(0) -> epc; * sp(1) -> ra; * sp(i) -> x(i+2) */ lw sp, (a1) /* resw ra to mepc */ lw a1, 0 * 4(sp) csrw mepc, a1 lw x1, 1 * 4(sp) /* force to machin mode(MPP=11) */ li a1, 0x00001800; csrs mstatus, a1 lw a1, 2 * 4(sp) csrs mstatus, a1 lw x4, 4 * 4(sp) lw x5, 5 * 4(sp) lw x6, 6 * 4(sp) lw x7, 7 * 4(sp) lw x8, 8 * 4(sp) lw x9, 9 * 4(sp) lw x10, 10 * 4(sp) lw x11, 11 * 4(sp) lw x12, 12 * 4(sp) lw x13, 13 * 4(sp) lw x14, 14 * 4(sp) lw x15, 15 * 4(sp) lw x16, 16 * 4(sp) lw x17, 17 * 4(sp) lw x18, 18 * 4(sp) lw x19, 19 * 4(sp) lw x20, 20 * 4(sp) lw x21, 21 * 4(sp) lw x22, 22 * 4(sp) lw x23, 23 * 4(sp) lw x24, 24 * 4(sp) lw x25, 25 * 4(sp) lw x26, 26 * 4(sp) lw x27, 27 * 4(sp) lw x28, 28 * 4(sp) lw x29, 29 * 4(sp) lw x30, 30 * 4(sp) lw x31, 31 * 4(sp) addi sp, sp, 32 * 4 mret /* * void rt_hw_context_switch_to(rt_uint32 to); * a0 --> to */ .globl rt_hw_context_switch_to rt_hw_context_switch_to: lw sp, (a0) /* load epc from stack */ lw a0, 0 * 4(sp) csrw mepc, a0 lw x1, 1 * 4(sp) /* load mstatus from stack */ lw a0, 2 * 4(sp) csrw mstatus, a0 lw x4, 4 * 4(sp) lw x5, 5 * 4(sp) lw x6, 6 * 4(sp) lw x7, 7 * 4(sp) lw x8, 8 * 4(sp) lw x9, 9 * 4(sp) lw x10, 10 * 4(sp) lw x11, 11 * 4(sp) lw x12, 12 * 4(sp) lw x13, 13 * 4(sp) lw x14, 14 * 4(sp) lw x15, 15 * 4(sp) lw x16, 16 * 4(sp) lw x17, 17 * 4(sp) lw x18, 18 * 4(sp) lw x19, 19 * 4(sp) lw x20, 20 * 4(sp) lw x21, 21 * 4(sp) lw x22, 22 * 4(sp) lw x23, 23 * 4(sp) lw x24, 24 * 4(sp) lw x25, 25 * 4(sp) lw x26, 26 * 4(sp) lw x27, 27 * 4(sp) lw x28, 28 * 4(sp) lw x29, 29 * 4(sp) lw x30, 30 * 4(sp) lw x31, 31 * 4(sp) addi sp, sp, 32 * 4 mret /* * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); */ .globl rt_thread_switch_interrupt_flag .globl rt_interrupt_from_thread .globl rt_interrupt_to_thread .globl rt_hw_context_switch_interrupt rt_hw_context_switch_interrupt: addi sp, sp, -16 sw s0, 12(sp) sw a0, 8(sp) sw a5, 4(sp) la a0, rt_thread_switch_interrupt_flag lw a5, (a0) bnez a5, _reswitch li a5, 1 sw a5, (a0) la a5, rt_interrupt_from_thread lw a0, 8(sp) sw a0, (a5) _reswitch: la a5, rt_interrupt_to_thread sw a1, (a5) lw a5, 4(sp) lw a0, 8(sp) lw s0, 12(sp) addi sp, sp, 16 ret