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 20 .section ".text", "ax" 21 .set noreorder 22 23/* 24 * rt_base_t rt_hw_interrupt_disable() 25 */ 26 .globl rt_hw_interrupt_disable 27rt_hw_interrupt_disable: 28 mfc0 v0, CP0_STATUS 29 and v1, v0, 0xfffffffe 30 mtc0 v1, CP0_STATUS 31 jr ra 32 nop 33 34/* 35 * void rt_hw_interrupt_enable(rt_base_t level) 36 */ 37 .globl rt_hw_interrupt_enable 38rt_hw_interrupt_enable: 39 mtc0 a0, CP0_STATUS 40 jr ra 41 nop 42 43/* 44 * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to) 45 * a0 --> from 46 * a1 --> to 47 */ 48 .globl rt_hw_context_switch 49rt_hw_context_switch: 50 mtc0 ra, CP0_EPC 51 SAVE_ALL 52 53 sw sp, 0(a0) /* store sp in preempted tasks TCB */ 54 lw sp, 0(a1) /* get new task stack pointer */ 55 56 RESTORE_ALL_AND_RET 57 58/* 59 * void rt_hw_context_switch_to(rt_uint32 to)/* 60 * a0 --> to 61 */ 62 .globl rt_hw_context_switch_to 63rt_hw_context_switch_to: 64 lw sp, 0(a0) /* get new task stack pointer */ 65 66 RESTORE_ALL_AND_RET 67 68/* 69 * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/* 70 */ 71 .globl rt_thread_switch_interrupt_flag 72 .globl rt_interrupt_from_thread 73 .globl rt_interrupt_to_thread 74 .globl rt_hw_context_switch_interrupt 75rt_hw_context_switch_interrupt: 76 la t0, rt_thread_switch_interrupt_flag 77 lw t1, 0(t0) 78 nop 79 bnez t1, _reswitch 80 nop 81 li t1, 0x01 /* set rt_thread_switch_interrupt_flag to 1 */ 82 sw t1, 0(t0) 83 la t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */ 84 sw a0, 0(t0) 85_reswitch: 86 la t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */ 87 sw a1, 0(t0) 88 jr ra 89 nop 90 91/* 92 * void rt_hw_context_switch_interrupt_do(rt_base_t flag) 93 */ 94 .globl rt_interrupt_enter 95 .globl rt_interrupt_leave 96 .globl mips_irq_handle 97mips_irq_handle: 98 SAVE_ALL 99 100 mfc0 t0, CP0_CAUSE 101 and t1, t0, 0xff 102 bnez t1, spurious_interrupt /* check exception */ 103 nop 104 105 /* let k0 keep the current context sp */ 106 move k0, sp 107 /* switch to kernel stack */ 108 li sp, SYSTEM_STACK 109 110 jal rt_interrupt_enter 111 nop 112 jal rt_interrupt_dispatch 113 nop 114 jal rt_interrupt_leave 115 nop 116 117 /* switch sp back to thread's context */ 118 move sp, k0 119 120 /* 121 * if rt_thread_switch_interrupt_flag set, jump to 122 * rt_hw_context_switch_interrupt_do and don't return 123 */ 124 la k0, rt_thread_switch_interrupt_flag 125 lw k1, 0(k0) 126 beqz k1, spurious_interrupt 127 nop 128 sw zero, 0(k0) /* clear flag */ 129 nop 130 131 /* 132 * switch to the new thread 133 */ 134 la k0, rt_interrupt_from_thread 135 lw k1, 0(k0) 136 nop 137 sw sp, 0(k1) /* store sp in preempted tasks's TCB */ 138 139 la k0, rt_interrupt_to_thread 140 lw k1, 0(k0) 141 nop 142 lw sp, 0(k1) /* get new task's stack pointer */ 143 j spurious_interrupt 144 nop 145 146spurious_interrupt: 147 RESTORE_ALL_AND_RET 148 149 .set reorder 150