From 17dfd0f808c297955cc8d6d596b9d7b34ce83b29 Mon Sep 17 00:00:00 2001 From: Angel Cascarino Date: Thu, 27 Jun 2024 23:49:53 +0100 Subject: [PATCH] Update XMOS xcore.ai port to be compatible with v11.x (#1096) * Fix kexcept function * Create dummy pxCurrentTCBs for xcore.ai port * Additional commentary * Add a layer of indirection to cope with singlecore * Clarify use of _DoException --- portable/ThirdParty/xClang/XCOREAI/port.c | 35 ++++++++++++++++++-- portable/ThirdParty/xClang/XCOREAI/portasm.S | 9 ++--- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/portable/ThirdParty/xClang/XCOREAI/port.c b/portable/ThirdParty/xClang/XCOREAI/port.c index ba4598b6b0b..ac12aa31a60 100644 --- a/portable/ThirdParty/xClang/XCOREAI/port.c +++ b/portable/ThirdParty/xClang/XCOREAI/port.c @@ -12,6 +12,15 @@ static hwtimer_t xKernelTimer; uint32_t ulPortYieldRequired[ portMAX_CORE_COUNT ] = { pdFALSE }; +/* When this port was designed, it was assumed that pxCurrentTCBs would always + exist and that it would always be an array containing pointers to the current + TCBs for each core. In v11, this is not the case; if we are only running one + core, the symbol is pxCurrentTCB instead. Therefore, this port adds a layer + of indirection - we populate this pointer-to-pointer in the RTOS kernel entry + function below. This makes this port agnostic to whether it is running on SMP + or singlecore RTOS. */ +void ** xcorePvtTCBContainer; + /*-----------------------------------------------------------*/ void vIntercoreInterruptISR( void ) @@ -140,6 +149,28 @@ DEFINE_RTOS_KERNEL_ENTRY( void, vPortStartSchedulerOnCore, void ) } #endif + /* Populate the TCBContainer depending on whether we're singlecore or SMP */ + #if ( configNUMBER_OF_CORES == 1 ) + { + asm volatile ( + "ldaw %0, dp[pxCurrentTCB]\n\t" + : "=r"(xcorePvtTCBContainer) + : /* no inputs */ + : /* no clobbers */ + ); + } + #else + { + asm volatile ( + "ldaw %0, dp[pxCurrentTCBs]\n\t" + : "=r"(xcorePvtTCBContainer) + : /* no inputs */ + : /* no clobbers */ + ); + } + + #endif + debug_printf( "FreeRTOS Core %d initialized\n", xCoreID ); /* @@ -147,8 +178,8 @@ DEFINE_RTOS_KERNEL_ENTRY( void, vPortStartSchedulerOnCore, void ) * to run and jump into it. */ asm volatile ( - "mov r6, %0\n\t" /* R6 must be the FreeRTOS core ID*/ - "ldaw r5, dp[pxCurrentTCBs]\n\t" /* R5 must be the TCB list which is indexed by R6 */ + "mov r6, %0\n\t" /* R6 must be the FreeRTOS core ID. In singlecore this is always 0. */ + "ldw r5, dp[xcorePvtTCBContainer]\n\t" /* R5 must be the TCB list which is indexed by R6 */ "bu _freertos_restore_ctx\n\t" : /* no outputs */ : "r" ( xCoreID ) diff --git a/portable/ThirdParty/xClang/XCOREAI/portasm.S b/portable/ThirdParty/xClang/XCOREAI/portasm.S index 7445672a08e..64b7b9d9ab5 100644 --- a/portable/ThirdParty/xClang/XCOREAI/portasm.S +++ b/portable/ThirdParty/xClang/XCOREAI/portasm.S @@ -14,11 +14,8 @@ rest of the ISR callback functions. */ .issue_mode dual .cc_top kexcept.function, kexcept kexcept: - ldc r11, 0x0008 - shl r11, r11, 16 - ldc r9, 0x0080 - or r11, r11, r9 - bau r11 //_TrapHandler is at 0x00080080. TODO: Is it always? Why can't I access the symbol _TrapHandler? + bu _DoException /* This symbol is generated by the toolchain and */ + /* provides graceful exception handling */ _yield: {set sp, r4 /* Restore the task's SP to save the rest of its context. */ @@ -123,7 +120,7 @@ _yield_continue: ldaw r11, sp[37]} vstc r11[0] #endif - ldaw r5, dp[pxCurrentTCBs] /* Get the current TCB array into r5. */ + ldw r5, dp[xcorePvtTCBContainer] ldw r1, r5[r0] /* Get this core's current TCB pointer into r1. */ stw r4, r1[0x0] /* Save the current task's SP to the first */ /* word (top of stack) in the current TCB. */