1/* 2 * Copyright (c) 2006-2022, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2019-12-04 Jiaxun Yang Initial version 9 * 2020-07-26 lizhirui Fixed some problems 10 */ 11 12#ifndef __ASSEMBLY__ 13#define __ASSEMBLY__ 14#endif 15 16#include "mips_regs.h" 17#include "stackframe.h" 18 19 .section ".text", "ax" 20 .set noreorder 21 22/* 23 * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to) 24 * a0 --> from 25 * a1 --> to 26 */ 27 .globl rt_hw_context_switch 28rt_hw_context_switch: 29 MTC0 ra, CP0_EPC 30 SAVE_ALL 31 32 REG_S sp, 0(a0) /* store sp in preempted tasks TCB */ 33 REG_L sp, 0(a1) /* get new task stack pointer */ 34 35 RESTORE_ALL_AND_RET 36 37/* 38 * void rt_hw_context_switch_to(rt_uint32 to)/* 39 * a0 --> to 40 */ 41 .globl rt_hw_context_switch_to 42rt_hw_context_switch_to: 43 REG_L sp, 0(a0) /* get new task stack pointer */ 44 RESTORE_ALL_AND_RET 45 46/* 47 * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/* 48 */ 49 .globl rt_thread_switch_interrupt_flag 50 .globl rt_interrupt_from_thread 51 .globl rt_interrupt_to_thread 52 .globl rt_hw_context_switch_interrupt 53rt_hw_context_switch_interrupt: 54 PTR_LA t0, rt_thread_switch_interrupt_flag 55 REG_L t1, 0(t0) 56 nop 57 bnez t1, _reswitch 58 nop 59 li t1, 0x01 /* set rt_thread_switch_interrupt_flag to 1 */ 60 LONG_S t1, 0(t0) 61 PTR_LA t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */ 62 LONG_S a0, 0(t0) 63_reswitch: 64 PTR_LA t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */ 65 LONG_S a1, 0(t0) 66 jr ra 67 nop 68 69/* 70 * void rt_hw_context_switch_interrupt_do(rt_base_t flag) 71 */ 72 .globl rt_interrupt_enter 73 .globl rt_interrupt_leave 74 .globl rt_general_exc_dispatch 75 .globl mips_irq_handle 76mips_irq_handle: 77 SAVE_ALL 78 79 /* let k0 keep the current context sp */ 80 move k0, sp 81 /* switch to kernel stack */ 82 PTR_LA sp, _system_stack 83 84 jal rt_interrupt_enter 85 nop 86 /* Get Old SP from k0 as paremeter in a0 */ 87 move a0, k0 88 jal rt_general_exc_dispatch 89 nop 90 jal rt_interrupt_leave 91 nop 92 93 /* switch sp back to thread context */ 94 move sp, k0 95 96 /* 97 * if rt_thread_switch_interrupt_flag set, jump to 98 * rt_hw_context_switch_interrupt_do and do not return 99 */ 100 PTR_LA k0, rt_thread_switch_interrupt_flag 101 LONG_L k1, 0(k0) 102 beqz k1, spurious_interrupt 103 nop 104 LONG_S zero, 0(k0) /* clear flag */ 105 nop 106 107 /* 108 * switch to the new thread 109 */ 110 PTR_LA k0, rt_interrupt_from_thread 111 LONG_L k1, 0(k0) 112 nop 113 LONG_S sp, 0(k1) /* store sp in preempted task TCB */ 114 115 PTR_LA k0, rt_interrupt_to_thread 116 LONG_L k1, 0(k0) 117 nop 118 LONG_L sp, 0(k1) /* get new task stack pointer */ 119 j spurious_interrupt 120 nop 121 122spurious_interrupt: 123 RESTORE_ALL_AND_RET 124 .set reorder 125