Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FreeRTOS/FreeRTOS-Kernel-Partner-Supported-Ports.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoranoop-rk97 <118251858+anoop-rk97@users.noreply.github.com>2022-11-21 16:57:58 +0300
committerGitHub <noreply@github.com>2022-11-21 16:57:58 +0300
commita21d142d3c615181cedc8f164b8d3aedb66d7894 (patch)
tree00ba874f4dfc7a38bf38bab91100c655b1f70d0d
parent3f9c99a682c5c796bb7eb89fd9c4385688fce27a (diff)
Add ARM A53 SMP kernel port for TI-Sitara-AM64x device. (#7)
Signed-off-by: Anoop <anoop.rk@ti.com> Signed-off-by: Anoop <anoop.rk@ti.com>
-rw-r--r--TI/CORTEX_A53_64-BIT_TI_AM64_SMP/port.c401
-rw-r--r--TI/CORTEX_A53_64-BIT_TI_AM64_SMP/portASM.S602
-rw-r--r--TI/CORTEX_A53_64-BIT_TI_AM64_SMP/portmacro.h294
3 files changed, 1297 insertions, 0 deletions
diff --git a/TI/CORTEX_A53_64-BIT_TI_AM64_SMP/port.c b/TI/CORTEX_A53_64-BIT_TI_AM64_SMP/port.c
new file mode 100644
index 0000000..5a84b6e
--- /dev/null
+++ b/TI/CORTEX_A53_64-BIT_TI_AM64_SMP/port.c
@@ -0,0 +1,401 @@
+/*
+ * FreeRTOS Kernel <DEVELOPMENT BRANCH>
+ * 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
+ *
+ */
+/*
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Standard includes. */
+#include <stdlib.h>
+
+/* Scheduler includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+#include <kernel/dpl/ClockP.h>
+#include <drivers/hw_include/cslr.h>
+
+#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
+ /* Check the configuration. */
+ #if( configMAX_PRIORITIES > 32 )
+ #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
+ #endif
+#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
+
+/* A critical section is exited when the critical section nesting count reaches
+this value. */
+#define portNO_CRITICAL_NESTING ( ( size_t ) 0 )
+
+/* Tasks are not created with a floating point context, but can be given a
+floating point context after they have been created. A variable is stored as
+part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
+does not have an FPU context, or any other value if the task does have an FPU
+context. */
+#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
+
+/* Constants required to setup the initial task context. */
+#define portSP_EL0 ( ( StackType_t ) 0x00 )
+#define portEL1 ( ( StackType_t ) 0x04 )
+#define portINITIAL_PSTATE ( portEL1 | portSP_EL0 )
+
+/* Masks all bits in the APSR other than the mode bits. */
+#define portAPSR_MODE_BITS_MASK ( 0x0C )
+
+/*
+ * Starts the first task executing. This function is necessarily written in
+ * assembly code so is implemented in portASM.s.
+ */
+extern void vPortRestoreTaskContext( void );
+
+/* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero
+then floating point context must be saved and restored for the task. */
+volatile uint64_t ullPortTaskHasFPUContext[configNUM_CORES] = {pdFALSE};
+
+/* Set to 1 to pend a context switch from an ISR. */
+uint64_t ullPortYieldRequired[configNUM_CORES] = { pdFALSE };
+
+/* Counts the interrupt nesting depth. A context switch is only performed if
+if the nesting depth is 0. */
+uint64_t ullPortInterruptNesting[configNUM_CORES] = { 0 };
+
+/* flag to control tick ISR handling, this is made true just before schedular start */
+volatile uint64_t ullPortSchedularRunning = pdFALSE;
+
+#define portPRIORITY_SHIFT 4
+__attribute__(( used )) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
+
+/*
+ * See header file for description.
+ */
+StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
+{
+ /* Setup the initial stack of the task. The stack is set exactly as
+ expected by the portRESTORE_CONTEXT() macro. */
+
+ /* First all the general purpose registers. */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x0101010101010101ULL; /* R1 */
+ pxTopOfStack--;
+ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x0303030303030303ULL; /* R3 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x0202020202020202ULL; /* R2 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x0505050505050505ULL; /* R5 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x0404040404040404ULL; /* R4 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x0707070707070707ULL; /* R7 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x0606060606060606ULL; /* R6 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x0909090909090909ULL; /* R9 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x0808080808080808ULL; /* R8 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x1111111111111111ULL; /* R11 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x1010101010101010ULL; /* R10 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x1313131313131313ULL; /* R13 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x1212121212121212ULL; /* R12 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x1515151515151515ULL; /* R15 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x1414141414141414ULL; /* R14 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x1717171717171717ULL; /* R17 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x1616161616161616ULL; /* R16 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x1919191919191919ULL; /* R19 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x1818181818181818ULL; /* R18 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x2121212121212121ULL; /* R21 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x2020202020202020ULL; /* R20 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x2323232323232323ULL; /* R23 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x2222222222222222ULL; /* R22 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x2525252525252525ULL; /* R25 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x2424242424242424ULL; /* R24 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x2727272727272727ULL; /* R27 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x2626262626262626ULL; /* R26 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x2929292929292929ULL; /* R29 */
+ pxTopOfStack--;
+ *pxTopOfStack = 0x2828282828282828ULL; /* R28 */
+ pxTopOfStack--;
+ *pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */
+ pxTopOfStack--;
+ *pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */
+ pxTopOfStack--;
+
+ *pxTopOfStack = portINITIAL_PSTATE;
+ pxTopOfStack--;
+
+ *pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */
+ pxTopOfStack--;
+
+ /* The task will start with a critical nesting count of 0 as interrupts are
+ enabled. */
+ *pxTopOfStack = portNO_CRITICAL_NESTING;
+ pxTopOfStack--;
+
+ /* The task will start without a floating point context. A task that uses
+ the floating point hardware must call vPortTaskUsesFPU() before executing
+ any floating point instructions. */
+ *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
+
+ return pxTopOfStack;
+}
+
+BaseType_t xPortStartScheduler( void )
+{
+ uint32_t ulAPSR;
+
+ __asm volatile ( "MRS %0, CurrentEL" : "=r" ( ulAPSR ) );
+ ulAPSR &= portAPSR_MODE_BITS_MASK;
+
+ configASSERT( ulAPSR == portEL1 );
+ if( ulAPSR == portEL1 )
+ {
+ /* Interrupts are turned off in the CPU itself to ensure a tick does
+ not execute while the scheduler is being started. Interrupts are
+ automatically turned back on in the CPU when the first task starts
+ executing. */
+ portDISABLE_INTERRUPTS();
+
+ if (0 == portGET_CORE_ID())
+ {
+ ullPortSchedularRunning = pdTRUE;
+ }
+
+ /* Start the first task executing. */
+ vPortRestoreTaskContext();
+ }
+
+ return 0;
+}
+
+void vPortEndScheduler( void )
+{
+ /* Not implemented in ports where there is nothing to return to.
+ Artificially force an assert. */
+ configASSERT( 0 );
+}
+
+void vPortTimerTickHandler()
+{
+ if( ullPortSchedularRunning == pdTRUE )
+ {
+ /* Increment the RTOS tick. */
+ if( xTaskIncrementTick() != pdFALSE )
+ {
+ ullPortYieldRequired[portGET_CORE_ID()] = pdTRUE;
+ }
+ }
+}
+
+void vPortTaskUsesFPU( void )
+{
+ /* A task is registering the fact that it needs an FPU context. Set the
+ FPU flag (which is saved as part of the task context). */
+ ullPortTaskHasFPUContext[portGET_CORE_ID()] = pdTRUE;
+
+ /* Consider initialising the FPSR here - but probably not necessary in
+ AArch64. */
+}
+
+/* configCHECK_FOR_STACK_OVERFLOW is set to 1, so the application must provide an
+ * implementation of vApplicationStackOverflowHook()
+ */
+void vApplicationStackOverflowHook( TaskHandle_t xTask,
+ char * pcTaskName )
+{
+ DebugP_logError("[FreeRTOS] Stack overflow detected for task [%s]", pcTaskName);
+ DebugP_assertNoLog(0);
+}
+
+static StaticTask_t xIdleTaskTCB;
+static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
+/* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an
+ * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
+ * used by the Idle task.
+ */
+void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer,
+ StackType_t **ppxIdleTaskStackBuffer,
+ uint32_t *pulIdleTaskStackSize )
+{
+ /* Pass out a pointer to the StaticTask_t structure in which the Idle task’s
+ * state will be stored.
+ */
+ *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
+
+ /* Pass out the array that will be used as the Idle task’s stack. */
+ *ppxIdleTaskStackBuffer = uxIdleTaskStack;
+
+ /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
+ * Note that, as the array is necessarily of type StackType_t,
+ * configMINIMAL_STACK_SIZE is specified in words, not bytes.
+ */
+ *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
+}
+
+static StaticTask_t xTimerTaskTCB;
+static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
+/* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
+ * application must provide an implementation of vApplicationGetTimerTaskMemory()
+ * to provide the memory that is used by the Timer service task.
+ */
+void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer,
+ StackType_t **ppxTimerTaskStackBuffer,
+ uint32_t *pulTimerTaskStackSize )
+{
+ /* Pass out a pointer to the StaticTask_t structure in which the Timer
+ * task’s state will be stored.
+ */
+ *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
+
+ /* Pass out the array that will be used as the Timer task’s stack. */
+ *ppxTimerTaskStackBuffer = uxTimerTaskStack;
+
+ /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
+ * Note that, as the array is necessarily of type StackType_t,
+ * configTIMER_TASK_STACK_DEPTH is specified in words, not bytes.
+ */
+ *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
+}
+
+/* This function is called when configUSE_IDLE_HOOK is 1 in FreeRTOSConfig.h */
+void vApplicationIdleHook( void )
+{
+ void vApplicationLoadHook();
+
+ vApplicationLoadHook();
+
+ __asm__ volatile ("wfi");
+}
+
+/* This function is called when configUSE_MINIMAL_IDLE_HOOK is 1 in FreeRTOSConfig.h */
+void vApplicationMinimalIdleHook( void )
+{
+ void vApplicationLoadHook();
+
+ vApplicationLoadHook();
+
+ __asm__ volatile ("wfi");
+}
+
+/* initialize high resolution timer for CPU and task load calculation */
+void vPortConfigTimerForRunTimeStats()
+{
+ /* we assume clock is initialized before the schedular is started */
+}
+
+/* return current counter value of high speed counter in units of usecs */
+uint32_t uiPortGetRunTimeCounterValue()
+{
+ uint64_t timeInUsecs = ClockP_getTimeUsec();
+
+ /* note, there is no overflow protection for this 32b value in FreeRTOS
+ *
+ * This value will overflow in
+ * ((0xFFFFFFFF)/(1000000*60)) minutes ~ 71 minutes
+ *
+ * We call vApplicationLoadHook() in idle loop to accumlate the task load into a 64b value.
+ * The implementation of vApplicationLoadHook() is in source\kernel\freertos\dpl\common\TaskP_freertos.c
+ */
+ return (uint32_t)(timeInUsecs);
+}
+
+int32_t Signal_coreIntr( CSL_gic500_gicrRegs *pGic500GicrRegs, uint32_t coreId, uint32_t intrNum )
+{
+ if ( coreId < configNUM_CORES )
+ {
+ if ( intrNum < HWIP_GICD_SGI_PPI_INTR_ID_MAX )
+ {
+ uint32_t mask = 1 << intrNum;
+ pGic500GicrRegs->CORE[coreId].SGI_PPI.ISPENDR0 = mask;
+ }
+ }
+
+ __asm("dsb sy");
+
+ return SystemP_SUCCESS;
+}
+
+/* Read 64b value shared between cores */
+uint64_t Get_64(volatile uint64_t* x)
+{
+ __asm("dsb sy");
+ return *x;
+}
+
+/* Write 64b value shared between cores */
+void Set_64(volatile uint64_t* x, uint64_t value)
+{
+ *x = value;
+ __asm("dsb sy");
+}
+
diff --git a/TI/CORTEX_A53_64-BIT_TI_AM64_SMP/portASM.S b/TI/CORTEX_A53_64-BIT_TI_AM64_SMP/portASM.S
new file mode 100644
index 0000000..266fd97
--- /dev/null
+++ b/TI/CORTEX_A53_64-BIT_TI_AM64_SMP/portASM.S
@@ -0,0 +1,602 @@
+/*
+ * FreeRTOS Kernel <DEVELOPMENT BRANCH>
+ * 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
+ *
+ */
+/*
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ .text
+
+ /* Variables and functions. */
+ .extern vTaskSwitchContext
+ .extern HwiP_intrHandler
+ .extern ullPortInterruptNesting
+ .extern ullPortTaskHasFPUContext
+ .extern ullPortYieldRequired
+
+ .global HwiP_IRQ_Handler
+ .global HwiP_SVC_Handler
+ .global vPortRestoreTaskContext
+ .global HwiP_defaultExcHandler
+ .global HwiP_abortHandler
+
+.macro PUSH_ALL_CPU_REGS stackPtr
+ stp x0, x1, [\stackPtr, #-16]!
+ stp x2, x3, [\stackPtr, #-16]!
+ stp x4, x5, [\stackPtr, #-16]!
+ stp x6, x7, [\stackPtr, #-16]!
+ stp x8, x9, [\stackPtr, #-16]!
+ stp x10, x11, [\stackPtr, #-16]!
+ stp x12, x13, [\stackPtr, #-16]!
+ stp x14, x15, [\stackPtr, #-16]!
+ stp x16, x17, [\stackPtr, #-16]!
+ stp x18, x19, [\stackPtr, #-16]!
+ stp x20, x21, [\stackPtr, #-16]!
+ stp x22, x23, [\stackPtr, #-16]!
+ stp x24, x25, [\stackPtr, #-16]!
+ stp x26, x27, [\stackPtr, #-16]!
+ stp x28, x29, [\stackPtr, #-16]!
+ stp x30, xzr, [\stackPtr, #-16]!
+.endm
+
+.macro POP_ALL_CPU_REGS stackPtr
+ LDP X30, XZR, [\stackPtr], #0x10
+ LDP X28, X29, [\stackPtr], #0x10
+ LDP X26, X27, [\stackPtr], #0x10
+ LDP X24, X25, [\stackPtr], #0x10
+ LDP X22, X23, [\stackPtr], #0x10
+ LDP X20, X21, [\stackPtr], #0x10
+ LDP X18, X19, [\stackPtr], #0x10
+ LDP X16, X17, [\stackPtr], #0x10
+ LDP X14, X15, [\stackPtr], #0x10
+ LDP X12, X13, [\stackPtr], #0x10
+ LDP X10, X11, [\stackPtr], #0x10
+ LDP X8, X9, [\stackPtr], #0x10
+ LDP X6, X7, [\stackPtr], #0x10
+ LDP X4, X5, [\stackPtr], #0x10
+ LDP X2, X3, [\stackPtr], #0x10
+ LDP X0, X1, [\stackPtr], #0x10
+.endm
+
+.macro PUSH_CALLER_SAVE_CPU_REGS stackPtr
+ stp x0, x1, [\stackPtr, #-16]!
+ stp x2, x3, [\stackPtr, #-16]!
+ stp x4, x5, [\stackPtr, #-16]!
+ stp x6, x7, [\stackPtr, #-16]!
+ stp x8, x9, [\stackPtr, #-16]!
+ stp x10, x11, [\stackPtr, #-16]!
+ stp x12, x13, [\stackPtr, #-16]!
+ stp x14, x15, [\stackPtr, #-16]!
+ stp x16, x17, [\stackPtr, #-16]!
+ stp x18, x19, [\stackPtr, #-16]!
+ stp x29, x30, [\stackPtr, #-16]!
+.endm
+
+.macro POP_CALLER_SAVE_CPU_REGS stackPtr
+ ldp x29, x30, [\stackPtr], #16
+ ldp x18, x19, [\stackPtr], #16
+ ldp x16, x17, [\stackPtr], #16
+ ldp x14, x15, [\stackPtr], #16
+ ldp x12, x13, [\stackPtr], #16
+ ldp x10, x11, [\stackPtr], #16
+ ldp x8, x9, [\stackPtr], #16
+ ldp x6, x7, [\stackPtr], #16
+ ldp x4, x5, [\stackPtr], #16
+ ldp x2, x3, [\stackPtr], #16
+ ldp x0, x1, [\stackPtr], #16
+.endm
+
+.macro PUSH_CALLER_SAVE_FPU_REGS stackPtr
+ stp q0, q1, [\stackPtr, #-32]!
+ stp q2, q3, [\stackPtr, #-32]!
+ stp q4, q5, [\stackPtr, #-32]!
+ stp q6, q7, [\stackPtr, #-32]!
+ stp q8, q9, [\stackPtr, #-32]!
+ stp q10, q11, [\stackPtr, #-32]!
+ stp q12, q13, [\stackPtr, #-32]!
+ stp q14, q15, [\stackPtr, #-32]!
+ stp q16, q17, [\stackPtr, #-32]!
+ stp q18, q19, [\stackPtr, #-32]!
+ stp q20, q21, [\stackPtr, #-32]!
+ stp q22, q23, [\stackPtr, #-32]!
+ stp q24, q25, [\stackPtr, #-32]!
+ stp q26, q27, [\stackPtr, #-32]!
+ stp q28, q29, [\stackPtr, #-32]!
+ stp q30, q31, [\stackPtr, #-32]!
+.endm
+
+.macro POP_CALLER_SAVE_FPU_REGS stackPtr
+ ldp q30, q31, [\stackPtr], #32
+ ldp q28, q29, [\stackPtr], #32
+ ldp q26, q27, [\stackPtr], #32
+ ldp q24, q25, [\stackPtr], #32
+ ldp q22, q23, [\stackPtr], #32
+ ldp q20, q21, [\stackPtr], #32
+ ldp q18, q19, [\stackPtr], #32
+ ldp q16, q17, [\stackPtr], #32
+ ldp q14, q15, [\stackPtr], #32
+ ldp q12, q13, [\stackPtr], #32
+ ldp q10, q11, [\stackPtr], #32
+ ldp q8, q9, [\stackPtr], #32
+ ldp q6, q7, [\stackPtr], #32
+ ldp q4, q5, [\stackPtr], #32
+ ldp q2, q3, [\stackPtr], #32
+ ldp q0, q1, [\stackPtr], #32
+.endm
+
+
+.macro portSAVE_CONTEXT
+
+ /* Switch to use the EL0 stack pointer. */
+ MSR SPSEL, #0
+
+ /* Save the entire context. */
+ PUSH_ALL_CPU_REGS SP
+
+ /* Save the SPSR. */
+ MRS X3, SPSR_EL1
+ MRS X2, ELR_EL1
+
+ STP X2, X3, [SP, #-0x10]!
+
+ /* Get coreId to X1 */
+ MRS X1, MPIDR_EL1
+ AND X1, X1, #0xff
+ LDR X0, ullPortTaskHasFPUContextConst
+ CMP X1, #0
+ BEQ 3f
+ ADD X0, X0, #8
+3:
+
+ /* Save the FPU context indicator. */
+ LDR X2, [X0]
+
+ /* Save the FPU context, if any (32 128-bit registers). */
+ CMP X2, #0
+ B.EQ 1f
+ PUSH_CALLER_SAVE_FPU_REGS SP
+
+1:
+ /* Store the FPU context indicator. */
+ STR x2, [SP, #-0x10]!
+
+ LDR X0, pxCurrentTCBConst
+
+ /* Get coreId and choose the corresponding index for core in pxCurrentTCB */
+ MRS X1, MPIDR_EL1
+ AND X1, X1, #0xff
+ CMP X1, #0
+ B.EQ 2f
+ ADD X0, X0, #8
+
+2:
+ LDR X1, [X0]
+ MOV X0, SP /* Move SP into X0 for saving. */
+ STR X0, [X1]
+
+ /* Switch to use the ELx stack pointer. */
+ MSR SPSEL, #1
+
+.endm
+
+; /**********************************************************************/
+
+.macro portRESTORE_CONTEXT
+
+ /* Switch to use the EL0 stack pointer. */
+ MSR SPSEL, #0
+
+ /* Set the SP to point to the stack of the task being restored. */
+ LDR X0, pxCurrentTCBConst
+
+ /* Get coreId and choose the corresponding index for core in pxCurrentTCB */
+ MRS X1, MPIDR_EL1
+ AND X1, X1, #0xff
+ CMP X1, #0
+ B.EQ 2f
+ ADD X0, X0, #8
+
+2:
+ LDR X1, [X0]
+ LDR X0, [X1]
+ MOV SP, X0
+
+ LDR X2, [SP], #0x10 /* FPU context. */
+
+ /* Set the PMR register to be correct for the current critical nesting
+ depth. */
+ MOV X1, #255 /* X1 holds the unmask value. */
+
+ MSR s3_0_c4_c6_0, X1 /* Write the mask value to ICCPMR. s3_0_c4_c6_0 is ICC_PMR_EL1. */
+ DSB SY /* _RB_Barriers probably not required here. */
+ ISB SY
+
+ /* Get coreId */
+ MRS X1, MPIDR_EL1
+ AND X1, X1, #0xff
+ LDR X0, ullPortTaskHasFPUContextConst
+ BEQ 3f
+ ADD X0, X0, #8
+3:
+
+ /* Restore the FPU context indicator. */
+ STR X2, [X0]
+
+ /* Restore the FPU context, if any. */
+ CMP X2, #0
+ B.EQ 1f
+ POP_CALLER_SAVE_FPU_REGS SP
+1:
+ LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */
+
+ /* Restore the SPSR. */
+ MSR SPSR_EL1, X3
+ /* Restore the ELR. */
+ MSR ELR_EL1, X2
+
+ POP_ALL_CPU_REGS SP
+
+ /* Switch to use the ELx stack pointer. _RB_ Might not be required. */
+ MSR SPSEL, #1
+
+ ERET
+
+.endm
+
+.macro VECTOR_ENTRY name
+ .align 7
+\name:
+.endm
+
+ .global HwiP_gicv3Vectors
+ .section .vecs, "ax"
+ .align 11
+HwiP_gicv3Vectors:
+
+/*
+ *************************************************************************
+ * Exception from currentEL, using SP0
+ *************************************************************************
+ */
+VECTOR_ENTRY el1SyncSP0
+ B HwiP_SVC_Handler
+
+VECTOR_ENTRY el1IrqSP0
+ B HwiP_IRQ_Handler
+
+VECTOR_ENTRY el1FiqSP0
+ b el1FiqSP0
+
+VECTOR_ENTRY el1SErrorSP0
+ PUSH_ALL_CPU_REGS sp /* save all CPU regs */
+ mrs x0, sp_el0
+ mrs x1, elr_el1
+ mrs x2, spsr_el1
+ mrs x3, esr_el1
+ stp x0, x1, [sp, #-16]! /* save sp & elr */
+ stp x2, x3, [sp, #-16]! /* save spsr and esr */
+ mov x0, sp
+ mov x1, #1
+ ldr x2, =HwiP_defaultExcHandler
+ br x2
+
+/*
+ *************************************************************************
+ * Exception from currentEL, using SPx
+ *************************************************************************
+ */
+VECTOR_ENTRY el1SyncSPx
+ B HwiP_SVC_Handler
+
+VECTOR_ENTRY el1IrqSPx
+ B HwiP_IRQ_Handler
+
+VECTOR_ENTRY el1FiqSPx
+ b el1FiqSPx
+
+VECTOR_ENTRY el1SErrorSPx
+ PUSH_ALL_CPU_REGS sp /* save all CPU regs */
+ add x0, sp, #256 /* compute original SP */
+ mrs x1, elr_el1
+ mrs x2, spsr_el1
+ mrs x3, esr_el1
+ stp x0, x1, [sp, #-16]! /* save sp & elr */
+ stp x2, x3, [sp, #-16]! /* save spsr and esr */
+ mov x0, sp
+ mov x1, #1
+ ldr x2, =HwiP_defaultExcHandler
+ br x2
+
+/*
+ *************************************************************************
+ * Exception from lowerEL, all lowerEL using Aarch64
+ *************************************************************************
+ */
+VECTOR_ENTRY el0SyncAarch64
+ b el0SyncAarch64
+
+VECTOR_ENTRY el0IrqAarch64
+ b el0IrqAarch64
+
+VECTOR_ENTRY el0FiqAarch64
+ b el0FiqAarch64
+
+VECTOR_ENTRY el0SErrorAarch64
+ b el0SErrorAarch64
+
+/*
+ *************************************************************************
+ * Exception from lowerEL, all lowerEL using Aarch32
+ *************************************************************************
+ */
+VECTOR_ENTRY el0SyncAarch32
+ b el0SyncAarch32
+
+VECTOR_ENTRY el0IrqAarch32
+ b el0IrqAarch32
+
+VECTOR_ENTRY el0FiqAarch32
+ b el0FiqAarch32
+
+VECTOR_ENTRY el0SErrorAarch32
+ b el0SErrorAarch32
+
+
+/******************************************************************************
+ * vPortRestoreTaskContext is used to start the scheduler.
+ *****************************************************************************/
+.align 8
+.type vPortRestoreTaskContext, %function
+vPortRestoreTaskContext:
+ DSB SY
+ ISB SY
+ /* Start the first task. */
+ portRESTORE_CONTEXT
+
+/******************************************************************************
+ * handles SVC entry and exit.
+ *****************************************************************************/
+.align 8
+.type HwiP_SVC_Handler, %function
+HwiP_SVC_Handler:
+ /* Save the context of the current task and select a new task to run. */
+ portSAVE_CONTEXT
+ MRS X0, ESR_EL1
+ MRS X2, ELR_EL1
+ LSR X1, X0, #26
+ CMP X1, #0x15 /* 0x15 = SVC instruction. */
+ B.NE HwiP_SVC_Abort
+ MRS x0, mpidr_el1 /* Get CoreID */
+ and x0, x0, #0xff
+ BL vTaskSwitchContext
+ portRESTORE_CONTEXT
+HwiP_SVC_Abort:
+ /* Full ESR is in X0, exception class code is in X1. */
+ B .
+
+/******************************************************************************
+ * handles IRQ entry and exit.
+ *****************************************************************************/
+.align 8
+.type HwiP_IRQ_Handler, %function
+HwiP_IRQ_Handler:
+ /* save cpu scratch regs */
+ PUSH_CALLER_SAVE_CPU_REGS SP
+
+ /* Save the SPSR and ELR. */
+ MRS X3, SPSR_EL1
+ MRS X2, ELR_EL1
+ STP X2, X3, [SP, #-0x10]!
+
+ /* Increment the interrupt nesting counter. */
+ LDR X5, ullPortInterruptNestingConst
+
+ /* Get coreId and choose the corresponding index for core in ullPortInterruptNesting */
+ MRS X1, MPIDR_EL1
+ AND X1, X1, #0xff
+ CMP X1, #0
+ B.EQ 2f
+ ADD X5, X5, #8
+2:
+ LDR X1, [X5] /* Old nesting count in X1. */
+ ADD X6, X1, #1
+ STR X6, [X5] /* Address of nesting count variable in X5. */
+
+ /* Maintain the interrupt nesting information across the function call. */
+ STP X1, X5, [SP, #-0x10]!
+
+ /* Call the C handler. */
+ BL HwiP_intrHandler
+
+ /* Disable interrupts. */
+ MSR DAIFSET, #2
+ DSB SY
+ ISB SY
+
+ /* Restore the critical nesting count. */
+ LDP X1, X5, [SP], #0x10
+ STR X1, [X5]
+
+ /* Has interrupt nesting unwound? */
+ CMP X1, #0
+ B.NE Exit_IRQ_No_Context_Switch
+
+ /* Is a context switch required? */
+ LDR X0, ullPortYieldRequiredConst
+
+ /* Get coreId and choose the corresponding index for core in ullPortYieldRequired */
+ MRS X1, MPIDR_EL1
+ AND X1, X1, #0xff
+ CMP X1, #0
+ B.EQ 2f
+ ADD X0, X0, #8
+2:
+ LDR X1, [X0]
+ CMP X1, #0
+ B.EQ Exit_IRQ_No_Context_Switch
+
+ /* Reset ullPortYieldRequired to 0. */
+ MOV X2, #0
+ STR X2, [X0]
+
+ /* Restore volatile registers. */
+ LDP X4, X5, [SP], #0x10 /* SPSR and ELR. */
+ MSR SPSR_EL1, X5
+ MSR ELR_EL1, X4
+ DSB SY
+ ISB SY
+
+ POP_CALLER_SAVE_CPU_REGS SP
+
+ /* Save the context of the current task and select a new task to run. */
+ portSAVE_CONTEXT
+ MRS x0, mpidr_el1 /* Get CoreID */
+ and x0, x0, #0xff
+ BL vTaskSwitchContext
+ portRESTORE_CONTEXT
+
+Exit_IRQ_No_Context_Switch:
+ /* Restore volatile registers. */
+ LDP X4, X5, [SP], #0x10 /* SPSR and ELR. */
+ MSR SPSR_EL1, X5
+ MSR ELR_EL1, X4
+ DSB SY
+ ISB SY
+
+ POP_CALLER_SAVE_CPU_REGS SP
+
+ ERET
+
+/*
+ * Void HwiP_defaultExcHandler(uint32_t usingEL0Stack);
+ */
+ .section .text.HwiP_defaultExcHandler, "ax"
+ .func HwiP_defaultExcHandler
+HwiP_defaultExcHandler:
+
+ mov x19, x0 /* copy 'usingEL0Stack' argument */
+ mrs x0, spsr_el1
+ mrs x1, elr_el1
+ stp x0, x1, [sp, #-16]! /* save spsr_el1 and elr_el1 */
+#if defined(__ARM_FP)
+ mrs x0, fpcr
+ mrs x1, fpsr
+ stp x0, x1, [sp, #-16]! /* save fpcr and fpsr */
+#endif
+
+ /* call dispatch default handler */
+ mrs x0, elr_el1 /* pass IRP to dispatchIRQC() */
+ ldr x1, =HwiP_defaultHandler
+ blr x1
+
+ /* returns with interrupts disabled */
+#if defined(__ARM_FP)
+ ldp x0, x1, [sp], #16
+ msr fpcr, x0
+ msr fpsr, x1
+#endif
+ ldp x0, x1, [sp], #16
+ msr spsr_el1, x0
+ msr elr_el1, x1
+#if defined(__ARM_FP)
+ POP_CALLER_SAVE_FPU_REGS sp /* restore vfp scratch regs */
+#endif
+ POP_CALLER_SAVE_CPU_REGS sp /* restore cpu scratch regs */
+ eret
+
+.align 8
+
+/*
+ * int32_t GateSmp_tryLock(uintptr_t gateWord);
+ */
+ .global GateSmp_tryLock
+ .type GateSmp_tryLock , %function
+GateSmp_tryLock:
+ ldxr w1, [x0]
+ cmp w1, #1 /* is locked already? */
+ beq 1f /* if so, leave with fail */
+
+ mov w2, #1 /* locked = 1 */
+ stxr w1, w2, [x0] /* if so attempt to grab it */
+ cmp w1, #0 /* did we get it? zero is yes */
+ /* if not, loop while in contention */
+ bne GateSmp_tryLock
+1:
+ mov w0, w1
+ dmb sy
+ ret
+
+/*
+ * void GateSmp_unlock(uintptr_t gateWord);
+ */
+ .global GateSmp_unlock
+ .type GateSmp_unlock , %function
+
+GateSmp_unlock:
+ dmb sy
+
+ mov w1, #0
+ str w1, [x0]
+
+ dsb sy
+ sev /* let everyone know */
+ ret
+
+pxCurrentTCBConst: .dword pxCurrentTCBs
+ullPortTaskHasFPUContextConst: .dword ullPortTaskHasFPUContext
+ullPortInterruptNestingConst: .dword ullPortInterruptNesting
+ullPortYieldRequiredConst: .dword ullPortYieldRequired
+
+.end
diff --git a/TI/CORTEX_A53_64-BIT_TI_AM64_SMP/portmacro.h b/TI/CORTEX_A53_64-BIT_TI_AM64_SMP/portmacro.h
new file mode 100644
index 0000000..126b9ff
--- /dev/null
+++ b/TI/CORTEX_A53_64-BIT_TI_AM64_SMP/portmacro.h
@@ -0,0 +1,294 @@
+/*
+ * 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!
+ */
+/*
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PORTMACRO_H
+#define PORTMACRO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include <kernel/dpl/HwiP.h>
+#include <kernel/a53/HwiP_armv8_gic.h>
+#include <kernel/a53/common_armv8.h>
+
+/*-----------------------------------------------------------
+ * Port specific definitions.
+ *
+ * The settings in this file configure FreeRTOS correctly for the given hardware
+ * and compiler.
+ *
+ * These settings should not be altered.
+ *-----------------------------------------------------------
+ */
+
+/* Type definitions. */
+#define portCHAR char
+#define portFLOAT float
+#define portDOUBLE double
+#define portLONG long
+#define portSHORT short
+#define portSTACK_TYPE size_t
+#define portBASE_TYPE long
+
+typedef portSTACK_TYPE StackType_t;
+typedef portBASE_TYPE BaseType_t;
+typedef uint64_t UBaseType_t;
+
+typedef uint32_t TickType_t;
+#define portMAX_DELAY ( ( TickType_t ) 0xffffffff )
+
+/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
+not need to be guarded with a critical section. */
+#define portTICK_TYPE_IS_ATOMIC 1
+
+/* Hardware specifics. */
+#define portSTACK_GROWTH ( -1 )
+#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
+#define portBYTE_ALIGNMENT 16
+#define portPOINTER_SIZE_TYPE uint64_t
+#define portCRITICAL_NESTING_IN_TCB 1
+
+/* Task utilities. */
+
+extern uint64_t ullPortYieldRequired[];
+/* Called at the end of an ISR that can cause a context switch. */
+#define portEND_SWITCHING_ISR( xSwitchRequired ) \
+{ \
+ \
+ if( xSwitchRequired != pdFALSE ) \
+ { \
+ ullPortYieldRequired[portGET_CORE_ID()] = pdTRUE; \
+ } \
+}
+
+#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
+#define portYIELD() __asm volatile ( "SVC 0" ::: "memory" )
+
+/*-----------------------------------------------------------
+ * Critical section control
+ *----------------------------------------------------------*/
+
+extern void vTaskEnterCritical( void );
+extern void vTaskExitCritical( void );
+
+#define portDISABLE_INTERRUPTS() HwiP_disable()
+#define portENABLE_INTERRUPTS() HwiP_enable()
+#define portENTER_CRITICAL() vTaskEnterCritical();
+#define portEXIT_CRITICAL() vTaskExitCritical();
+#define portSET_INTERRUPT_MASK_FROM_ISR() ({ \
+ uint64_t x = HwiP_disable(); \
+ vTaskEnterCritical(); \
+ x; \
+ })
+
+#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) ({ \
+ vTaskExitCritical(); \
+ HwiP_restore(x); \
+ })
+
+/* Task function macros as described on the FreeRTOS.org WEB site. These are
+not required for this port but included in case common demo code that uses these
+macros is used. */
+#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
+#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
+
+/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
+before any floating point instructions are executed. */
+void vPortTaskUsesFPU( void );
+#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
+
+/* Architecture specific optimisations. */
+#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
+ #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
+#endif
+
+#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
+
+ /* Store/clear the ready priorities in a bit map. */
+ #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
+ #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
+
+ #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) )
+
+#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
+
+#define portNOP() __asm volatile( "NOP" )
+#define portINLINE __inline
+#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
+
+/* port for SMP */
+#define portGET_CORE_ID() Armv8_getCoreId()
+#define portRESTORE_INTERRUPTS( ulState ) HwiP_restore ( ulState )
+#define portCHECK_IF_IN_ISR() HwiP_inISR()
+
+/*-----------------------------------------------------------
+ * Critical section locks
+ *----------------------------------------------------------*/
+
+#define ISR_LOCK (0u)
+#define TASK_LOCK (1u)
+
+#define portRTOS_LOCK_COUNT 2
+#define portMAX_CORE_COUNT 2
+
+#define portRELEASE_ISR_LOCK() vPortRecursiveLock(ISR_LOCK, pdFALSE)
+#define portGET_ISR_LOCK() vPortRecursiveLock(ISR_LOCK, pdTRUE)
+
+#define portRELEASE_TASK_LOCK() vPortRecursiveLock(TASK_LOCK, pdFALSE)
+#define portGET_TASK_LOCK() vPortRecursiveLock(TASK_LOCK, pdTRUE)
+
+/* Interrupt number to interrupt a core for task yield */
+#define YIELD_CORE_INTERRUPT_NO (0U)
+
+extern int32_t Signal_coreIntr( CSL_gic500_gicrRegs *pGic500GicrRegs, uint32_t coreId, uint32_t intrNum );
+
+#define portYIELD_CORE( xCoreID ) do { \
+ Signal_coreIntr((CSL_gic500_gicrRegs *) ( HWIP_GIC_BASE_ADDR + \
+ CSL_GIC500_GICR_CORE_CONTROL_CTLR(0U)), xCoreID, YIELD_CORE_INTERRUPT_NO); \
+ }while(0);
+
+
+uint64_t Get_64(volatile uint64_t* x);
+void Set_64(volatile uint64_t* x, uint64_t value);
+
+/* Which core owns the lock */
+volatile uint64_t ucOwnedByCore[ portMAX_CORE_COUNT ];
+/* Lock count a core owns */
+volatile uint64_t ucRecursionCountByLock[ portRTOS_LOCK_COUNT ];
+
+/* Index 0 is used for ISR lock and Index 1 is used for task lock */
+uint32_t GateWord[ portRTOS_LOCK_COUNT ];
+
+int32_t GateSmp_tryLock(uint32_t* gateWord);
+void GateSmp_unlock(uint32_t* gateWord);
+
+static inline void vPortRecursiveLock(uint32_t ulLockNum, BaseType_t uxAcquire)
+{
+ uint32_t ulCoreNum = portGET_CORE_ID();
+ uint32_t ulLockBit = 1u << ulLockNum;
+
+ /* Lock acquire */
+ if (uxAcquire)
+ {
+
+ /* Check if spinlock is available */
+ /* If spinlock is not available check if the core owns the lock */
+ /* If the core owns the lock wait increment the lock count by the core */
+ /* If core does not own the lock wait for the spinlock */
+ if( GateSmp_tryLock( &GateWord[ulLockNum] ) != 0)
+ {
+ /* Check if the core owns the spinlock */
+ if( Get_64(&ucOwnedByCore[ulCoreNum]) & ulLockBit )
+ {
+ configASSERT( Get_64(&ucRecursionCountByLock[ulLockNum]) != 255u);
+ Set_64(&ucRecursionCountByLock[ulLockNum], (Get_64(&ucRecursionCountByLock[ulLockNum])+1));
+ return;
+ }
+
+ /* Preload the gate word into the cache */
+ uint32_t dummy = GateWord[ulLockNum];
+ dummy++;
+
+ /* Wait for spinlock */
+ while( GateSmp_tryLock(&GateWord[ulLockNum]) != 0);
+ }
+
+ /* Add barrier to ensure lock is taken before we proceed */
+ __asm__ __volatile__ (
+ "dmb sy"
+ ::: "memory"
+ );
+
+ /* Assert the lock count is 0 when the spinlock is free and is acquired */
+ configASSERT(Get_64(&ucRecursionCountByLock[ulLockNum]) == 0);
+
+ /* Set lock count as 1 */
+ Set_64(&ucRecursionCountByLock[ulLockNum], 1);
+ /* Set ucOwnedByCore */
+ Set_64(&ucOwnedByCore[ulCoreNum], (Get_64(&ucOwnedByCore[ulCoreNum]) | ulLockBit));
+ }
+ /* Lock release */
+ else
+ {
+ /* Assert the lock is not free already */
+ configASSERT( (Get_64(&ucOwnedByCore[ulCoreNum]) & ulLockBit) != 0 );
+ configASSERT( Get_64(&ucRecursionCountByLock[ulLockNum]) != 0 );
+
+ /* Reduce ucRecursionCountByLock by 1 */
+ Set_64(&ucRecursionCountByLock[ulLockNum], (Get_64(&ucRecursionCountByLock[ulLockNum]) - 1) );
+
+ if( !Get_64(&ucRecursionCountByLock[ulLockNum]) )
+ {
+ Set_64(&ucOwnedByCore[ulCoreNum], (Get_64(&ucOwnedByCore[ulCoreNum]) & ~ulLockBit));
+ GateSmp_unlock(&GateWord[ulLockNum]);
+ /* Add barrier to ensure lock is taken before we proceed */
+ __asm__ __volatile__ (
+ "dmb sy"
+ ::: "memory"
+ );
+ }
+ }
+}
+
+#ifdef __cplusplus
+ } /* extern C */
+#endif
+
+#endif /* PORTMACRO_H */
+