xref: /nrf52832-nimble/rt-thread/libcpu/mips/pic32/context_gcc.S (revision 104654410c56c573564690304ae786df310c91fc)
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