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