1;/*
2; * FreeRTOS Kernel V11.1.0
3; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4; *
5; * SPDX-License-Identifier: MIT
6; *
7; * Permission is hereby granted, free of charge, to any person obtaining a copy of
8; * this software and associated documentation files (the "Software"), to deal in
9; * the Software without restriction, including without limitation the rights to
10; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11; * the Software, and to permit persons to whom the Software is furnished to do so,
12; * subject to the following conditions:
13; *
14; * The above copyright notice and this permission notice shall be included in all
15; * copies or substantial portions of the Software.
16; *
17; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23; *
24; * https://www.FreeRTOS.org
25; * https://github.com/FreeRTOS
26; *
27; */
28; Note: Select the correct include files for the device used by the application.
29#include "FreeRTOSConfig.h"
30;------------------------------------------------------------------------------
31
32; Functions used by scheduler
33;------------------------------------------------------------------------------
34    EXTERN    vTaskSwitchContext
35    EXTERN    xTaskIncrementTick
36
37; Variables used by scheduler
38;------------------------------------------------------------------------------
39    EXTERN    pxCurrentTCB
40    EXTERN    usCriticalNesting
41
42; Functions implemented in this file
43;------------------------------------------------------------------------------
44    PUBLIC    vPortYield
45    PUBLIC    vPortStart
46
47; Security ID definition
48;------------------------------------------------------------------------------
49#define CG_SECURITY0    0FFH
50#define CG_SECURITY1    0FFH
51#define CG_SECURITY2    0FFH
52#define CG_SECURITY3    0FFH
53#define CG_SECURITY4    0FFH
54#define CG_SECURITY5    0FFH
55#define CG_SECURITY6    0FFH
56#define CG_SECURITY7    0FFH
57#define CG_SECURITY8    0FFH
58#define CG_SECURITY9    0FFH
59
60; Tick ISR Prototype
61;------------------------------------------------------------------------------
62        PUBWEAK `??MD_INTTM0EQ0??INTVEC 544`
63        PUBLIC MD_INTTM0EQ0
64
65MD_INTTM0EQ0        SYMBOL "MD_INTTM0EQ0"
66`??MD_INTTM0EQ0??INTVEC 544` SYMBOL "??INTVEC 544", MD_INTTM0EQ0
67
68;------------------------------------------------------------------------------
69;   portSAVE_CONTEXT MACRO
70;   Saves the context of the remaining general purpose registers
71;   and the usCriticalNesting Value of the active Task onto the task stack
72;   saves stack pointer to the TCB
73;------------------------------------------------------------------------------
74portSAVE_CONTEXT MACRO
75#if configDATA_MODE == 1                                        ; Using the Tiny data model
76    prepare {r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30},76,sp ; save general purpose registers
77    sst.w   r19,72[ep]
78    sst.w   r18,68[ep]
79    sst.w   r17,64[ep]
80    sst.w   r16,60[ep]
81    sst.w   r15,56[ep]
82    sst.w   r14,52[ep]
83    sst.w   r13,48[ep]
84    sst.w   r12,44[ep]
85    sst.w   r11,40[ep]
86    sst.w   r10,36[ep]
87    sst.w   r9,32[ep]
88    sst.w   r8,28[ep]
89    sst.w   r7,24[ep]
90    sst.w   r6,20[ep]
91    sst.w   r5,16[ep]
92    sst.w   r4,12[ep]
93#else                                                           ; Using the Small/Large data model
94    prepare {r20,r21,r22,r23,r24,r26,r27,r28,r29,r30},72,sp     ; save general purpose registers
95    sst.w   r19,68[ep]
96    sst.w   r18,64[ep]
97    sst.w   r17,60[ep]
98    sst.w   r16,56[ep]
99    sst.w   r15,52[ep]
100    sst.w   r14,48[ep]
101    sst.w   r13,44[ep]
102    sst.w   r12,40[ep]
103    sst.w   r11,36[ep]
104    sst.w   r10,32[ep]
105    sst.w   r9,28[ep]
106    sst.w   r8,24[ep]
107    sst.w   r7,20[ep]
108    sst.w   r6,16[ep]
109    sst.w   r5,12[ep]
110#endif /* configDATA_MODE */
111    sst.w   r2,8[ep]
112    sst.w   r1,4[ep]
113    MOVHI   hi1(usCriticalNesting),r0,r1                        ; save usCriticalNesting value to stack
114    ld.w    lw1(usCriticalNesting)[r1],r2
115    sst.w   r2,0[ep]
116    MOVHI   hi1(pxCurrentTCB),r0,r1                             ; save SP to top of current TCB
117    ld.w    lw1(pxCurrentTCB)[r1],r2
118    st.w    sp,0[r2]
119    ENDM
120;------------------------------------------------------------------------------
121
122;------------------------------------------------------------------------------
123;   portRESTORE_CONTEXT MACRO
124;   Gets stack pointer from the current TCB
125;   Restores the context of the usCriticalNesting value and general purpose
126;   registers of the selected task from the task stack
127;------------------------------------------------------------------------------
128portRESTORE_CONTEXT MACRO
129    MOVHI   hi1(pxCurrentTCB),r0,r1         ; get Stackpointer address
130    ld.w    lw1(pxCurrentTCB)[r1],sp
131    MOV     sp,r1
132    ld.w    0[r1],sp                        ; load stackpointer
133    MOV     sp,ep                           ; set stack pointer to element pointer
134    sld.w   0[ep],r1                        ; load usCriticalNesting value from stack
135    MOVHI   hi1(usCriticalNesting),r0,r2
136    st.w    r1,lw1(usCriticalNesting)[r2]
137    sld.w   4[ep],r1                        ; restore general purpose registers
138    sld.w   8[ep],r2
139#if configDATA_MODE == 1                    ; Using Tiny data model
140    sld.w   12[ep],r4
141    sld.w   16[ep],r5
142    sld.w   20[ep],r6
143    sld.w   24[ep],r7
144    sld.w   28[ep],r8
145    sld.w   32[ep],r9
146    sld.w   36[ep],r10
147    sld.w   40[ep],r11
148    sld.w   44[ep],r12
149    sld.w   48[ep],r13
150    sld.w   52[ep],r14
151    sld.w   56[ep],r15
152    sld.w   60[ep],r16
153    sld.w   64[ep],r17
154    sld.w   68[ep],r18
155    sld.w   72[ep],r19
156    dispose 76,{r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30}
157#else                                       ; Using Small/Large data model
158    sld.w   12[ep],r5
159    sld.w   16[ep],r6
160    sld.w   20[ep],r7
161    sld.w   24[ep],r8
162    sld.w   28[ep],r9
163    sld.w   32[ep],r10
164    sld.w   36[ep],r11
165    sld.w   40[ep],r12
166    sld.w   44[ep],r13
167    sld.w   48[ep],r14
168    sld.w   52[ep],r15
169    sld.w   56[ep],r16
170    sld.w   60[ep],r17
171    sld.w   64[ep],r18
172    sld.w   68[ep],r19
173    dispose 72,{r20,r21,r22,r23,r24,r26,r27,r28,r29,r30}
174#endif /* configDATA_MODE */
175    ENDM
176;------------------------------------------------------------------------------
177
178;------------------------------------------------------------------------------
179;   Restore the context of the first task that is going to run.
180;
181;   Input:  NONE
182;
183;   Call:   CALL    vPortStart
184;
185;   Output: NONE
186;------------------------------------------------------------------------------
187    RSEG CODE:CODE
188vPortStart:
189    portRESTORE_CONTEXT                     ; Restore the context of whichever task the ...
190    ld.w    0[sp],lp
191    ldsr    lp,5                            ; restore PSW
192    DI
193    ld.w    4[sp],lp                        ; restore LP
194    ld.w    8[sp],lp                        ; restore LP
195    ADD     0x0C,sp                         ; set SP to right position
196    EI
197    jmp     [lp]
198;------------------------------------------------------------------------------
199
200;------------------------------------------------------------------------------
201;   Port Yield function to check for a Task switch in the cooperative and
202;   preemptive mode
203;
204;   Input:  NONE
205;
206;   Call:   CALL    vPortYield
207;
208;   Output: NONE
209;------------------------------------------------------------------------------
210
211    RSEG CODE:CODE
212vPortYield:
213
214    add     -0x0C,sp                          ; prepare stack to save necessary values
215    st.w    lp,8[sp]                        ; store LP to stack
216    stsr    0,r31
217    st.w    lp,4[sp]                        ; store EIPC to stack
218    stsr    1,lp
219    st.w    lp,0[sp]                        ; store EIPSW to stack
220    portSAVE_CONTEXT                    ; Save the context of the current task.
221    jarl    vTaskSwitchContext,lp           ; Call the scheduler.
222    portRESTORE_CONTEXT                 ; Restore the context of whichever task the ...
223                                    ; ... scheduler decided should run.
224    ld.w    0[sp],lp                        ; restore EIPSW from stack
225    ldsr    lp,1
226    ld.w    4[sp],lp                        ; restore EIPC from stack
227    ldsr    lp,0
228    ld.w    8[sp],lp                        ; restore LP from stack
229    add     0x0C,sp                         ; set SP to right position
230
231    RETI
232
233;------------------------------------------------------------------------------
234
235;------------------------------------------------------------------------------
236;   Perform the necessary steps of the Tick Count Increment and Task Switch
237;   depending on the chosen kernel configuration
238;
239;   Input:  NONE
240;
241;   Call:   ISR
242;
243;   Output: NONE
244;------------------------------------------------------------------------------
245#if configUSE_PREEMPTION == 1               ; use preemptive kernel mode
246
247MD_INTTM0EQ0:
248
249    add     -0x0C,sp                          ; prepare stack to save necessary values
250    st.w    lp,8[sp]                        ; store LP to stack
251    stsr    0,r31
252    st.w    lp,4[sp]                        ; store EIPC to stack
253    stsr    1,lp
254    st.w    lp,0[sp]                        ; store EIPSW to stack
255    portSAVE_CONTEXT                    ; Save the context of the current task.
256    jarl    xTaskIncrementTick,lp           ; Call the timer tick function.
257    jarl    vTaskSwitchContext,lp           ; Call the scheduler.
258    portRESTORE_CONTEXT                 ; Restore the context of whichever task the ...
259                                    ; ... scheduler decided should run.
260    ld.w    0[sp],lp                        ; restore EIPSW from stack
261    ldsr    lp,1
262    ld.w    4[sp],lp                        ; restore EIPC from stack
263    ldsr    lp,0
264    ld.w    8[sp],lp                        ; restore LP from stack
265    add     0x0C,sp                         ; set SP to right position
266
267    RETI
268;------------------------------------------------------------------------------
269#else                                       ; use cooperative kernel mode
270
271MD_INTTM0EQ0:
272    prepare {lp,ep},8,sp
273    sst.w   r1,4[ep]
274    sst.w   r5,0[ep]
275    jarl    xTaskIncrementTick,lp           ; Call the timer tick function.
276    sld.w   0[ep],r5
277    sld.w   4[ep],r1
278    dispose 8,{lp,ep}
279    RETI
280#endif /* configUSE_PREEMPTION */
281
282;------------------------------------------------------------------------------
283        COMMON INTVEC:CODE:ROOT(2)
284        ORG 544
285`??MD_INTTM0EQ0??INTVEC 544`:
286        JR MD_INTTM0EQ0
287
288        RSEG NEAR_ID:CONST:SORT:NOROOT(2)
289`?<Initializer for usCriticalNesting>`:
290        DW 10
291
292      COMMON INTVEC:CODE:ROOT(2)
293      ORG 40H
294`??vPortYield??INTVEC 40`:
295        JR vPortYield
296
297;------------------------------------------------------------------------------
298; set microcontroller security ID
299
300      COMMON INTVEC:CODE:ROOT(2)
301      ORG 70H
302`SECUID`:
303      DB CG_SECURITY0
304      DB CG_SECURITY1
305      DB CG_SECURITY2
306      DB CG_SECURITY3
307      DB CG_SECURITY4
308      DB CG_SECURITY5
309      DB CG_SECURITY6
310      DB CG_SECURITY7
311      DB CG_SECURITY8
312      DB CG_SECURITY9
313
314
315; set microcontroller Option bytes
316
317      COMMON INTVEC:CODE:ROOT(2)
318      ORG 122
319`OPTBYTES`:
320      DB 0xFD
321      DB 0xFF
322      DB 0xFF
323      DB 0xFF
324      DB 0xFF
325      DB 0xFF
326
327#if configOCD_USAGE == 1
328
329      COMMON   INTVEC:CODE:ROOT(4)
330      ORG      0x230
331      PUBLIC ROM_INT2
332ROM_INT2:
333      DB 0xff, 0xff, 0xff, 0xff
334      DB 0xff, 0xff, 0xff, 0xff
335      DB 0xff, 0xff, 0xff, 0xff
336      DB 0xff, 0xff, 0xff, 0xff
337
338
339      COMMON   INTVEC:CODE:ROOT(4)
340      ORG      0x60
341      PUBLIC   ROM_INT
342ROM_INT:
343      DB 0xff, 0xff, 0xff, 0xff
344      DB 0xff, 0xff, 0xff, 0xff
345      DB 0xff, 0xff, 0xff, 0xff
346      DB 0xff, 0xff, 0xff, 0xff
347
348#endif /* configOCD_USAGE */
349
350      END
351