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