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