1*10465441SEvalZero#include <p32xxxx.h> 2*10465441SEvalZero#include "../common/mips.inc" 3*10465441SEvalZero#include "../common/stackframe.h" 4*10465441SEvalZero 5*10465441SEvalZero .section ".text", "ax" 6*10465441SEvalZero .set noat 7*10465441SEvalZero .set noreorder 8*10465441SEvalZero 9*10465441SEvalZero/* 10*10465441SEvalZero * rt_base_t rt_hw_interrupt_disable() 11*10465441SEvalZero */ 12*10465441SEvalZero .globl rt_hw_interrupt_disable 13*10465441SEvalZerort_hw_interrupt_disable: 14*10465441SEvalZero mfc0 v0, CP0_STATUS /* v0 = status */ 15*10465441SEvalZero addiu v1, zero, -2 /* v1 = 0-2 = 0xFFFFFFFE */ 16*10465441SEvalZero and v1, v0, v1 /* v1 = v0 & 0xFFFFFFFE */ 17*10465441SEvalZero mtc0 v1, CP0_STATUS /* status = v1 */ 18*10465441SEvalZero jr ra 19*10465441SEvalZero nop 20*10465441SEvalZero 21*10465441SEvalZero/* 22*10465441SEvalZero * void rt_hw_interrupt_enable(rt_base_t level) 23*10465441SEvalZero */ 24*10465441SEvalZero .globl rt_hw_interrupt_enable 25*10465441SEvalZerort_hw_interrupt_enable: 26*10465441SEvalZero mtc0 a0, CP0_STATUS 27*10465441SEvalZero jr ra 28*10465441SEvalZero nop 29*10465441SEvalZero 30*10465441SEvalZero/* 31*10465441SEvalZero * void rt_hw_context_switch_to(rt_uint32 to)/* 32*10465441SEvalZero * a0 --> to 33*10465441SEvalZero */ 34*10465441SEvalZero .globl rt_hw_context_switch_to 35*10465441SEvalZerort_hw_context_switch_to: 36*10465441SEvalZero lw sp, 0(a0) /* get new task stack pointer */ 37*10465441SEvalZero 38*10465441SEvalZero RESTORE_ALL_AND_RET 39*10465441SEvalZero 40*10465441SEvalZero/* 41*10465441SEvalZero * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to) 42*10465441SEvalZero * a0 --> from 43*10465441SEvalZero * a1 --> to 44*10465441SEvalZero */ 45*10465441SEvalZero .globl rt_hw_context_switch 46*10465441SEvalZerort_hw_context_switch: 47*10465441SEvalZero mtc0 ra, CP0_EPC 48*10465441SEvalZero SAVE_ALL 49*10465441SEvalZero 50*10465441SEvalZero sw sp, 0(a0) /* store sp in preempted tasks TCB */ 51*10465441SEvalZero lw sp, 0(a1) /* get new task stack pointer */ 52*10465441SEvalZero 53*10465441SEvalZero RESTORE_ALL_AND_RET 54*10465441SEvalZero 55*10465441SEvalZero/* 56*10465441SEvalZero * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/* 57*10465441SEvalZero */ 58*10465441SEvalZero .globl rt_thread_switch_interrupt_flag 59*10465441SEvalZero .globl rt_interrupt_from_thread 60*10465441SEvalZero .globl rt_interrupt_to_thread 61*10465441SEvalZero .globl rt_hw_context_switch_interrupt 62*10465441SEvalZerort_hw_context_switch_interrupt: 63*10465441SEvalZero la t0, rt_thread_switch_interrupt_flag 64*10465441SEvalZero lw t1, 0(t0) 65*10465441SEvalZero nop 66*10465441SEvalZero bnez t1, _reswitch 67*10465441SEvalZero nop 68*10465441SEvalZero li t1, 0x01 /* set rt_thread_switch_interrupt_flag to 1 */ 69*10465441SEvalZero sw t1, 0(t0) 70*10465441SEvalZero la t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */ 71*10465441SEvalZero sw a0, 0(t0) 72*10465441SEvalZero_reswitch: 73*10465441SEvalZero la t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */ 74*10465441SEvalZero sw a1, 0(t0) 75*10465441SEvalZero 76*10465441SEvalZero /* trigger the soft exception (causes context switch) */ 77*10465441SEvalZero mfc0 t0, CP0_CAUSE /* t0 = Cause */ 78*10465441SEvalZero ori t0, t0, (1<<8) /* t0 |= (1<<8) */ 79*10465441SEvalZero mtc0 t0, CP0_CAUSE /* cause = t0 */ 80*10465441SEvalZero addiu t1, zero, -257 /* t1 = ~(1<<8) */ 81*10465441SEvalZero and t0, t0, t1 /* t0 &= t1 */ 82*10465441SEvalZero mtc0 t0, CP0_CAUSE /* cause = t0 */ 83*10465441SEvalZero jr ra 84*10465441SEvalZero nop 85*10465441SEvalZero 86*10465441SEvalZero/* 87*10465441SEvalZero * void __ISR(_CORE_SOFTWARE_0_VECTOR, ipl2) CoreSW0Handler(void) 88*10465441SEvalZero */ 89*10465441SEvalZero .section ".text", "ax" 90*10465441SEvalZero .set noreorder 91*10465441SEvalZero .set noat 92*10465441SEvalZero .ent CoreSW0Handler 93*10465441SEvalZero 94*10465441SEvalZero .globl CoreSW0Handler 95*10465441SEvalZeroCoreSW0Handler: 96*10465441SEvalZero SAVE_ALL 97*10465441SEvalZero 98*10465441SEvalZero /* mCS0ClearIntFlag(); */ 99*10465441SEvalZero la t0, IFS0CLR /* t0 = IFS0CLR */ 100*10465441SEvalZero addiu t1,zero,0x02 /* t1 = (1<<2) */ 101*10465441SEvalZero sw t1, 0(t0) /* IFS0CLR = t1 */ 102*10465441SEvalZero 103*10465441SEvalZero la k0, rt_thread_switch_interrupt_flag 104*10465441SEvalZero sw zero, 0(k0) /* clear flag */ 105*10465441SEvalZero 106*10465441SEvalZero /* 107*10465441SEvalZero * switch to the new thread 108*10465441SEvalZero */ 109*10465441SEvalZero la k0, rt_interrupt_from_thread 110*10465441SEvalZero lw k1, 0(k0) 111*10465441SEvalZero nop 112*10465441SEvalZero sw sp, 0(k1) /* store sp in preempted tasks's TCB */ 113*10465441SEvalZero 114*10465441SEvalZero la k0, rt_interrupt_to_thread 115*10465441SEvalZero lw k1, 0(k0) 116*10465441SEvalZero nop 117*10465441SEvalZero lw sp, 0(k1) /* get new task's stack pointer */ 118*10465441SEvalZero 119*10465441SEvalZero RESTORE_ALL_AND_RET 120*10465441SEvalZero 121*10465441SEvalZero .end CoreSW0Handler 122