123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- /*
- * FreeRTOS Kernel V10.4.6
- * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * SPDX-License-Identifier: MIT
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * https://www.FreeRTOS.org
- * https://github.com/FreeRTOS
- *
- */
- /* FreeRTOS includes. */
- #include "FreeRTOSConfig.h"
- /* Xilinx library includes. */
- #include "microblaze_exceptions_g.h"
- #include "xparameters.h"
- /* The context is oversized to allow functions called from the ISR to write
- back into the caller stack. */
- #if( XPAR_MICROBLAZE_USE_FPU != 0 )
- #define portCONTEXT_SIZE 136
- #define portMINUS_CONTEXT_SIZE -136
- #else
- #define portCONTEXT_SIZE 132
- #define portMINUS_CONTEXT_SIZE -132
- #endif
- /* Offsets from the stack pointer at which saved registers are placed. */
- #define portR31_OFFSET 4
- #define portR30_OFFSET 8
- #define portR29_OFFSET 12
- #define portR28_OFFSET 16
- #define portR27_OFFSET 20
- #define portR26_OFFSET 24
- #define portR25_OFFSET 28
- #define portR24_OFFSET 32
- #define portR23_OFFSET 36
- #define portR22_OFFSET 40
- #define portR21_OFFSET 44
- #define portR20_OFFSET 48
- #define portR19_OFFSET 52
- #define portR18_OFFSET 56
- #define portR17_OFFSET 60
- #define portR16_OFFSET 64
- #define portR15_OFFSET 68
- #define portR14_OFFSET 72
- #define portR13_OFFSET 76
- #define portR12_OFFSET 80
- #define portR11_OFFSET 84
- #define portR10_OFFSET 88
- #define portR9_OFFSET 92
- #define portR8_OFFSET 96
- #define portR7_OFFSET 100
- #define portR6_OFFSET 104
- #define portR5_OFFSET 108
- #define portR4_OFFSET 112
- #define portR3_OFFSET 116
- #define portR2_OFFSET 120
- #define portCRITICAL_NESTING_OFFSET 124
- #define portMSR_OFFSET 128
- #define portFSR_OFFSET 132
- .extern pxCurrentTCB
- .extern XIntc_DeviceInterruptHandler
- .extern vTaskSwitchContext
- .extern uxCriticalNesting
- .extern pulISRStack
- .extern ulTaskSwitchRequested
- .extern vPortExceptionHandler
- .extern pulStackPointerOnFunctionEntry
- .global _interrupt_handler
- .global VPortYieldASM
- .global vPortStartFirstTask
- .global vPortExceptionHandlerEntry
- .macro portSAVE_CONTEXT
- /* Make room for the context on the stack. */
- addik r1, r1, portMINUS_CONTEXT_SIZE
- /* Stack general registers. */
- swi r31, r1, portR31_OFFSET
- swi r30, r1, portR30_OFFSET
- swi r29, r1, portR29_OFFSET
- swi r28, r1, portR28_OFFSET
- swi r27, r1, portR27_OFFSET
- swi r26, r1, portR26_OFFSET
- swi r25, r1, portR25_OFFSET
- swi r24, r1, portR24_OFFSET
- swi r23, r1, portR23_OFFSET
- swi r22, r1, portR22_OFFSET
- swi r21, r1, portR21_OFFSET
- swi r20, r1, portR20_OFFSET
- swi r19, r1, portR19_OFFSET
- swi r18, r1, portR18_OFFSET
- swi r17, r1, portR17_OFFSET
- swi r16, r1, portR16_OFFSET
- swi r15, r1, portR15_OFFSET
- /* R14 is saved later as it needs adjustment if a yield is performed. */
- swi r13, r1, portR13_OFFSET
- swi r12, r1, portR12_OFFSET
- swi r11, r1, portR11_OFFSET
- swi r10, r1, portR10_OFFSET
- swi r9, r1, portR9_OFFSET
- swi r8, r1, portR8_OFFSET
- swi r7, r1, portR7_OFFSET
- swi r6, r1, portR6_OFFSET
- swi r5, r1, portR5_OFFSET
- swi r4, r1, portR4_OFFSET
- swi r3, r1, portR3_OFFSET
- swi r2, r1, portR2_OFFSET
- /* Stack the critical section nesting value. */
- lwi r18, r0, uxCriticalNesting
- swi r18, r1, portCRITICAL_NESTING_OFFSET
- /* Stack MSR. */
- mfs r18, rmsr
- swi r18, r1, portMSR_OFFSET
- #if( XPAR_MICROBLAZE_USE_FPU != 0 )
- /* Stack FSR. */
- mfs r18, rfsr
- swi r18, r1, portFSR_OFFSET
- #endif
- /* Save the top of stack value to the TCB. */
- lwi r3, r0, pxCurrentTCB
- sw r1, r0, r3
- .endm
- .macro portRESTORE_CONTEXT
- /* Load the top of stack value from the TCB. */
- lwi r18, r0, pxCurrentTCB
- lw r1, r0, r18
- /* Restore the general registers. */
- lwi r31, r1, portR31_OFFSET
- lwi r30, r1, portR30_OFFSET
- lwi r29, r1, portR29_OFFSET
- lwi r28, r1, portR28_OFFSET
- lwi r27, r1, portR27_OFFSET
- lwi r26, r1, portR26_OFFSET
- lwi r25, r1, portR25_OFFSET
- lwi r24, r1, portR24_OFFSET
- lwi r23, r1, portR23_OFFSET
- lwi r22, r1, portR22_OFFSET
- lwi r21, r1, portR21_OFFSET
- lwi r20, r1, portR20_OFFSET
- lwi r19, r1, portR19_OFFSET
- lwi r17, r1, portR17_OFFSET
- lwi r16, r1, portR16_OFFSET
- lwi r15, r1, portR15_OFFSET
- lwi r14, r1, portR14_OFFSET
- lwi r13, r1, portR13_OFFSET
- lwi r12, r1, portR12_OFFSET
- lwi r11, r1, portR11_OFFSET
- lwi r10, r1, portR10_OFFSET
- lwi r9, r1, portR9_OFFSET
- lwi r8, r1, portR8_OFFSET
- lwi r7, r1, portR7_OFFSET
- lwi r6, r1, portR6_OFFSET
- lwi r5, r1, portR5_OFFSET
- lwi r4, r1, portR4_OFFSET
- lwi r3, r1, portR3_OFFSET
- lwi r2, r1, portR2_OFFSET
- /* Reload the rmsr from the stack. */
- lwi r18, r1, portMSR_OFFSET
- mts rmsr, r18
- #if( XPAR_MICROBLAZE_USE_FPU != 0 )
- /* Reload the FSR from the stack. */
- lwi r18, r1, portFSR_OFFSET
- mts rfsr, r18
- #endif
- /* Load the critical nesting value. */
- lwi r18, r1, portCRITICAL_NESTING_OFFSET
- swi r18, r0, uxCriticalNesting
- /* Test the critical nesting value. If it is non zero then the task last
- exited the running state using a yield. If it is zero, then the task
- last exited the running state through an interrupt. */
- xori r18, r18, 0
- bnei r18, exit_from_yield
- /* r18 was being used as a temporary. Now restore its true value from the
- stack. */
- lwi r18, r1, portR18_OFFSET
- /* Remove the stack frame. */
- addik r1, r1, portCONTEXT_SIZE
- /* Return using rtid so interrupts are re-enabled as this function is
- exited. */
- rtid r14, 0
- or r0, r0, r0
- .endm
- /* This function is used to exit portRESTORE_CONTEXT() if the task being
- returned to last left the Running state by calling taskYIELD() (rather than
- being preempted by an interrupt). */
- .text
- .align 4
- exit_from_yield:
- /* r18 was being used as a temporary. Now restore its true value from the
- stack. */
- lwi r18, r1, portR18_OFFSET
- /* Remove the stack frame. */
- addik r1, r1, portCONTEXT_SIZE
- /* Return to the task. */
- rtsd r14, 0
- or r0, r0, r0
- .text
- .align 4
- _interrupt_handler:
- portSAVE_CONTEXT
- /* Stack the return address. */
- swi r14, r1, portR14_OFFSET
- /* Switch to the ISR stack. */
- lwi r1, r0, pulISRStack
- /* The parameter to the interrupt handler. */
- ori r5, r0, configINTERRUPT_CONTROLLER_TO_USE
- /* Execute any pending interrupts. */
- bralid r15, XIntc_DeviceInterruptHandler
- or r0, r0, r0
- /* See if a new task should be selected to execute. */
- lwi r18, r0, ulTaskSwitchRequested
- or r18, r18, r0
- /* If ulTaskSwitchRequested is already zero, then jump straight to
- restoring the task that is already in the Running state. */
- beqi r18, task_switch_not_requested
- /* Set ulTaskSwitchRequested back to zero as a task switch is about to be
- performed. */
- swi r0, r0, ulTaskSwitchRequested
- /* ulTaskSwitchRequested was not 0 when tested. Select the next task to
- execute. */
- bralid r15, vTaskSwitchContext
- or r0, r0, r0
- task_switch_not_requested:
- /* Restore the context of the next task scheduled to execute. */
- portRESTORE_CONTEXT
- .text
- .align 4
- VPortYieldASM:
- portSAVE_CONTEXT
- /* Modify the return address so a return is done to the instruction after
- the call to VPortYieldASM. */
- addi r14, r14, 8
- swi r14, r1, portR14_OFFSET
- /* Switch to use the ISR stack. */
- lwi r1, r0, pulISRStack
- /* Select the next task to execute. */
- bralid r15, vTaskSwitchContext
- or r0, r0, r0
- /* Restore the context of the next task scheduled to execute. */
- portRESTORE_CONTEXT
- .text
- .align 4
- vPortStartFirstTask:
- portRESTORE_CONTEXT
- #if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
- .text
- .align 4
- vPortExceptionHandlerEntry:
- /* Take a copy of the stack pointer before vPortExecptionHandler is called,
- storing its value prior to the function stack frame being created. */
- swi r1, r0, pulStackPointerOnFunctionEntry
- bralid r15, vPortExceptionHandler
- or r0, r0, r0
- #endif /* ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 ) */
|