]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/RVDS/ARM_CA9/portASM.s
307c1c03b438fdd65ab4f1b4c347ba3d1d5bd586
[freertos] / FreeRTOS / Source / portable / RVDS / ARM_CA9 / portASM.s
1 ;/*\r
2 ; * FreeRTOS Kernel V10.1.0\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 to permit persons to whom the Software is furnished to do so,\r
10 ; * subject to the following conditions:\r
11 ; *\r
12 ; * The above copyright notice and this permission notice shall be included in all\r
13 ; * copies or substantial portions of the Software.\r
14 ; *\r
15 ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16 ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17 ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18 ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19 ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20 ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21 ; *\r
22 ; * http://www.FreeRTOS.org\r
23 ; * http://aws.amazon.com/freertos\r
24 ; *\r
25 ; * 1 tab == 4 spaces!\r
26 ; */\r
27 \r
28         INCLUDE portmacro.inc\r
29 \r
30         IMPORT  vApplicationIRQHandler\r
31         IMPORT  vTaskSwitchContext\r
32         IMPORT  ulPortYieldRequired\r
33         IMPORT  ulPortInterruptNesting\r
34         IMPORT  vTaskSwitchContext\r
35         IMPORT  ulICCIAR\r
36         IMPORT  ulICCEOIR\r
37 \r
38         EXPORT  FreeRTOS_SWI_Handler\r
39         EXPORT  FreeRTOS_IRQ_Handler\r
40         EXPORT  vPortRestoreTaskContext\r
41 \r
42         ARM\r
43         AREA    PORT_ASM, CODE, READONLY\r
44 \r
45 \r
46 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
47 ; SVC handler is used to yield a task.\r
48 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
49 FreeRTOS_SWI_Handler\r
50 \r
51         PRESERVE8\r
52 \r
53         ; Save the context of the current task and select a new task to run.\r
54         portSAVE_CONTEXT\r
55         LDR R0, =vTaskSwitchContext\r
56         BLX     R0\r
57         portRESTORE_CONTEXT\r
58 \r
59 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
60 ; vPortRestoreTaskContext is used to start the scheduler.\r
61 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
62 vPortRestoreTaskContext\r
63         ; Switch to system mode\r
64         CPS             #SYS_MODE\r
65         portRESTORE_CONTEXT\r
66 \r
67 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
68 ; PL390 GIC interrupt handler\r
69 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
70 FreeRTOS_IRQ_Handler\r
71 \r
72         ; Return to the interrupted instruction.\r
73         SUB             lr, lr, #4\r
74 \r
75         ; Push the return address and SPSR\r
76         PUSH    {lr}\r
77         MRS             lr, SPSR\r
78         PUSH    {lr}\r
79 \r
80         ; Change to supervisor mode to allow reentry.\r
81         CPS             #SVC_MODE\r
82 \r
83         ; Push used registers.\r
84         PUSH    {r0-r4, r12}\r
85 \r
86         ; Increment nesting count.  r3 holds the address of ulPortInterruptNesting\r
87         ; for future use.  r1 holds the original ulPortInterruptNesting value for\r
88         ; future use.\r
89         LDR             r3, =ulPortInterruptNesting\r
90         LDR             r1, [r3]\r
91         ADD             r4, r1, #1\r
92         STR             r4, [r3]\r
93 \r
94         ; Read value from the interrupt acknowledge register, which is stored in r0\r
95         ; for future parameter and interrupt clearing use.\r
96         LDR     r2, =ulICCIAR\r
97         LDR             r0, [r2]\r
98 \r
99         ; Ensure bit 2 of the stack pointer is clear.  r2 holds the bit 2 value for\r
100         ; future use.  _RB_ Does this ever actually need to be done provided the\r
101         ; start of the stack is 8-byte aligned?\r
102         MOV             r2, sp\r
103         AND             r2, r2, #4\r
104         SUB             sp, sp, r2\r
105 \r
106         ; Call the interrupt handler.  r4 is pushed to maintain alignment.\r
107         PUSH    {r0-r4, lr}\r
108         LDR             r1, =vApplicationIRQHandler\r
109         BLX             r1\r
110         POP             {r0-r4, lr}\r
111         ADD             sp, sp, r2\r
112 \r
113         CPSID   i\r
114 \r
115         ; Write the value read from ICCIAR to ICCEOIR\r
116         LDR     r4, =ulICCEOIR\r
117         STR             r0, [r4]\r
118 \r
119         ; Restore the old nesting count\r
120         STR             r1, [r3]\r
121 \r
122         ; A context switch is never performed if the nesting count is not 0\r
123         CMP             r1, #0\r
124         BNE             exit_without_switch\r
125 \r
126         ; Did the interrupt request a context switch?  r1 holds the address of\r
127         ; ulPortYieldRequired and r0 the value of ulPortYieldRequired for future\r
128         ; use.\r
129         LDR             r1, =ulPortYieldRequired\r
130         LDR             r0, [r1]\r
131         CMP             r0, #0\r
132         BNE             switch_before_exit\r
133 \r
134 exit_without_switch\r
135         ; No context switch.  Restore used registers, LR_irq and SPSR before\r
136         ; returning.\r
137         POP             {r0-r4, r12}\r
138         CPS             #IRQ_MODE\r
139         POP             {LR}\r
140         MSR             SPSR_cxsf, LR\r
141         POP             {LR}\r
142         MOVS    PC, LR\r
143 \r
144 switch_before_exit\r
145         ; A context swtich is to be performed.  Clear the context switch pending\r
146         ; flag.\r
147         MOV             r0, #0\r
148         STR             r0, [r1]\r
149 \r
150         ; Restore used registers, LR-irq and SPSR before saving the context\r
151         ; to the task stack.\r
152         POP             {r0-r4, r12}\r
153         CPS             #IRQ_MODE\r
154         POP             {LR}\r
155         MSR             SPSR_cxsf, LR\r
156         POP             {LR}\r
157         portSAVE_CONTEXT\r
158 \r
159         ; Call the function that selects the new task to execute.\r
160         ; vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD\r
161         ; instructions, or 8 byte aligned stack allocated data.  LR does not need\r
162         ; saving as a new LR will be loaded by portRESTORE_CONTEXT anyway.\r
163         LDR             r0, =vTaskSwitchContext\r
164         BLX             r0\r
165 \r
166         ; Restore the context of, and branch to, the task selected to execute next.\r
167         portRESTORE_CONTEXT\r
168 \r
169 \r
170         END\r
171 \r
172 \r
173 \r
174 \r