]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/GCC/RISC-V-RV32/portASM.S
Some efficiency improvements in Risc-V port.
[freertos] / FreeRTOS / Source / portable / GCC / RISC-V-RV32 / portASM.S
1 /*\r
2  * FreeRTOS Kernel V10.1.1\r
3  * Copyright (C) 2018 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and t\r
10 \r
11  o permit persons to whom the Software is furnished to do so,\r
12  * subject to the following conditions:\r
13  *\r
14  * The above copyright notice and this permission notice shall be included in all\r
15  * copies or substantial portions of the Software.\r
16  *\r
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
19  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
20  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
23  *\r
24  * http://www.FreeRTOS.org\r
25  * http://aws.amazon.com/freertos\r
26  *\r
27  * 1 tab == 4 spaces!\r
28  */\r
29 \r
30 #if __riscv_xlen == 64\r
31         #error Not implemented yet - change lw to ld, and sw to sd.\r
32         #define WORD_SIZE 8\r
33 #elif __riscv_xlen == 32\r
34         #define WORD_SIZE 4\r
35 #else\r
36         #error Assembler has not defined __riscv_xlen\r
37 #endif\r
38 \r
39 #define CONTEXT_SIZE ( 30 * WORD_SIZE )\r
40 \r
41 .global xPortStartFirstTask\r
42 .global vPortTrapHandler\r
43 .extern pxCurrentTCB\r
44 .extern ulPortTrapHandler\r
45 .extern vTaskSwitchContext\r
46 .extern Timer_IRQHandler\r
47 \r
48 \r
49 .extern pullMachineTimerCompareRegister\r
50 .extern pullNextTime\r
51 .extern ulTimerIncrementsForOneTick\r
52 \r
53 \r
54 /*-----------------------------------------------------------*/\r
55 \r
56 .align 8\r
57 xPortStartFirstTask:\r
58 \r
59         la t0, vPortTrapHandler\r
60         csrw mtvec, t0\r
61 \r
62         lw  sp, pxCurrentTCB                    /* Load pxCurrentTCB. */\r
63         lw  sp, 0( sp )                                 /* Read sp from first TCB member. */\r
64 \r
65         lw  x1, 0( sp ) /* Note for starting the scheduler the exception return address is used as the function return address. */\r
66         lw  x5, 2 * WORD_SIZE( sp )             /* t0 */\r
67         lw  x6, 3 * WORD_SIZE( sp )             /* t1 */\r
68         lw  x7, 4 * WORD_SIZE( sp )             /* t2 */\r
69         lw  x8, 5 * WORD_SIZE( sp )             /* s0/fp */\r
70         lw  x9, 6 * WORD_SIZE( sp )             /* s1 */\r
71         lw  x10, 7 * WORD_SIZE( sp )    /* a0 */\r
72         lw  x11, 8 * WORD_SIZE( sp )    /* a1 */\r
73         lw  x12, 9 * WORD_SIZE( sp )    /* a2 */\r
74         lw  x13, 10 * WORD_SIZE( sp )   /* a3 */\r
75         lw  x14, 11 * WORD_SIZE( sp )   /* a4 */\r
76         lw  x15, 12 * WORD_SIZE( sp )   /* a5 */\r
77         lw  x16, 13 * WORD_SIZE( sp )   /* a6 */\r
78         lw  x17, 14 * WORD_SIZE( sp )   /* a7 */\r
79         lw  x18, 15 * WORD_SIZE( sp )   /* s2 */\r
80         lw  x19, 16 * WORD_SIZE( sp )   /* s3 */\r
81         lw  x20, 17 * WORD_SIZE( sp )   /* s4 */\r
82         lw  x21, 18 * WORD_SIZE( sp )   /* s5 */\r
83         lw  x22, 19 * WORD_SIZE( sp )   /* s6 */\r
84         lw  x23, 20 * WORD_SIZE( sp )   /* s7 */\r
85         lw  x24, 21 * WORD_SIZE( sp )   /* s8 */\r
86         lw  x25, 22 * WORD_SIZE( sp )   /* s9 */\r
87         lw  x26, 23 * WORD_SIZE( sp )   /* s10 */\r
88         lw  x27, 24 * WORD_SIZE( sp )   /* s11 */\r
89         lw  x28, 25 * WORD_SIZE( sp )   /* t3 */\r
90         lw  x29, 26 * WORD_SIZE( sp )   /* t4 */\r
91         lw  x30, 27 * WORD_SIZE( sp )   /* t5 */\r
92         lw  x31, 28 * WORD_SIZE( sp )   /* t6 */\r
93         addi    sp, sp, CONTEXT_SIZE\r
94         csrs    mstatus, 8                        /* Enable machine interrupts. */\r
95         ret\r
96 \r
97 /*-----------------------------------------------------------*/\r
98 \r
99 .align 8\r
100 vPortTrapHandler:\r
101         addi sp, sp, -CONTEXT_SIZE\r
102         sw x1, 1 * WORD_SIZE( sp )\r
103         sw x5, 2 * WORD_SIZE( sp )\r
104         sw x6, 3 * WORD_SIZE( sp )\r
105         sw x7, 4 * WORD_SIZE( sp )\r
106         sw x8, 5 * WORD_SIZE( sp )\r
107         sw x9, 6 * WORD_SIZE( sp )\r
108         sw x10, 7 * WORD_SIZE( sp )\r
109         sw x11, 8 * WORD_SIZE( sp )\r
110         sw x12, 9 * WORD_SIZE( sp )\r
111         sw x13, 10 * WORD_SIZE( sp )\r
112         sw x14, 11 * WORD_SIZE( sp )\r
113         sw x15, 12 * WORD_SIZE( sp )\r
114         sw x16, 13 * WORD_SIZE( sp )\r
115         sw x17, 14 * WORD_SIZE( sp )\r
116         sw x18, 15 * WORD_SIZE( sp )\r
117         sw x19, 16 * WORD_SIZE( sp )\r
118         sw x20, 17 * WORD_SIZE( sp )\r
119         sw x21, 18 * WORD_SIZE( sp )\r
120         sw x22, 19 * WORD_SIZE( sp )\r
121         sw x23, 20 * WORD_SIZE( sp )\r
122         sw x24, 21 * WORD_SIZE( sp )\r
123         sw x25, 22 * WORD_SIZE( sp )\r
124         sw x26, 23 * WORD_SIZE( sp )\r
125         sw x27, 24 * WORD_SIZE( sp )\r
126         sw x28, 25 * WORD_SIZE( sp )\r
127         sw x29, 26 * WORD_SIZE( sp )\r
128         sw x30, 27 * WORD_SIZE( sp )\r
129         sw x31, 28 * WORD_SIZE( sp )\r
130 \r
131         csrr t0, mstatus                                                /* Required for MPIE bit. */\r
132         sw t0, 29 * WORD_SIZE( sp )\r
133 \r
134         lw  t0, pxCurrentTCB                                    /* Load pxCurrentTCB. */\r
135         sw  sp, 0( t0 )                                                 /* Write sp to first TCB member. */\r
136 \r
137         csrr a0, mcause\r
138         csrr a1, mepc\r
139         mv a2, sp\r
140 \r
141 test_if_environment_call:\r
142         li t0, 11                                                               /* 11 == environment call when using qemu. */\r
143         bne a0, t0, test_if_timer\r
144         addi a1, a1, 4                                                  /* Synchronous so return to the instruction after the environment call. */\r
145         sw a1, 0( sp )                                                  /* Save updated exception return address. */\r
146 /*_RB_ Does stack need aligning here? */\r
147         jal vTaskSwitchContext\r
148         j processed_source\r
149 \r
150 \r
151 test_if_timer:\r
152         sw a1, 0( sp )                                                  /* Asynch so save unmodified exception return address. */\r
153 \r
154         lui t0, 0x80000\r
155         addi t1,t0, 7                                                   /* 0x80000007 == machine timer interrupt. */\r
156         bne a0, t1, as_yet_unhandled\r
157 \r
158         lw t0, pullMachineTimerCompareRegister  /* Load address of compare register into t0. */\r
159         lw t1, pullNextTime                                     /* Load the address of ullNextTime into t1. */\r
160         lw t2, 0(t1)                                                    /* Load the low word of ullNextTime into t2. */\r
161         lw t3, 4(t1)                                                    /* Load the high word of ullNextTime into t3. */\r
162         sw t2, 0(t0)                                                    /* Store low word of ullNextTime into compare register. */\r
163         sw t3, 4(t0)                                                    /* Store high word of ullNextTime into compare register. */\r
164         lw t0, ulTimerIncrementsForOneTick              /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */\r
165         add t4, t0, t2                                                  /* Add the low word of ullNextTime to the timer increments for one tick (assumes timer increment for one tick fits in 32-bits. */\r
166         sltu t5, t4, t2                                                 /* See if the sum of low words overflowed (what about the zero case?). */\r
167         add t6, t3, t5                                                  /* Add overflow to high word of ullNextTime. */\r
168         sw t4, 0(t1)                                                    /* Store new low word of ullNextTime. */\r
169         sw t6, 4(t1)                                                    /* Store new high word of ullNextTime. */\r
170         jal xTaskIncrementTick\r
171         beqz a0, processed_source                               /* Don't switch context if incrementing tick didn't unblock a task. */\r
172         jal vTaskSwitchContext\r
173         j processed_source\r
174 \r
175 as_yet_unhandled:\r
176         j as_yet_unhandled                                              /* External interrupt? */\r
177 \r
178 processed_source:\r
179         lw  sp, pxCurrentTCB                                    /* Load pxCurrentTCB. */\r
180         lw  sp, 0( sp )                                                 /* Read sp from first TCB member. */\r
181 \r
182         /* Load mret with the address of the next task. */\r
183         lw t0, 0( sp )\r
184         csrw mepc, t0\r
185 \r
186         /* Load mstatus with the interrupt enable bits used by the task. */\r
187         lw  t0, 29 * WORD_SIZE( sp )\r
188         csrw mstatus, t0                                                /* Required for MPIE bit. */\r
189 \r
190         lw  x1, 1 * WORD_SIZE( sp )\r
191         lw  x5, 2 * WORD_SIZE( sp )                             /* t0 */\r
192         lw  x6, 3 * WORD_SIZE( sp )                             /* t1 */\r
193         lw  x7, 4 * WORD_SIZE( sp )                             /* t2 */\r
194         lw  x8, 5 * WORD_SIZE( sp )                             /* s0/fp */\r
195         lw  x9, 6 * WORD_SIZE( sp )                             /* s1 */\r
196         lw  x10, 7 * WORD_SIZE( sp )                    /* a0 */\r
197         lw  x11, 8 * WORD_SIZE( sp )                    /* a1 */\r
198         lw  x12, 9 * WORD_SIZE( sp )                    /* a2 */\r
199         lw  x13, 10 * WORD_SIZE( sp )                   /* a3 */\r
200         lw  x14, 11 * WORD_SIZE( sp )                   /* a4 */\r
201         lw  x15, 12 * WORD_SIZE( sp )                   /* a5 */\r
202         lw  x16, 13 * WORD_SIZE( sp )                   /* a6 */\r
203         lw  x17, 14 * WORD_SIZE( sp )                   /* a7 */\r
204         lw  x18, 15 * WORD_SIZE( sp )                   /* s2 */\r
205         lw  x19, 16 * WORD_SIZE( sp )                   /* s3 */\r
206         lw  x20, 17 * WORD_SIZE( sp )                   /* s4 */\r
207         lw  x21, 18 * WORD_SIZE( sp )                   /* s5 */\r
208         lw  x22, 19 * WORD_SIZE( sp )                   /* s6 */\r
209         lw  x23, 20 * WORD_SIZE( sp )                   /* s7 */\r
210         lw  x24, 21 * WORD_SIZE( sp )                   /* s8 */\r
211         lw  x25, 22 * WORD_SIZE( sp )                   /* s9 */\r
212         lw  x26, 23 * WORD_SIZE( sp )                   /* s10 */\r
213         lw  x27, 24 * WORD_SIZE( sp )                   /* s11 */\r
214         lw  x28, 25 * WORD_SIZE( sp )                   /* t3 */\r
215         lw  x29, 26 * WORD_SIZE( sp )                   /* t4 */\r
216         lw  x30, 27 * WORD_SIZE( sp )                   /* t5 */\r
217         lw  x31, 28 * WORD_SIZE( sp )                   /* t6 */\r
218         addi    sp, sp, CONTEXT_SIZE\r
219 \r
220         mret\r
221 \r
222 \r