• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021 Nuclei Limited. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 *    conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 *    of conditions and the following disclaimer in the documentation and/or other materials
12 *    provided with the distribution.
13 *
14 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15 *    to endorse or promote products derived from this software without specific prior written
16 *    permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "riscv_encoding.h"
32
33#ifndef __riscv_32e
34#define portRegNum          30
35#else
36#define portRegNum          14
37#endif
38
39#define portCONTEXT_SIZE    ( portRegNum * REGBYTES )
40
41    .section .text
42    .align 4
43
44    .type ArchIntLock, %function
45    .global ArchIntLock
46ArchIntLock:
47    csrr    a0, mstatus           // return value
48    li      t0, MSTATUS_MIE   // mie
49    csrrc   zero, mstatus, t0
50    ret
51
52    .type ArchIntUnLock, %function
53    .global ArchIntUnLock
54ArchIntUnLock:
55    csrr    a0, mstatus           // return value
56    li      t0, MSTATUS_MIE   // mie
57    csrrs   zero, mstatus, t0
58    ret
59
60    .type ArchIntRestore, %function
61    .global ArchIntRestore
62ArchIntRestore:
63    csrw mstatus, a0
64    ret
65
66
67/* Start the first task.  This also clears the bit that indicates the FPU is
68    in use in case the FPU was used before the scheduler was started - which
69    would otherwise result in the unnecessary leaving of space in the stack
70    for lazy saving of FPU registers. */
71    .type HalStartToRun, %function
72    .global HalStartToRun
73    .align 3
74HalStartToRun:
75    /* Setup Interrupt Stack using
76       The stack that was used by main()
77       before the scheduler is started is
78       no longer required after the scheduler is started.
79       Interrupt stack pointer is stored in CSR_MSCRATCH */
80    la t0, _sp
81    csrw CSR_MSCRATCH, t0
82    /* get stack pointer */
83    la t0, g_losTask
84    LOAD t1, 0x0(t0)
85    LOAD      sp, 0(t1)
86    //LOAD sp, 0x0(sp)                /* Read sp from first TCB member */
87
88    /* Pop PC from stack and set MEPC */
89    LOAD t0,  0  * REGBYTES(sp)
90    csrw CSR_MEPC, t0
91    /* Pop mstatus from stack and set it */
92    LOAD t0,  (portRegNum - 1)  * REGBYTES(sp)
93    csrw CSR_MSTATUS, t0
94    /* Interrupt still disable here */
95    /* Restore Registers from Stack */
96    LOAD x1,  1  * REGBYTES(sp)    /* RA */
97    LOAD x5,  2  * REGBYTES(sp)
98    LOAD x6,  3  * REGBYTES(sp)
99    LOAD x7,  4  * REGBYTES(sp)
100    LOAD x8,  5  * REGBYTES(sp)
101    LOAD x9,  6  * REGBYTES(sp)
102    LOAD x10, 7  * REGBYTES(sp)
103    LOAD x11, 8  * REGBYTES(sp)
104    LOAD x12, 9  * REGBYTES(sp)
105    LOAD x13, 10 * REGBYTES(sp)
106    LOAD x14, 11 * REGBYTES(sp)
107    LOAD x15, 12 * REGBYTES(sp)
108#ifndef __riscv_32e
109    LOAD x16, 13 * REGBYTES(sp)
110    LOAD x17, 14 * REGBYTES(sp)
111    LOAD x18, 15 * REGBYTES(sp)
112    LOAD x19, 16 * REGBYTES(sp)
113    LOAD x20, 17 * REGBYTES(sp)
114    LOAD x21, 18 * REGBYTES(sp)
115    LOAD x22, 19 * REGBYTES(sp)
116    LOAD x23, 20 * REGBYTES(sp)
117    LOAD x24, 21 * REGBYTES(sp)
118    LOAD x25, 22 * REGBYTES(sp)
119    LOAD x26, 23 * REGBYTES(sp)
120    LOAD x27, 24 * REGBYTES(sp)
121    LOAD x28, 25 * REGBYTES(sp)
122    LOAD x29, 26 * REGBYTES(sp)
123    LOAD x30, 27 * REGBYTES(sp)
124    LOAD x31, 28 * REGBYTES(sp)
125#endif
126
127    addi sp, sp, portCONTEXT_SIZE
128
129    mret
130
131.extern HalTaskSwitch
132.align 2
133.global eclic_msip_handler
134eclic_msip_handler:
135    addi sp, sp, -portCONTEXT_SIZE
136    STORE x1,  1  * REGBYTES(sp)    /* RA */
137    STORE x5,  2  * REGBYTES(sp)
138    STORE x6,  3  * REGBYTES(sp)
139    STORE x7,  4  * REGBYTES(sp)
140    STORE x8,  5  * REGBYTES(sp)
141    STORE x9,  6  * REGBYTES(sp)
142    STORE x10, 7  * REGBYTES(sp)
143    STORE x11, 8  * REGBYTES(sp)
144    STORE x12, 9  * REGBYTES(sp)
145    STORE x13, 10 * REGBYTES(sp)
146    STORE x14, 11 * REGBYTES(sp)
147    STORE x15, 12 * REGBYTES(sp)
148#ifndef __riscv_32e
149    STORE x16, 13 * REGBYTES(sp)
150    STORE x17, 14 * REGBYTES(sp)
151    STORE x18, 15 * REGBYTES(sp)
152    STORE x19, 16 * REGBYTES(sp)
153    STORE x20, 17 * REGBYTES(sp)
154    STORE x21, 18 * REGBYTES(sp)
155    STORE x22, 19 * REGBYTES(sp)
156    STORE x23, 20 * REGBYTES(sp)
157    STORE x24, 21 * REGBYTES(sp)
158    STORE x25, 22 * REGBYTES(sp)
159    STORE x26, 23 * REGBYTES(sp)
160    STORE x27, 24 * REGBYTES(sp)
161    STORE x28, 25 * REGBYTES(sp)
162    STORE x29, 26 * REGBYTES(sp)
163    STORE x30, 27 * REGBYTES(sp)
164    STORE x31, 28 * REGBYTES(sp)
165#endif
166    /* Push mstatus to stack */
167    csrr t0, CSR_MSTATUS
168    STORE t0,  (portRegNum - 1)  * REGBYTES(sp)
169
170    /* Push additional registers */
171
172    /* Store sp to task stack */
173    la t0, g_losTask
174    LOAD t0, 0(t0)
175    STORE sp, 0(t0)
176
177    csrr t0, CSR_MEPC
178    STORE t0, 0(sp)
179
180    /* Switch task context */
181    jal HalTaskSwitch
182    /* Load new task */
183    la t0, g_losTask
184    LOAD t0, 0(t0)
185    LOAD sp, 0x0(t0)                /* Read sp from first TCB member */
186
187    /* Pop PC from stack and set MEPC */
188    LOAD t0,  0  * REGBYTES(sp)
189    csrw CSR_MEPC, t0
190    /* Pop additional registers */
191
192    /* Pop mstatus from stack and set it */
193    LOAD t0,  (portRegNum - 1)  * REGBYTES(sp)
194    csrw CSR_MSTATUS, t0
195    /* Interrupt still disable here */
196    /* Restore Registers from Stack */
197    LOAD x1,  1  * REGBYTES(sp)    /* RA */
198    LOAD x5,  2  * REGBYTES(sp)
199    LOAD x6,  3  * REGBYTES(sp)
200    LOAD x7,  4  * REGBYTES(sp)
201    LOAD x8,  5  * REGBYTES(sp)
202    LOAD x9,  6  * REGBYTES(sp)
203    LOAD x10, 7  * REGBYTES(sp)
204    LOAD x11, 8  * REGBYTES(sp)
205    LOAD x12, 9  * REGBYTES(sp)
206    LOAD x13, 10 * REGBYTES(sp)
207    LOAD x14, 11 * REGBYTES(sp)
208    LOAD x15, 12 * REGBYTES(sp)
209#ifndef __riscv_32e
210    LOAD x16, 13 * REGBYTES(sp)
211    LOAD x17, 14 * REGBYTES(sp)
212    LOAD x18, 15 * REGBYTES(sp)
213    LOAD x19, 16 * REGBYTES(sp)
214    LOAD x20, 17 * REGBYTES(sp)
215    LOAD x21, 18 * REGBYTES(sp)
216    LOAD x22, 19 * REGBYTES(sp)
217    LOAD x23, 20 * REGBYTES(sp)
218    LOAD x24, 21 * REGBYTES(sp)
219    LOAD x25, 22 * REGBYTES(sp)
220    LOAD x26, 23 * REGBYTES(sp)
221    LOAD x27, 24 * REGBYTES(sp)
222    LOAD x28, 25 * REGBYTES(sp)
223    LOAD x29, 26 * REGBYTES(sp)
224    LOAD x30, 27 * REGBYTES(sp)
225    LOAD x31, 28 * REGBYTES(sp)
226#endif
227
228    addi sp, sp, portCONTEXT_SIZE
229    mret
230