1 /*
2  * FreeRTOS Kernel <DEVELOPMENT BRANCH>
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 
29     .extern ulTopOfSystemStack
30     .extern ulInterruptNesting
31 
32 /*-----------------------------------------------------------*/
33 
34 .macro portFREERTOS_INTERRUPT_ENTRY
35 
36     /* Save general purpose registers. */
37     pusha
38 
39     /* If ulInterruptNesting is zero the rest of the task context will need
40     saving and a stack switch might be required. */
41     movl    ulInterruptNesting, %eax
42     test    %eax, %eax
43     jne     2f
44 
45     /* Interrupts are not nested, so save the rest of the task context. */
46     .if configSUPPORT_FPU == 1
47 
48         /* If the task has a buffer allocated to save the FPU context then
49         save the FPU context now. */
50         movl    pucPortTaskFPUContextBuffer, %eax
51         test    %eax, %eax
52         je      1f
53         fnsave  ( %eax ) /* Save FLOP context into ucTempFPUBuffer array. */
54         fwait
55 
56         1:
57         /* Save the address of the FPU context, if any. */
58         push    pucPortTaskFPUContextBuffer
59 
60     .endif /* configSUPPORT_FPU */
61 
62     /* Find the TCB. */
63     movl    pxCurrentTCB, %eax
64 
65     /* Stack location is first item in the TCB. */
66     movl    %esp, (%eax)
67 
68     /* Switch stacks. */
69     movl    ulTopOfSystemStack, %esp
70     movl    %esp, %ebp
71 
72     2:
73     /* Increment nesting count. */
74     add     $1, ulInterruptNesting
75 
76 .endm
77 /*-----------------------------------------------------------*/
78 
79 .macro portINTERRUPT_EPILOGUE
80 
81     cli
82     sub     $1, ulInterruptNesting
83 
84     /* If the nesting has unwound to zero. */
85     movl    ulInterruptNesting, %eax
86     test    %eax, %eax
87     jne     2f
88 
89     /* If a yield was requested then select a new TCB now. */
90     movl    ulPortYieldPending, %eax
91     test    %eax, %eax
92     je      1f
93     movl    $0, ulPortYieldPending
94     call    vTaskSwitchContext
95 
96     1:
97     /* Stack location is first item in the TCB. */
98     movl    pxCurrentTCB, %eax
99     movl    (%eax), %esp
100 
101     .if configSUPPORT_FPU == 1
102 
103         /* Restore address of task's FPU context buffer. */
104         pop     pucPortTaskFPUContextBuffer
105 
106         /* If the task has a buffer allocated in which its FPU context is saved,
107         then restore it now. */
108         movl    pucPortTaskFPUContextBuffer, %eax
109         test    %eax, %eax
110         je      1f
111         frstor  ( %eax )
112         1:
113     .endif
114 
115     2:
116     popa
117 
118 .endm
119 /*-----------------------------------------------------------*/
120 
121 .macro portFREERTOS_INTERRUPT_EXIT
122 
123     portINTERRUPT_EPILOGUE
124     /* EOI. */
125     movl    $0x00, (0xFEE000B0)
126     iret
127 
128 .endm
129