123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- /*
- * Copyright (c) 2006-2020, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2019-12-04 Jiaxun Yang Initial version
- * 2020-07-26 lizhirui Fixed some problems
- */
- #ifndef __ASSEMBLY__
- #define __ASSEMBLY__
- #endif
- #include "mips_regs.h"
- #include "stackframe.h"
- .section ".text", "ax"
- .set noreorder
- /*
- * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)
- * a0 --> from
- * a1 --> to
- */
- .globl rt_hw_context_switch
- rt_hw_context_switch:
- MTC0 ra, CP0_EPC
- SAVE_ALL
- REG_S sp, 0(a0) /* store sp in preempted tasks TCB */
- REG_L sp, 0(a1) /* get new task stack pointer */
- RESTORE_ALL_AND_RET
- /*
- * void rt_hw_context_switch_to(rt_uint32 to)/*
- * a0 --> to
- */
- .globl rt_hw_context_switch_to
- rt_hw_context_switch_to:
- REG_L sp, 0(a0) /* get new task stack pointer */
- RESTORE_ALL_AND_RET
- /*
- * 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:
- PTR_LA t0, rt_thread_switch_interrupt_flag
- REG_L t1, 0(t0)
- nop
- bnez t1, _reswitch
- nop
- li t1, 0x01 /* set rt_thread_switch_interrupt_flag to 1 */
- LONG_S t1, 0(t0)
- PTR_LA t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
- LONG_S a0, 0(t0)
- _reswitch:
- PTR_LA t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */
- LONG_S a1, 0(t0)
- jr ra
- nop
- /*
- * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
- */
- .globl rt_interrupt_enter
- .globl rt_interrupt_leave
- .globl rt_general_exc_dispatch
- .globl mips_irq_handle
- mips_irq_handle:
- SAVE_ALL
- /* let k0 keep the current context sp */
- move k0, sp
- /* switch to kernel stack */
- PTR_LA sp, _system_stack
- jal rt_interrupt_enter
- nop
- /* Get Old SP from k0 as paremeter in a0 */
- move a0, k0
- jal rt_general_exc_dispatch
- nop
- jal rt_interrupt_leave
- nop
- /* switch sp back to thread context */
- move sp, k0
- /*
- * if rt_thread_switch_interrupt_flag set, jump to
- * rt_hw_context_switch_interrupt_do and do not return
- */
- PTR_LA k0, rt_thread_switch_interrupt_flag
- LONG_L k1, 0(k0)
- beqz k1, spurious_interrupt
- nop
- LONG_S zero, 0(k0) /* clear flag */
- nop
- /*
- * switch to the new thread
- */
- PTR_LA k0, rt_interrupt_from_thread
- LONG_L k1, 0(k0)
- nop
- LONG_S sp, 0(k1) /* store sp in preempted task TCB */
- PTR_LA k0, rt_interrupt_to_thread
- LONG_L k1, 0(k0)
- nop
- LONG_L sp, 0(k1) /* get new task stack pointer */
- j spurious_interrupt
- nop
- spurious_interrupt:
- RESTORE_ALL_AND_RET
- .set reorder
|