/* * File : context_gcc.S * This file is part of RT-Thread RTOS * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rt-thread.org/license/LICENSE * * Change Logs: * Date Author Notes * 2010-05-17 swkyer first version * 2010-09-11 bernard port to Loongson SoC3210 * 2011-08-08 lgnq port to Loongson LS1B */ #include "../common/mips.inc" #include "../common/stackframe.h" .section ".text", "ax" .set noreorder /* * rt_base_t rt_hw_interrupt_disable() */ .globl rt_hw_interrupt_disable rt_hw_interrupt_disable: mfc0 v0, CP0_STATUS and v1, v0, 0xfffffffe mtc0 v1, CP0_STATUS jr ra nop /* * void rt_hw_interrupt_enable(rt_base_t level) */ .globl rt_hw_interrupt_enable rt_hw_interrupt_enable: mtc0 a0, CP0_STATUS jr ra nop /* * 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 sw sp, 0(a0) /* store sp in preempted tasks TCB */ lw 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: lw 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_interrput_flag .globl rt_interrupt_from_thread .globl rt_interrupt_to_thread .globl rt_hw_context_switch_interrupt rt_hw_context_switch_interrupt: la t0, rt_thread_switch_interrput_flag lw t1, 0(t0) nop bnez t1, _reswitch nop li t1, 0x01 /* set rt_thread_switch_interrput_flag to 1 */ sw t1, 0(t0) la t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */ sw a0, 0(t0) _reswitch: la t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */ sw 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 mips_irq_handle mips_irq_handle: SAVE_ALL mfc0 t0, CP0_CAUSE and t1, t0, 0xff bnez t1, spurious_interrupt /* check exception */ nop /* let k0 keep the current context sp */ move k0, sp /* switch to kernel stack */ li sp, SYSTEM_STACK jal rt_interrupt_enter nop jal rt_interrupt_dispatch nop jal rt_interrupt_leave nop /* switch sp back to thread's context */ move sp, k0 /* * if rt_thread_switch_interrput_flag set, jump to * rt_hw_context_switch_interrupt_do and don't return */ la k0, rt_thread_switch_interrput_flag lw k1, 0(k0) beqz k1, spurious_interrupt nop sw zero, 0(k0) /* clear flag */ nop /* * switch to the new thread */ la k0, rt_interrupt_from_thread lw k1, 0(k0) nop sw sp, 0(k1) /* store sp in preempted tasks's TCB */ la k0, rt_interrupt_to_thread lw k1, 0(k0) nop lw sp, 0(k1) /* get new task's stack pointer */ j spurious_interrupt nop spurious_interrupt: RESTORE_ALL_AND_RET .set reorder