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