228 lines
5.1 KiB
ArmAsm
228 lines
5.1 KiB
ArmAsm
|
;/*
|
||
|
; * 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
|