1*10465441SEvalZero/* 2*10465441SEvalZero * File : context_gcc.S 3*10465441SEvalZero * Change Logs: 4*10465441SEvalZero * Date Author Notes 5*10465441SEvalZero * 2010-05-17 swkyer first version 6*10465441SEvalZero * 2010-09-11 bernard port to Jz4755 7*10465441SEvalZero */ 8*10465441SEvalZero#include "../common/mips.inc" 9*10465441SEvalZero#include "../common/stackframe.h" 10*10465441SEvalZero#include "stack.h" 11*10465441SEvalZero 12*10465441SEvalZero .section ".text", "ax" 13*10465441SEvalZero .set noreorder 14*10465441SEvalZero 15*10465441SEvalZero/* 16*10465441SEvalZero * rt_base_t rt_hw_interrupt_disable() 17*10465441SEvalZero */ 18*10465441SEvalZero .globl rt_hw_interrupt_disable 19*10465441SEvalZerort_hw_interrupt_disable: 20*10465441SEvalZero mfc0 v0, CP0_STATUS 21*10465441SEvalZero and v1, v0, 0xfffffffe 22*10465441SEvalZero mtc0 v1, CP0_STATUS 23*10465441SEvalZero jr ra 24*10465441SEvalZero nop 25*10465441SEvalZero 26*10465441SEvalZero/* 27*10465441SEvalZero * void rt_hw_interrupt_enable(rt_base_t level) 28*10465441SEvalZero */ 29*10465441SEvalZero .globl rt_hw_interrupt_enable 30*10465441SEvalZerort_hw_interrupt_enable: 31*10465441SEvalZero mtc0 a0, CP0_STATUS 32*10465441SEvalZero jr ra 33*10465441SEvalZero nop 34*10465441SEvalZero 35*10465441SEvalZero/* 36*10465441SEvalZero * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to) 37*10465441SEvalZero * a0 --> from 38*10465441SEvalZero * a1 --> to 39*10465441SEvalZero */ 40*10465441SEvalZero .globl rt_hw_context_switch 41*10465441SEvalZerort_hw_context_switch: 42*10465441SEvalZero mtc0 ra, CP0_EPC 43*10465441SEvalZero SAVE_ALL 44*10465441SEvalZero 45*10465441SEvalZero sw sp, 0(a0) /* store sp in preempted tasks TCB */ 46*10465441SEvalZero lw sp, 0(a1) /* get new task stack pointer */ 47*10465441SEvalZero 48*10465441SEvalZero RESTORE_ALL_AND_RET 49*10465441SEvalZero 50*10465441SEvalZero/* 51*10465441SEvalZero * void rt_hw_context_switch_to(rt_uint32 to)/* 52*10465441SEvalZero * a0 --> to 53*10465441SEvalZero */ 54*10465441SEvalZero .globl rt_hw_context_switch_to 55*10465441SEvalZerort_hw_context_switch_to: 56*10465441SEvalZero lw sp, 0(a0) /* get new task stack pointer */ 57*10465441SEvalZero 58*10465441SEvalZero RESTORE_ALL_AND_RET 59*10465441SEvalZero 60*10465441SEvalZero/* 61*10465441SEvalZero * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/* 62*10465441SEvalZero */ 63*10465441SEvalZero .globl rt_thread_switch_interrupt_flag 64*10465441SEvalZero .globl rt_interrupt_from_thread 65*10465441SEvalZero .globl rt_interrupt_to_thread 66*10465441SEvalZero .globl rt_hw_context_switch_interrupt 67*10465441SEvalZerort_hw_context_switch_interrupt: 68*10465441SEvalZero la t0, rt_thread_switch_interrupt_flag 69*10465441SEvalZero lw t1, 0(t0) 70*10465441SEvalZero nop 71*10465441SEvalZero bnez t1, _reswitch 72*10465441SEvalZero nop 73*10465441SEvalZero li t1, 0x01 /* set rt_thread_switch_interrupt_flag to 1 */ 74*10465441SEvalZero sw t1, 0(t0) 75*10465441SEvalZero la t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */ 76*10465441SEvalZero sw a0, 0(t0) 77*10465441SEvalZero_reswitch: 78*10465441SEvalZero la t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */ 79*10465441SEvalZero sw a1, 0(t0) 80*10465441SEvalZero jr ra 81*10465441SEvalZero nop 82*10465441SEvalZero 83*10465441SEvalZero .globl system_dump 84*10465441SEvalZero 85*10465441SEvalZero/* 86*10465441SEvalZero * void rt_hw_context_switch_interrupt_do(rt_base_t flag) 87*10465441SEvalZero */ 88*10465441SEvalZero .globl rt_interrupt_enter 89*10465441SEvalZero .globl rt_interrupt_leave 90*10465441SEvalZero .globl mips_irq_handle 91*10465441SEvalZeromips_irq_handle: 92*10465441SEvalZero SAVE_ALL 93*10465441SEvalZero 94*10465441SEvalZero mfc0 t0, CP0_CAUSE 95*10465441SEvalZero mfc0 t1, CP0_STATUS 96*10465441SEvalZero and t0, t1 97*10465441SEvalZero 98*10465441SEvalZero andi t0, 0xff00 99*10465441SEvalZero beqz t0, spurious_interrupt 100*10465441SEvalZero nop 101*10465441SEvalZero 102*10465441SEvalZero /* let k0 keep the current context sp */ 103*10465441SEvalZero move k0, sp 104*10465441SEvalZero /* switch to kernel stack */ 105*10465441SEvalZero li sp, SYSTEM_STACK 106*10465441SEvalZero 107*10465441SEvalZero jal rt_interrupt_enter 108*10465441SEvalZero nop 109*10465441SEvalZero jal rt_interrupt_dispatch 110*10465441SEvalZero nop 111*10465441SEvalZero jal rt_interrupt_leave 112*10465441SEvalZero nop 113*10465441SEvalZero 114*10465441SEvalZero /* switch sp back to thread's context */ 115*10465441SEvalZero move sp, k0 116*10465441SEvalZero 117*10465441SEvalZero /* 118*10465441SEvalZero * if rt_thread_switch_interrupt_flag set, jump to 119*10465441SEvalZero * rt_hw_context_switch_interrupt_do and don't return 120*10465441SEvalZero */ 121*10465441SEvalZero la k0, rt_thread_switch_interrupt_flag 122*10465441SEvalZero lw k1, 0(k0) 123*10465441SEvalZero beqz k1, spurious_interrupt 124*10465441SEvalZero nop 125*10465441SEvalZero sw zero, 0(k0) /* clear flag */ 126*10465441SEvalZero nop 127*10465441SEvalZero 128*10465441SEvalZero /* 129*10465441SEvalZero * switch to the new thread 130*10465441SEvalZero */ 131*10465441SEvalZero la k0, rt_interrupt_from_thread 132*10465441SEvalZero lw k1, 0(k0) 133*10465441SEvalZero nop 134*10465441SEvalZero sw sp, 0(k1) /* store sp in preempted tasks's TCB */ 135*10465441SEvalZero 136*10465441SEvalZero la k0, rt_interrupt_to_thread 137*10465441SEvalZero lw k1, 0(k0) 138*10465441SEvalZero nop 139*10465441SEvalZero lw sp, 0(k1) /* get new task's stack pointer */ 140*10465441SEvalZero j spurious_interrupt 141*10465441SEvalZero nop 142*10465441SEvalZero 143*10465441SEvalZerospurious_interrupt: 144*10465441SEvalZero RESTORE_ALL_AND_RET 145*10465441SEvalZero 146*10465441SEvalZero .set reorder 147