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