mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-05-19 11:39:04 -04:00
* Add XMOS XCore ports Some minor modifications are also made to the kernel to support the XCore compiler's automatic stack size calculation. * Update kernel to support SMP The XMOS XCore ports are also updated to support SMP. * Fix compiler warnings in xcore ports The port set and clear interrupt mask from ISR macros were removed from the ports so that the default macros found in FreeRTOS.h are used instead. The default macros do not result in warnings when they are used. * Remove inline function from timers.h Inline function converted to macro. This should now build when optimizations are off and inlining is disabled. * Fix compiler warnings in xcore ports and tasks.c * fixed documentation for ulTaskNotifyTake() and ulTaskNotifyTakeIndexed() * spelling fixes for tasks.c Co-authored-by: Michael Bruno <mikeb@xmos.com>
329 lines
8.6 KiB
ArmAsm
329 lines
8.6 KiB
ArmAsm
/*
|
|
* FreeRTOS Kernel V10.4.3
|
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
*
|
|
* 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
|
|
*
|
|
* 1 tab == 4 spaces!
|
|
*/
|
|
|
|
/* 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 ) */
|
|
|
|
|
|
|