summaryrefslogtreecommitdiff
path: root/libcpu/mips/pic32/context_gcc.S
blob: 5c6f20af6e05d8188cd4346d09e5904bb84bc302 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
 * Copyright (c) 2006-2022, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2011-05-24     aozima       first version
 * 2019-07-19     Zhou Yanjie  clean up code
 */

#ifndef __ASSEMBLY__
#define __ASSEMBLY__
#endif

#include <p32xxxx.h>
#include "../common/mips_def.h"
#include "../common/stackframe.h"

    .section ".text", "ax"
    .set        noat
    .set noreorder

/*
 * rt_base_t rt_hw_interrupt_disable()
 */
    .globl rt_hw_interrupt_disable
rt_hw_interrupt_disable:
    mfc0    v0, CP0_STATUS    /* v0 = status */
    addiu   v1, zero,   -2    /* v1 = 0-2 = 0xFFFFFFFE */
    and     v1, v0, v1        /* v1 = v0 & 0xFFFFFFFE */
    mtc0    v1, CP0_STATUS    /* status = v1 */
    jr      ra
    nop

/*
 * void rt_hw_interrupt_enable(rt_base_t level)
 */
    .globl rt_hw_interrupt_enable
rt_hw_interrupt_enable:
    mtc0    a0, CP0_STATUS
    jr      ra
    nop

/*
 * void rt_hw_context_switch_to(rt_uint32 to)/*
 * a0 --> to
 */
    .globl rt_hw_context_switch_to
rt_hw_context_switch_to:
    lw      sp, 0(a0)       /* get new task stack pointer */

    RESTORE_ALL_AND_RET

/*
 * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)
 * a0 --> from
 * a1 --> to
 */
    .globl rt_hw_context_switch
rt_hw_context_switch:
    mtc0    ra, CP0_EPC
    SAVE_ALL

    sw      sp, 0(a0)       /* store sp in preempted tasks TCB */
    lw      sp, 0(a1)       /* get new task stack pointer */

    RESTORE_ALL_AND_RET

/*
 * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/*
 */
    .globl rt_thread_switch_interrupt_flag
    .globl rt_interrupt_from_thread
    .globl rt_interrupt_to_thread
    .globl rt_hw_context_switch_interrupt
rt_hw_context_switch_interrupt:
    la      t0, rt_thread_switch_interrupt_flag
    lw      t1, 0(t0)
    nop
    bnez    t1, _reswitch
    nop
    li      t1, 0x01                       /* set rt_thread_switch_interrupt_flag to 1 */
    sw      t1, 0(t0)
    la      t0, rt_interrupt_from_thread   /* set rt_interrupt_from_thread */
    sw      a0, 0(t0)
_reswitch:
    la      t0, rt_interrupt_to_thread     /* set rt_interrupt_to_thread */
    sw      a1, 0(t0)

    /* trigger the soft exception (causes context switch) */
    mfc0    t0, CP0_CAUSE                  /* t0 = Cause */
    ori     t0, t0, (1<<8)                 /* t0 |= (1<<8) */
    mtc0    t0, CP0_CAUSE                  /* cause = t0 */
    addiu   t1, zero,   -257               /* t1 = ~(1<<8) */
    and     t0, t0, t1                     /* t0 &= t1 */
    mtc0    t0, CP0_CAUSE                  /* cause = t0 */
    jr      ra
    nop

/*
 * void __ISR(_CORE_SOFTWARE_0_VECTOR, ipl2) CoreSW0Handler(void)
 */
    .section ".text", "ax"
    .set noreorder
    .set        noat
    .ent        CoreSW0Handler

        .globl CoreSW0Handler
CoreSW0Handler:
    SAVE_ALL

    /* mCS0ClearIntFlag(); */
    la      t0, IFS0CLR             /* t0 = IFS0CLR */
    addiu   t1,zero,0x02            /* t1 = (1<<2) */
    sw      t1, 0(t0)               /* IFS0CLR = t1 */

    la      k0, rt_thread_switch_interrupt_flag
    sw      zero, 0(k0)                     /* clear flag */

    /*
     * switch to the new thread
     */
    la      k0, rt_interrupt_from_thread
    lw      k1, 0(k0)
    nop
    sw      sp, 0(k1)                       /* store sp in preempted tasks's TCB */

    la      k0, rt_interrupt_to_thread
    lw      k1, 0(k0)
    nop
    lw      sp, 0(k1)                       /* get new task's stack pointer */

    RESTORE_ALL_AND_RET

    .end        CoreSW0Handler