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