1/* 2 * File : context_gcc.S 3 * This file is part of RT-Thread RTOS 4 * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team 5 * 6 * The license and distribution terms for this file may be 7 * found in the file LICENSE in this distribution or at 8 * http://www.rt-thread.org/license/LICENSE 9 * 10 * Change Logs: 11 * Date Author Notes 12 * 2010-05-17 swkyer first version 13 * 2010-09-11 bernard port to Loongson SoC3210 14 * 2011-08-08 lgnq port to Loongson LS1B 15 */ 16 17#include "../common/mips.inc" 18#include "../common/stackframe.h" 19#include "stackframe_fpu.h" 20 21 .section ".text", "ax" 22 .set noreorder 23 24/* 25 * rt_base_t rt_hw_interrupt_disable() 26 */ 27 .globl rt_hw_interrupt_disable 28rt_hw_interrupt_disable: 29 mfc0 v0, CP0_STATUS 30 and v1, v0, 0xfffffffe 31 mtc0 v1, CP0_STATUS 32 jr ra 33 nop 34 35/* 36 * void rt_hw_interrupt_enable(rt_base_t level) 37 */ 38 .globl rt_hw_interrupt_enable 39rt_hw_interrupt_enable: 40 ori a0, 0x00000800 41 mtc0 a0, CP0_STATUS 42 ehb 43 mfc0 v0, CP0_CAUSE 44 ehb 45 or v1, v0, 0x800000 //EBASE + 0x200 46 mtc0 v1, CP0_CAUSE 47 ehb 48 jr ra 49 nop 50 51/* 52 * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to) 53 * a0 --> from 54 * a1 --> to 55 */ 56 .globl rt_hw_context_switch 57rt_hw_context_switch: 58 mtc0 ra, CP0_EPC 59 SAVE_ALL 60 SAVE_FPU 61 62 sw sp, 0(a0) /* store sp in preempted tasks TCB */ 63 lw sp, 0(a1) /* get new task stack pointer */ 64 65 RESTORE_FPU 66 RESTORE_ALL_AND_RET 67 68/* 69 * void rt_hw_context_switch_to(rt_uint32 to)/* 70 * a0 --> to 71 */ 72 .globl rt_hw_context_switch_to 73rt_hw_context_switch_to: 74 lw sp, 0(a0) /* get new task stack pointer */ 75 76 RESTORE_FPU 77 RESTORE_ALL_AND_RET 78 79/* 80 * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/* 81 */ 82 .globl rt_thread_switch_interrupt_flag 83 .globl rt_interrupt_from_thread 84 .globl rt_interrupt_to_thread 85 .globl rt_hw_context_switch_interrupt 86rt_hw_context_switch_interrupt: 87 la t0, rt_thread_switch_interrupt_flag 88 lw t1, 0(t0) 89 nop 90 bnez t1, _reswitch 91 nop 92 li t1, 0x01 /* set rt_thread_switch_interrupt_flag to 1 */ 93 sw t1, 0(t0) 94 la t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */ 95 sw a0, 0(t0) 96_reswitch: 97 la t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */ 98 sw a1, 0(t0) 99 jr ra 100 nop 101 102/* 103 * void rt_hw_context_switch_interrupt_do(rt_base_t flag) 104 */ 105 .globl rt_interrupt_enter 106 .globl rt_interrupt_leave 107 .globl mips_irq_handle 108mips_irq_handle: 109 SAVE_ALL 110 SAVE_FPU 111 112 mfc0 t0, CP0_CAUSE 113 and t1, t0, 0xff 114 bnez t1, spurious_interrupt /* check exception */ 115 nop 116 117 /* let k0 keep the current context sp */ 118 move k0, sp 119 /* switch to kernel stack */ 120 li sp, SYSTEM_STACK 121 122 jal rt_interrupt_enter 123 nop 124 jal rt_interrupt_dispatch 125 nop 126 jal rt_interrupt_leave 127 nop 128 129 /* switch sp back to thread's context */ 130 move sp, k0 131 132 /* 133 * if rt_thread_switch_interrupt_flag set, jump to 134 * rt_hw_context_switch_interrupt_do and don't return 135 */ 136 la k0, rt_thread_switch_interrupt_flag 137 lw k1, 0(k0) 138 beqz k1, spurious_interrupt 139 nop 140 sw zero, 0(k0) /* clear flag */ 141 nop 142 143 /* 144 * switch to the new thread 145 */ 146 la k0, rt_interrupt_from_thread 147 lw k1, 0(k0) 148 nop 149 sw sp, 0(k1) /* store sp in preempted tasks's TCB */ 150 151 la k0, rt_interrupt_to_thread 152 lw k1, 0(k0) 153 nop 154 lw sp, 0(k1) /* get new task's stack pointer */ 155 j spurious_interrupt 156 nop 157 158spurious_interrupt: 159 RESTORE_FPU 160 RESTORE_ALL_AND_RET 161 162 .set reorder 163