From 529de5606e08bedcf7c9a6b0ecbb27cdab73ce18 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Wed, 10 Jan 2024 09:58:45 -0500 Subject: Revert #768 on the XCC/Xtensa portable files (#948) --- portable/ThirdParty/XCC/Xtensa/port.c | 69 ++- portable/ThirdParty/XCC/Xtensa/portbenchmark.h | 2 +- portable/ThirdParty/XCC/Xtensa/portclib.c | 394 +++++++++-------- portable/ThirdParty/XCC/Xtensa/portmacro.h | 254 ++++++----- portable/ThirdParty/XCC/Xtensa/porttrace.h | 6 +- portable/ThirdParty/XCC/Xtensa/xtensa_api.h | 121 +++--- portable/ThirdParty/XCC/Xtensa/xtensa_config.h | 208 ++++----- portable/ThirdParty/XCC/Xtensa/xtensa_context.h | 478 ++++++++++----------- portable/ThirdParty/XCC/Xtensa/xtensa_init.c | 42 +- portable/ThirdParty/XCC/Xtensa/xtensa_intr.c | 153 +++---- .../ThirdParty/XCC/Xtensa/xtensa_overlay_os_hook.c | 36 +- portable/ThirdParty/XCC/Xtensa/xtensa_rtos.h | 232 +++++----- portable/ThirdParty/XCC/Xtensa/xtensa_timer.h | 160 +++---- 13 files changed, 1059 insertions(+), 1096 deletions(-) diff --git a/portable/ThirdParty/XCC/Xtensa/port.c b/portable/ThirdParty/XCC/Xtensa/port.c index a95784167..805a78401 100644 --- a/portable/ThirdParty/XCC/Xtensa/port.c +++ b/portable/ThirdParty/XCC/Xtensa/port.c @@ -37,39 +37,34 @@ /* Defined in portasm.h */ -extern void _frxt_tick_timer_init( void ); +extern void _frxt_tick_timer_init(void); /* Defined in xtensa_context.S */ -extern void _xt_coproc_init( void ); +extern void _xt_coproc_init(void); /*-----------------------------------------------------------*/ /* We require the address of the pxCurrentTCB variable, but don't want to know - * any details of its type. */ +any details of its type. */ typedef void TCB_t; extern volatile TCB_t * volatile pxCurrentTCB; -unsigned port_xSchedulerRunning = 0; /* Duplicate of inaccessible xSchedulerRunning; needed at startup to avoid counting nesting */ -unsigned port_interruptNesting = 0; /* Interrupt nesting level */ +unsigned port_xSchedulerRunning = 0; // Duplicate of inaccessible xSchedulerRunning; needed at startup to avoid counting nesting +unsigned port_interruptNesting = 0; // Interrupt nesting level /*-----------------------------------------------------------*/ -/* User exception dispatcher when exiting */ -void _xt_user_exit( void ); +// User exception dispatcher when exiting +void _xt_user_exit(void); /* * Stack initialization */ #if portUSING_MPU_WRAPPERS - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) #else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - TaskFunction_t pxCode, - void * pvParameters ) +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) #endif { StackType_t * sp; @@ -134,18 +129,18 @@ void _xt_user_exit( void ); void vPortEndScheduler( void ) { /* It is unlikely that the Xtensa port will get stopped. If required simply - * disable the tick interrupt here. */ + disable the tick interrupt here. */ } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) { - /* Interrupts are disabled at this point and stack contains PS with enabled interrupts when task context is restored */ + // Interrupts are disabled at this point and stack contains PS with enabled interrupts when task context is restored #if XCHAL_CP_NUM > 0 - /* Initialize co-processor management for tasks. Leave CPENABLE alone. */ - _xt_coproc_init(); + /* Initialize co-processor management for tasks. Leave CPENABLE alone. */ + _xt_coproc_init(); #endif /* Init the tick divisor value */ @@ -155,14 +150,14 @@ BaseType_t xPortStartScheduler( void ) _frxt_tick_timer_init(); #if XT_USE_THREAD_SAFE_CLIB - /* Init C library */ - vPortClibInit(); + // Init C library + vPortClibInit(); #endif port_xSchedulerRunning = 1; - /* Cannot be directly called from C; never returns */ - __asm__ volatile ( "call0 _frxt_dispatch\n" ); + // Cannot be directly called from C; never returns + __asm__ volatile ("call0 _frxt_dispatch\n"); /* Should not get here. */ return pdTRUE; @@ -195,19 +190,19 @@ BaseType_t xPortSysTickHandler( void ) * Used to set coprocessor area in stack. Current hack is to reuse MPU pointer for coprocessor area. */ #if portUSING_MPU_WRAPPERS - void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, - const struct xMEMORY_REGION * const xRegions, - StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) - { - #if XCHAL_CP_NUM > 0 - xMPUSettings->coproc_area = ( StackType_t * ) ( ( uint32_t ) ( pxBottomOfStack + ulStackDepth - 1 ) ); - xMPUSettings->coproc_area = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) xMPUSettings->coproc_area ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); - xMPUSettings->coproc_area = ( StackType_t * ) ( ( ( uint32_t ) xMPUSettings->coproc_area - XT_CP_SIZE ) & ~0xf ); - - /* NOTE: we cannot initialize the coprocessor save area here because FreeRTOS is going to - * clear the stack area after we return. This is done in pxPortInitialiseStack(). - */ - #endif - } +void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, + const struct xMEMORY_REGION * const xRegions, + StackType_t * pxBottomOfStack, + uint32_t ulStackDepth ) +{ + #if XCHAL_CP_NUM > 0 + xMPUSettings->coproc_area = ( StackType_t * ) ( ( uint32_t ) ( pxBottomOfStack + ulStackDepth - 1 )); + xMPUSettings->coproc_area = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) xMPUSettings->coproc_area ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); + xMPUSettings->coproc_area = ( StackType_t * ) ( ( ( uint32_t ) xMPUSettings->coproc_area - XT_CP_SIZE ) & ~0xf ); + + /* NOTE: we cannot initialize the coprocessor save area here because FreeRTOS is going to + * clear the stack area after we return. This is done in pxPortInitialiseStack(). + */ + #endif +} #endif /* if portUSING_MPU_WRAPPERS */ diff --git a/portable/ThirdParty/XCC/Xtensa/portbenchmark.h b/portable/ThirdParty/XCC/Xtensa/portbenchmark.h index deb1cd0d6..7778dd1a5 100644 --- a/portable/ThirdParty/XCC/Xtensa/portbenchmark.h +++ b/portable/ThirdParty/XCC/Xtensa/portbenchmark.h @@ -42,7 +42,7 @@ #endif #define portbenchmarkINTERRUPT_DISABLE() -#define portbenchmarkINTERRUPT_RESTORE( newstate ) +#define portbenchmarkINTERRUPT_RESTORE(newstate) #define portbenchmarkIntLatency() #define portbenchmarkIntWait() #define portbenchmarkReset() diff --git a/portable/ThirdParty/XCC/Xtensa/portclib.c b/portable/ThirdParty/XCC/Xtensa/portclib.c index bb415fbbe..3c87d6741 100644 --- a/portable/ThirdParty/XCC/Xtensa/portclib.c +++ b/portable/ThirdParty/XCC/Xtensa/portclib.c @@ -31,204 +31,200 @@ #if XT_USE_THREAD_SAFE_CLIB - #if XSHAL_CLIB == XTHAL_CLIB_XCLIB - - #include - #include - - #include "semphr.h" - - typedef SemaphoreHandle_t _Rmtx; - -/*----------------------------------------------------------------------------- */ -/* Override this and set to nonzero to enable locking. */ -/*----------------------------------------------------------------------------- */ - int32_t _xclib_use_mt = 1; - - -/*----------------------------------------------------------------------------- */ -/* Init lock. */ -/*----------------------------------------------------------------------------- */ - void _Mtxinit( _Rmtx * mtx ) - { - *mtx = xSemaphoreCreateRecursiveMutex(); - } - -/*----------------------------------------------------------------------------- */ -/* Destroy lock. */ -/*----------------------------------------------------------------------------- */ - void _Mtxdst( _Rmtx * mtx ) - { - if( ( mtx != NULL ) && ( *mtx != NULL ) ) - { - vSemaphoreDelete( *mtx ); - } - } - -/*----------------------------------------------------------------------------- */ -/* Lock. */ -/*----------------------------------------------------------------------------- */ - void _Mtxlock( _Rmtx * mtx ) - { - if( ( mtx != NULL ) && ( *mtx != NULL ) ) - { - xSemaphoreTakeRecursive( *mtx, portMAX_DELAY ); - } - } - -/*----------------------------------------------------------------------------- */ -/* Unlock. */ -/*----------------------------------------------------------------------------- */ - void _Mtxunlock( _Rmtx * mtx ) - { - if( ( mtx != NULL ) && ( *mtx != NULL ) ) - { - xSemaphoreGiveRecursive( *mtx ); - } - } - -/*----------------------------------------------------------------------------- */ -/* Called by malloc() to allocate blocks of memory from the heap. */ -/*----------------------------------------------------------------------------- */ - void * _sbrk_r( struct _reent * reent, - int32_t incr ) - { - extern char _end; - extern char _heap_sentry; - static char * _heap_sentry_ptr = &_heap_sentry; - static char * heap_ptr; - char * base; - - if( !heap_ptr ) - { - heap_ptr = ( char * ) &_end; - } - - base = heap_ptr; - - if( heap_ptr + incr >= _heap_sentry_ptr ) - { - reent->_errno = ENOMEM; - return ( char * ) -1; - } - - heap_ptr += incr; - return base; - } - -/*----------------------------------------------------------------------------- */ -/* Global initialization for C library. */ -/*----------------------------------------------------------------------------- */ - void vPortClibInit( void ) - { - } - -/*----------------------------------------------------------------------------- */ -/* Per-thread cleanup stub provided for linking, does nothing. */ -/*----------------------------------------------------------------------------- */ - void _reclaim_reent( void * ptr ) - { - } - - #endif /* XSHAL_CLIB == XTHAL_CLIB_XCLIB */ - - #if XSHAL_CLIB == XTHAL_CLIB_NEWLIB - - #include - #include - #include - #include - #include - - #include "semphr.h" - - static SemaphoreHandle_t xClibMutex; - static uint32_t ulClibInitDone = 0; - -/*----------------------------------------------------------------------------- */ -/* Get C library lock. */ -/*----------------------------------------------------------------------------- */ - void __malloc_lock( struct _reent * ptr ) - { - if( !ulClibInitDone ) - { - return; - } - - xSemaphoreTakeRecursive( xClibMutex, portMAX_DELAY ); - } - -/*----------------------------------------------------------------------------- */ -/* Release C library lock. */ -/*----------------------------------------------------------------------------- */ - void __malloc_unlock( struct _reent * ptr ) - { - if( !ulClibInitDone ) - { - return; - } - - xSemaphoreGiveRecursive( xClibMutex ); - } - -/*----------------------------------------------------------------------------- */ -/* Lock for environment. Since we have only one global lock we can just call */ -/* the malloc() lock function. */ -/*----------------------------------------------------------------------------- */ - void __env_lock( struct _reent * ptr ) - { - __malloc_lock( ptr ); - } - - -/*----------------------------------------------------------------------------- */ -/* Unlock environment. */ -/*----------------------------------------------------------------------------- */ - void __env_unlock( struct _reent * ptr ) - { - __malloc_unlock( ptr ); - } - -/*----------------------------------------------------------------------------- */ -/* Called by malloc() to allocate blocks of memory from the heap. */ -/*----------------------------------------------------------------------------- */ - void * _sbrk_r( struct _reent * reent, - int32_t incr ) - { - extern char _end; - extern char _heap_sentry; - static char * _heap_sentry_ptr = &_heap_sentry; - static char * heap_ptr; - char * base; - - if( !heap_ptr ) - { - heap_ptr = ( char * ) &_end; - } - - base = heap_ptr; - - if( heap_ptr + incr >= _heap_sentry_ptr ) - { - reent->_errno = ENOMEM; - return ( char * ) -1; - } - - heap_ptr += incr; - return base; - } - -/*----------------------------------------------------------------------------- */ -/* Global initialization for C library. */ -/*----------------------------------------------------------------------------- */ - void vPortClibInit( void ) - { - configASSERT( !ulClibInitDone ); - - xClibMutex = xSemaphoreCreateRecursiveMutex(); - ulClibInitDone = 1; - } - - #endif /* XSHAL_CLIB == XTHAL_CLIB_NEWLIB */ +#if XSHAL_CLIB == XTHAL_CLIB_XCLIB + +#include +#include + +#include "semphr.h" + +typedef SemaphoreHandle_t _Rmtx; + +//----------------------------------------------------------------------------- +// Override this and set to nonzero to enable locking. +//----------------------------------------------------------------------------- +int32_t _xclib_use_mt = 1; + + +//----------------------------------------------------------------------------- +// Init lock. +//----------------------------------------------------------------------------- +void +_Mtxinit(_Rmtx * mtx) +{ + *mtx = xSemaphoreCreateRecursiveMutex(); +} + +//----------------------------------------------------------------------------- +// Destroy lock. +//----------------------------------------------------------------------------- +void +_Mtxdst(_Rmtx * mtx) +{ + if ((mtx != NULL) && (*mtx != NULL)) { + vSemaphoreDelete(*mtx); + } +} + +//----------------------------------------------------------------------------- +// Lock. +//----------------------------------------------------------------------------- +void +_Mtxlock(_Rmtx * mtx) +{ + if ((mtx != NULL) && (*mtx != NULL)) { + xSemaphoreTakeRecursive(*mtx, portMAX_DELAY); + } +} + +//----------------------------------------------------------------------------- +// Unlock. +//----------------------------------------------------------------------------- +void +_Mtxunlock(_Rmtx * mtx) +{ + if ((mtx != NULL) && (*mtx != NULL)) { + xSemaphoreGiveRecursive(*mtx); + } +} + +//----------------------------------------------------------------------------- +// Called by malloc() to allocate blocks of memory from the heap. +//----------------------------------------------------------------------------- +void * +_sbrk_r (struct _reent * reent, int32_t incr) +{ + extern char _end; + extern char _heap_sentry; + static char * _heap_sentry_ptr = &_heap_sentry; + static char * heap_ptr; + char * base; + + if (!heap_ptr) + heap_ptr = (char *) &_end; + + base = heap_ptr; + if (heap_ptr + incr >= _heap_sentry_ptr) { + reent->_errno = ENOMEM; + return (char *) -1; + } + + heap_ptr += incr; + return base; +} + +//----------------------------------------------------------------------------- +// Global initialization for C library. +//----------------------------------------------------------------------------- +void +vPortClibInit(void) +{ +} + +//----------------------------------------------------------------------------- +// Per-thread cleanup stub provided for linking, does nothing. +//----------------------------------------------------------------------------- +void +_reclaim_reent(void * ptr) +{ +} + +#endif /* XSHAL_CLIB == XTHAL_CLIB_XCLIB */ + +#if XSHAL_CLIB == XTHAL_CLIB_NEWLIB + +#include +#include +#include +#include +#include + +#include "semphr.h" + +static SemaphoreHandle_t xClibMutex; +static uint32_t ulClibInitDone = 0; + +//----------------------------------------------------------------------------- +// Get C library lock. +//----------------------------------------------------------------------------- +void +__malloc_lock(struct _reent * ptr) +{ + if (!ulClibInitDone) + return; + + xSemaphoreTakeRecursive(xClibMutex, portMAX_DELAY); +} + +//----------------------------------------------------------------------------- +// Release C library lock. +//----------------------------------------------------------------------------- +void +__malloc_unlock(struct _reent * ptr) +{ + if (!ulClibInitDone) + return; + + xSemaphoreGiveRecursive(xClibMutex); +} + +//----------------------------------------------------------------------------- +// Lock for environment. Since we have only one global lock we can just call +// the malloc() lock function. +//----------------------------------------------------------------------------- +void +__env_lock(struct _reent * ptr) +{ + __malloc_lock(ptr); +} + + +//----------------------------------------------------------------------------- +// Unlock environment. +//----------------------------------------------------------------------------- +void +__env_unlock(struct _reent * ptr) +{ + __malloc_unlock(ptr); +} + +//----------------------------------------------------------------------------- +// Called by malloc() to allocate blocks of memory from the heap. +//----------------------------------------------------------------------------- +void * +_sbrk_r (struct _reent * reent, int32_t incr) +{ + extern char _end; + extern char _heap_sentry; + static char * _heap_sentry_ptr = &_heap_sentry; + static char * heap_ptr; + char * base; + + if (!heap_ptr) + heap_ptr = (char *) &_end; + + base = heap_ptr; + if (heap_ptr + incr >= _heap_sentry_ptr) { + reent->_errno = ENOMEM; + return (char *) -1; + } + + heap_ptr += incr; + return base; +} + +//----------------------------------------------------------------------------- +// Global initialization for C library. +//----------------------------------------------------------------------------- +void +vPortClibInit(void) +{ + configASSERT(!ulClibInitDone); + + xClibMutex = xSemaphoreCreateRecursiveMutex(); + ulClibInitDone = 1; +} + +#endif /* XSHAL_CLIB == XTHAL_CLIB_NEWLIB */ #endif /* XT_USE_THREAD_SAFE_CLIB */ diff --git a/portable/ThirdParty/XCC/Xtensa/portmacro.h b/portable/ThirdParty/XCC/Xtensa/portmacro.h index 21d3e5384..f84e4335e 100644 --- a/portable/ThirdParty/XCC/Xtensa/portmacro.h +++ b/portable/ThirdParty/XCC/Xtensa/portmacro.h @@ -38,15 +38,15 @@ #ifndef __ASSEMBLER__ - #include +#include - #include - #include - #include - #include /* required for XSHAL_CLIB */ - #include +#include +#include +#include +#include /* required for XSHAL_CLIB */ +#include -/*#include "xtensa_context.h" */ +//#include "xtensa_context.h" /*----------------------------------------------------------- * Port specific definitions. @@ -60,159 +60,149 @@ /* Type definitions. */ - #define portCHAR int8_t - #define portFLOAT float - #define portDOUBLE double - #define portLONG int32_t - #define portSHORT int16_t - #define portSTACK_TYPE uint32_t - #define portBASE_TYPE int - - typedef portSTACK_TYPE StackType_t; - typedef portBASE_TYPE BaseType_t; - typedef unsigned portBASE_TYPE UBaseType_t; - - #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) - typedef uint16_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffff - #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL - #else - #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. - #endif +#define portCHAR int8_t +#define portFLOAT float +#define portDOUBLE double +#define portLONG int32_t +#define portSHORT int16_t +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE int + +typedef portSTACK_TYPE StackType_t; +typedef portBASE_TYPE BaseType_t; +typedef unsigned portBASE_TYPE UBaseType_t; + +#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. +#endif /*-----------------------------------------------------------*/ -/* portbenchmark */ - #include "portbenchmark.h" +// portbenchmark +#include "portbenchmark.h" /* Critical section management. NW-TODO: replace XTOS_SET_INTLEVEL with more efficient version, if any? */ -/* These cannot be nested. They should be used with a lot of care and cannot be called from interrupt level. */ - #define portDISABLE_INTERRUPTS() do { XTOS_SET_INTLEVEL( XCHAL_EXCM_LEVEL ); portbenchmarkINTERRUPT_DISABLE(); } while( 0 ) - #define portENABLE_INTERRUPTS() do { portbenchmarkINTERRUPT_RESTORE( 0 ); XTOS_SET_INTLEVEL( 0 ); } while( 0 ) - -/* These can be nested */ - #define portCRITICAL_NESTING_IN_TCB 1 /* For now, let FreeRTOS' (tasks.c) manage critical nesting */ - void vTaskEnterCritical( void ); - void vTaskExitCritical( void ); - #define portENTER_CRITICAL() vTaskEnterCritical() - #define portEXIT_CRITICAL() vTaskExitCritical() - -/* Cleaner and preferred solution allows nested interrupts disabling and restoring via local registers or stack. */ -/* They can be called from interrupts too. */ - static inline unsigned portENTER_CRITICAL_NESTED() - { - unsigned state = XTOS_SET_INTLEVEL( XCHAL_EXCM_LEVEL ); - - portbenchmarkINTERRUPT_DISABLE(); - return state; - } - #define portEXIT_CRITICAL_NESTED( state ) do { portbenchmarkINTERRUPT_RESTORE( state ); XTOS_RESTORE_JUST_INTLEVEL( state ); } while( 0 ) - -/* These FreeRTOS versions are similar to the nested versions above */ - #define portSET_INTERRUPT_MASK_FROM_ISR() portENTER_CRITICAL_NESTED() - #define portCLEAR_INTERRUPT_MASK_FROM_ISR( state ) portEXIT_CRITICAL_NESTED( state ) +// These cannot be nested. They should be used with a lot of care and cannot be called from interrupt level. +#define portDISABLE_INTERRUPTS() do { XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); portbenchmarkINTERRUPT_DISABLE(); } while (0) +#define portENABLE_INTERRUPTS() do { portbenchmarkINTERRUPT_RESTORE(0); XTOS_SET_INTLEVEL(0); } while (0) + +// These can be nested +#define portCRITICAL_NESTING_IN_TCB 1 // For now, let FreeRTOS' (tasks.c) manage critical nesting +void vTaskEnterCritical(void); +void vTaskExitCritical(void); +#define portENTER_CRITICAL() vTaskEnterCritical() +#define portEXIT_CRITICAL() vTaskExitCritical() + +// Cleaner and preferred solution allows nested interrupts disabling and restoring via local registers or stack. +// They can be called from interrupts too. +static inline unsigned portENTER_CRITICAL_NESTED() { unsigned state = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); portbenchmarkINTERRUPT_DISABLE(); return state; } +#define portEXIT_CRITICAL_NESTED(state) do { portbenchmarkINTERRUPT_RESTORE(state); XTOS_RESTORE_JUST_INTLEVEL(state); } while (0) + +// These FreeRTOS versions are similar to the nested versions above +#define portSET_INTERRUPT_MASK_FROM_ISR() portENTER_CRITICAL_NESTED() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(state) portEXIT_CRITICAL_NESTED(state) /*-----------------------------------------------------------*/ /* Architecture specifics. */ - #define portSTACK_GROWTH ( -1 ) - #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) - #define portBYTE_ALIGNMENT 4 - #define portNOP() XT_NOP() +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 4 +#define portNOP() XT_NOP() /*-----------------------------------------------------------*/ /* Fine resolution time */ - #define portGET_RUN_TIME_COUNTER_VALUE() xthal_get_ccount() +#define portGET_RUN_TIME_COUNTER_VALUE() xthal_get_ccount() /* Kernel utilities. */ - void vPortYield( void ); - void _frxt_setup_switch( void ); - #define portYIELD() vPortYield() - #define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) \ - if( ( xHigherPriorityTaskWoken ) != 0 ) { \ - _frxt_setup_switch(); \ +void vPortYield( void ); +void _frxt_setup_switch( void ); +#define portYIELD() vPortYield() +#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) \ + if ( ( xHigherPriorityTaskWoken ) != 0 ) { \ + _frxt_setup_switch(); \ } /*-----------------------------------------------------------*/ /* Task function macros as described on the FreeRTOS.org WEB site. */ - #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) - #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) - -/* When coprocessors are defined, we to maintain a pointer to coprocessors area. */ -/* We currently use a hack: redefine field xMPU_SETTINGS in TCB block as a structure that can hold: */ -/* MPU wrappers, coprocessor area pointer, trace code structure, and more if needed. */ -/* The field is normally used for memory protection. FreeRTOS should create another general purpose field. */ - typedef struct - { - #if XCHAL_CP_NUM > 0 - volatile StackType_t * coproc_area; /* Pointer to coprocessor save area; MUST BE FIRST */ - #endif - - #if portUSING_MPU_WRAPPERS - /* Define here mpu_settings, which is port dependent */ - int mpu_setting; /* Just a dummy example here; MPU not ported to Xtensa yet */ - #endif - - #if configUSE_TRACE_FACILITY_2 - struct - { - /* Cf. porttraceStamp() */ - int taskstamp; /* Stamp from inside task to see where we are */ - int taskstampcount; /* A counter usually incremented when we restart the task's loop */ - } porttrace; - #endif - } xMPU_SETTINGS; - -/* Main hack to use MPU_wrappers even when no MPU is defined (warning: mpu_setting should not be accessed; otherwise move this above xMPU_SETTINGS) */ - #if ( XCHAL_CP_NUM > 0 || configUSE_TRACE_FACILITY_2 ) && !portUSING_MPU_WRAPPERS /* If MPU wrappers not used, we still need to allocate coproc area */ - #undef portUSING_MPU_WRAPPERS - #define portUSING_MPU_WRAPPERS 1 /* Enable it to allocate coproc area */ - #define MPU_WRAPPERS_H /* Override mpu_wrapper.h to disable unwanted code */ - #define PRIVILEGED_FUNCTION - #define PRIVILEGED_DATA +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) + +// When coprocessors are defined, we to maintain a pointer to coprocessors area. +// We currently use a hack: redefine field xMPU_SETTINGS in TCB block as a structure that can hold: +// MPU wrappers, coprocessor area pointer, trace code structure, and more if needed. +// The field is normally used for memory protection. FreeRTOS should create another general purpose field. +typedef struct { + #if XCHAL_CP_NUM > 0 + volatile StackType_t* coproc_area; // Pointer to coprocessor save area; MUST BE FIRST #endif -/* porttrace */ - #if configUSE_TRACE_FACILITY_2 - #include "porttrace.h" + #if portUSING_MPU_WRAPPERS + // Define here mpu_settings, which is port dependent + int mpu_setting; // Just a dummy example here; MPU not ported to Xtensa yet #endif -/* configASSERT_2 if requested */ - #if configASSERT_2 - #include - void exit( int ); - #define configASSERT( x ) if( !( x ) ) { porttracePrint( -1 ); printf( "\nAssertion failed in %s:%d\n", __FILE__, __LINE__ ); exit( -1 ); } + #if configUSE_TRACE_FACILITY_2 + struct { + // Cf. porttraceStamp() + int taskstamp; /* Stamp from inside task to see where we are */ + int taskstampcount; /* A counter usually incremented when we restart the task's loop */ + } porttrace; #endif +} xMPU_SETTINGS; + +// Main hack to use MPU_wrappers even when no MPU is defined (warning: mpu_setting should not be accessed; otherwise move this above xMPU_SETTINGS) +#if (XCHAL_CP_NUM > 0 || configUSE_TRACE_FACILITY_2) && !portUSING_MPU_WRAPPERS // If MPU wrappers not used, we still need to allocate coproc area + #undef portUSING_MPU_WRAPPERS + #define portUSING_MPU_WRAPPERS 1 // Enable it to allocate coproc area + #define MPU_WRAPPERS_H // Override mpu_wrapper.h to disable unwanted code + #define PRIVILEGED_FUNCTION + #define PRIVILEGED_DATA +#endif + +// porttrace +#if configUSE_TRACE_FACILITY_2 +#include "porttrace.h" +#endif + +// configASSERT_2 if requested +#if configASSERT_2 +#include +void exit(int); +#define configASSERT( x ) if (!(x)) { porttracePrint(-1); printf("\nAssertion failed in %s:%d\n", __FILE__, __LINE__); exit(-1); } +#endif /* C library support -- only XCLIB and NEWLIB are supported. */ /* To enable thread-safe C library support, XT_USE_THREAD_SAFE_CLIB must be - * defined to be > 0 somewhere above or on the command line. */ - - #if ( XT_USE_THREAD_SAFE_CLIB > 0u ) && ( XSHAL_CLIB == XTHAL_CLIB_XCLIB ) - extern void vPortClibInit( void ); - #endif // XCLIB support - - #if ( XT_USE_THREAD_SAFE_CLIB > 0u ) && ( XSHAL_CLIB == XTHAL_CLIB_NEWLIB ) - extern void vPortClibInit( void ); - -/* This C library cleanup is not currently done by FreeRTOS when deleting a task */ - #include - #define portCLEAN_UP_TCB( pxTCB ) vPortCleanUpTcbClib( &( ( pxTCB )->xNewLib_reent ) ) - static inline void vPortCleanUpTcbClib( struct _reent * ptr ) - { - FILE * fp = &( ptr->__sf[ 0 ] ); - int i; - - for( i = 0; i < 3; ++i, ++fp ) - { - fp->_close = NULL; - } - } - #endif // NEWLIB support + defined to be > 0 somewhere above or on the command line. */ + +#if (XT_USE_THREAD_SAFE_CLIB > 0u) && (XSHAL_CLIB == XTHAL_CLIB_XCLIB) +extern void vPortClibInit(void); +#endif // XCLIB support + +#if (XT_USE_THREAD_SAFE_CLIB > 0u) && (XSHAL_CLIB == XTHAL_CLIB_NEWLIB) +extern void vPortClibInit(void); + +// This C library cleanup is not currently done by FreeRTOS when deleting a task +#include +#define portCLEAN_UP_TCB(pxTCB) vPortCleanUpTcbClib(&((pxTCB)->xNewLib_reent)) +static inline void vPortCleanUpTcbClib(struct _reent *ptr) +{ + FILE * fp = &(ptr->__sf[0]); + int i; + for (i = 0; i < 3; ++i, ++fp) { + fp->_close = NULL; + } +} +#endif // NEWLIB support #endif // __ASSEMBLER__ diff --git a/portable/ThirdParty/XCC/Xtensa/porttrace.h b/portable/ThirdParty/XCC/Xtensa/porttrace.h index 7a2ad1d53..9909ec3af 100644 --- a/portable/ThirdParty/XCC/Xtensa/porttrace.h +++ b/portable/ThirdParty/XCC/Xtensa/porttrace.h @@ -1,4 +1,4 @@ -/* + /* * FreeRTOS Kernel * Copyright (C) 2015-2019 Cadence Design Systems, Inc. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -43,7 +43,7 @@ #error "You need to download the FreeRTOS_trace patch that overwrites this file" #endif -#define porttracePrint( nelements ) -#define porttraceStamp( stamp, count_incr ) +#define porttracePrint(nelements) +#define porttraceStamp(stamp, count_incr) #endif /* PORTTRACE_H */ diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_api.h b/portable/ThirdParty/XCC/Xtensa/xtensa_api.h index bf2834f09..703449f2b 100644 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_api.h +++ b/portable/ThirdParty/XCC/Xtensa/xtensa_api.h @@ -1,4 +1,4 @@ -/* + /* * FreeRTOS Kernel * Copyright (C) 2015-2019 Cadence Design Systems, Inc. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -40,90 +40,87 @@ /* Typedef for C-callable interrupt handler function */ -typedef void (* xt_handler)( void * ); +typedef void (*xt_handler)(void *); /* Typedef for C-callable exception handler function */ -typedef void (* xt_exc_handler)( XtExcFrame * ); +typedef void (*xt_exc_handler)(XtExcFrame *); /* - * ------------------------------------------------------------------------------- - * Call this function to set a handler for the specified exception. - * - * n - Exception number (type) - * f - Handler function address, NULL to uninstall handler. - * - * The handler will be passed a pointer to the exception frame, which is created - * on the stack of the thread that caused the exception. - * - * If the handler returns, the thread context will be restored and the faulting - * instruction will be retried. Any values in the exception frame that are - * modified by the handler will be restored as part of the context. For details - * of the exception frame structure see xtensa_context.h. - * ------------------------------------------------------------------------------- - */ -extern xt_exc_handler xt_set_exception_handler( int n, - xt_exc_handler f ); +------------------------------------------------------------------------------- + Call this function to set a handler for the specified exception. + + n - Exception number (type) + f - Handler function address, NULL to uninstall handler. + + The handler will be passed a pointer to the exception frame, which is created + on the stack of the thread that caused the exception. + + If the handler returns, the thread context will be restored and the faulting + instruction will be retried. Any values in the exception frame that are + modified by the handler will be restored as part of the context. For details + of the exception frame structure see xtensa_context.h. +------------------------------------------------------------------------------- +*/ +extern xt_exc_handler xt_set_exception_handler(int n, xt_exc_handler f); /* - * ------------------------------------------------------------------------------- - * Call this function to set a handler for the specified interrupt. - * - * n - Interrupt number. - * f - Handler function address, NULL to uninstall handler. - * arg - Argument to be passed to handler. - * ------------------------------------------------------------------------------- - */ -extern xt_handler xt_set_interrupt_handler( int n, - xt_handler f, - void * arg ); +------------------------------------------------------------------------------- + Call this function to set a handler for the specified interrupt. + + n - Interrupt number. + f - Handler function address, NULL to uninstall handler. + arg - Argument to be passed to handler. +------------------------------------------------------------------------------- +*/ +extern xt_handler xt_set_interrupt_handler(int n, xt_handler f, void * arg); /* - * ------------------------------------------------------------------------------- - * Call this function to enable the specified interrupts. - * - * mask - Bit mask of interrupts to be enabled. - * - * Returns the previous state of the interrupt enables. - * ------------------------------------------------------------------------------- - */ -extern unsigned int xt_ints_on( unsigned int mask ); +------------------------------------------------------------------------------- + Call this function to enable the specified interrupts. + + mask - Bit mask of interrupts to be enabled. + + Returns the previous state of the interrupt enables. +------------------------------------------------------------------------------- +*/ +extern unsigned int xt_ints_on(unsigned int mask); /* - * ------------------------------------------------------------------------------- - * Call this function to disable the specified interrupts. - * - * mask - Bit mask of interrupts to be disabled. - * - * Returns the previous state of the interrupt enables. - * ------------------------------------------------------------------------------- - */ -extern unsigned int xt_ints_off( unsigned int mask ); +------------------------------------------------------------------------------- + Call this function to disable the specified interrupts. + + mask - Bit mask of interrupts to be disabled. + + Returns the previous state of the interrupt enables. +------------------------------------------------------------------------------- +*/ +extern unsigned int xt_ints_off(unsigned int mask); /* - * ------------------------------------------------------------------------------- - * Call this function to set the specified (s/w) interrupt. - * ------------------------------------------------------------------------------- - */ -static inline void xt_set_intset( unsigned int arg ) +------------------------------------------------------------------------------- + Call this function to set the specified (s/w) interrupt. +------------------------------------------------------------------------------- +*/ +static inline void xt_set_intset(unsigned int arg) { - xthal_set_intset( arg ); + xthal_set_intset(arg); } /* - * ------------------------------------------------------------------------------- - * Call this function to clear the specified (s/w or edge-triggered) - * interrupt. - * ------------------------------------------------------------------------------- - */ -static inline void xt_set_intclear( unsigned int arg ) +------------------------------------------------------------------------------- + Call this function to clear the specified (s/w or edge-triggered) + interrupt. +------------------------------------------------------------------------------- +*/ +static inline void xt_set_intclear(unsigned int arg) { - xthal_set_intclear( arg ); + xthal_set_intclear(arg); } diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_config.h b/portable/ThirdParty/XCC/Xtensa/xtensa_config.h index cf80f8190..a5efcda58 100644 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_config.h +++ b/portable/ThirdParty/XCC/Xtensa/xtensa_config.h @@ -1,4 +1,4 @@ -/* + /* * FreeRTOS Kernel * Copyright (C) 2015-2019 Cadence Design Systems, Inc. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -47,139 +47,139 @@ #include #include -#include /* required for XSHAL_CLIB */ +#include /* required for XSHAL_CLIB */ #include "xtensa_context.h" /*----------------------------------------------------------------------------- - * STACK REQUIREMENTS - * - * This section defines the minimum stack size, and the extra space required to - * be allocated for saving coprocessor state and/or C library state information - * (if thread safety is enabled for the C library). The sizes are in bytes. - * - * Stack sizes for individual tasks should be derived from these minima based on - * the maximum call depth of the task and the maximum level of interrupt nesting. - * A minimum stack size is defined by XT_STACK_MIN_SIZE. This minimum is based - * on the requirement for a task that calls nothing else but can be interrupted. - * This assumes that interrupt handlers do not call more than a few levels deep. - * If this is not true, i.e. one or more interrupt handlers make deep calls then - * the minimum must be increased. - * - * If the Xtensa processor configuration includes coprocessors, then space is - * allocated to save the coprocessor state on the stack. - * - * If thread safety is enabled for the C runtime library, (XT_USE_THREAD_SAFE_CLIB - * is defined) then space is allocated to save the C library context in the TCB. - * - * Allocating insufficient stack space is a common source of hard-to-find errors. - * During development, it is best to enable the FreeRTOS stack checking features. - * - * Usage: - * - * XT_USE_THREAD_SAFE_CLIB -- Define this to a nonzero value to enable thread-safe - * use of the C library. This will require extra stack - * space to be allocated for tasks that use the C library - * reentrant functions. See below for more information. - * - * NOTE: The Xtensa toolchain supports multiple C libraries and not all of them - * support thread safety. Check your core configuration to see which C library - * was chosen for your system. - * - * XT_STACK_MIN_SIZE -- The minimum stack size for any task. It is recommended - * that you do not use a stack smaller than this for any - * task. In case you want to use stacks smaller than this - * size, you must verify that the smaller size(s) will work - * under all operating conditions. - * - * XT_STACK_EXTRA -- The amount of extra stack space to allocate for a task - * that does not make C library reentrant calls. Add this - * to the amount of stack space required by the task itself. - * - * XT_STACK_EXTRA_CLIB -- The amount of space to allocate for C library state. - * - * -----------------------------------------------------------------------------*/ +* STACK REQUIREMENTS +* +* This section defines the minimum stack size, and the extra space required to +* be allocated for saving coprocessor state and/or C library state information +* (if thread safety is enabled for the C library). The sizes are in bytes. +* +* Stack sizes for individual tasks should be derived from these minima based on +* the maximum call depth of the task and the maximum level of interrupt nesting. +* A minimum stack size is defined by XT_STACK_MIN_SIZE. This minimum is based +* on the requirement for a task that calls nothing else but can be interrupted. +* This assumes that interrupt handlers do not call more than a few levels deep. +* If this is not true, i.e. one or more interrupt handlers make deep calls then +* the minimum must be increased. +* +* If the Xtensa processor configuration includes coprocessors, then space is +* allocated to save the coprocessor state on the stack. +* +* If thread safety is enabled for the C runtime library, (XT_USE_THREAD_SAFE_CLIB +* is defined) then space is allocated to save the C library context in the TCB. +* +* Allocating insufficient stack space is a common source of hard-to-find errors. +* During development, it is best to enable the FreeRTOS stack checking features. +* +* Usage: +* +* XT_USE_THREAD_SAFE_CLIB -- Define this to a nonzero value to enable thread-safe +* use of the C library. This will require extra stack +* space to be allocated for tasks that use the C library +* reentrant functions. See below for more information. +* +* NOTE: The Xtensa toolchain supports multiple C libraries and not all of them +* support thread safety. Check your core configuration to see which C library +* was chosen for your system. +* +* XT_STACK_MIN_SIZE -- The minimum stack size for any task. It is recommended +* that you do not use a stack smaller than this for any +* task. In case you want to use stacks smaller than this +* size, you must verify that the smaller size(s) will work +* under all operating conditions. +* +* XT_STACK_EXTRA -- The amount of extra stack space to allocate for a task +* that does not make C library reentrant calls. Add this +* to the amount of stack space required by the task itself. +* +* XT_STACK_EXTRA_CLIB -- The amount of space to allocate for C library state. +* +-----------------------------------------------------------------------------*/ /* Extra space required for interrupt/exception hooks. */ #ifdef XT_INTEXC_HOOKS - #ifdef __XTENSA_CALL0_ABI__ - #define STK_INTEXC_EXTRA 0x200 - #else - #define STK_INTEXC_EXTRA 0x180 - #endif + #ifdef __XTENSA_CALL0_ABI__ + #define STK_INTEXC_EXTRA 0x200 + #else + #define STK_INTEXC_EXTRA 0x180 + #endif #else - #define STK_INTEXC_EXTRA 0 + #define STK_INTEXC_EXTRA 0 #endif /* Check C library thread safety support and compute size of C library save area. - * For the supported libraries, we enable thread safety by default, and this can - * be overridden from the compiler/make command line. */ -#if ( XSHAL_CLIB == XTHAL_CLIB_NEWLIB ) || ( XSHAL_CLIB == XTHAL_CLIB_XCLIB ) - #ifndef XT_USE_THREAD_SAFE_CLIB - #define XT_USE_THREAD_SAFE_CLIB 1 - #endif + For the supported libraries, we enable thread safety by default, and this can + be overridden from the compiler/make command line. */ +#if (XSHAL_CLIB == XTHAL_CLIB_NEWLIB) || (XSHAL_CLIB == XTHAL_CLIB_XCLIB) + #ifndef XT_USE_THREAD_SAFE_CLIB + #define XT_USE_THREAD_SAFE_CLIB 1 + #endif #else - #define XT_USE_THREAD_SAFE_CLIB 0 + #define XT_USE_THREAD_SAFE_CLIB 0 #endif #if XT_USE_THREAD_SAFE_CLIB > 0u - #if XSHAL_CLIB == XTHAL_CLIB_XCLIB - #define XT_HAVE_THREAD_SAFE_CLIB 1 - #if !defined __ASSEMBLER__ - #include - #define XT_CLIB_CONTEXT_AREA_SIZE ( ( sizeof( struct _reent ) + 15 ) + ( -16 ) ) - #define XT_CLIB_GLOBAL_PTR _reent_ptr - #define _REENT_INIT_PTR _init_reent - #define _impure_ptr _reent_ptr - - void _reclaim_reent( void * ptr ); - #endif - #elif XSHAL_CLIB == XTHAL_CLIB_NEWLIB - #define XT_HAVE_THREAD_SAFE_CLIB 1 - #if !defined __ASSEMBLER__ - #include - #define XT_CLIB_CONTEXT_AREA_SIZE ( ( sizeof( struct _reent ) + 15 ) + ( -16 ) ) - #define XT_CLIB_GLOBAL_PTR _impure_ptr - #endif - #else /* if XSHAL_CLIB == XTHAL_CLIB_XCLIB */ - #define XT_HAVE_THREAD_SAFE_CLIB 0 - #error The selected C runtime library is not thread safe. - #endif /* if XSHAL_CLIB == XTHAL_CLIB_XCLIB */ -#else /* if XT_USE_THREAD_SAFE_CLIB > 0u */ - #define XT_CLIB_CONTEXT_AREA_SIZE 0 -#endif /* if XT_USE_THREAD_SAFE_CLIB > 0u */ + #if XSHAL_CLIB == XTHAL_CLIB_XCLIB + #define XT_HAVE_THREAD_SAFE_CLIB 1 + #if !defined __ASSEMBLER__ + #include + #define XT_CLIB_CONTEXT_AREA_SIZE ((sizeof(struct _reent) + 15) + (-16)) + #define XT_CLIB_GLOBAL_PTR _reent_ptr + #define _REENT_INIT_PTR _init_reent + #define _impure_ptr _reent_ptr + + void _reclaim_reent(void * ptr); + #endif + #elif XSHAL_CLIB == XTHAL_CLIB_NEWLIB + #define XT_HAVE_THREAD_SAFE_CLIB 1 + #if !defined __ASSEMBLER__ + #include + #define XT_CLIB_CONTEXT_AREA_SIZE ((sizeof(struct _reent) + 15) + (-16)) + #define XT_CLIB_GLOBAL_PTR _impure_ptr + #endif + #else + #define XT_HAVE_THREAD_SAFE_CLIB 0 + #error The selected C runtime library is not thread safe. + #endif +#else + #define XT_CLIB_CONTEXT_AREA_SIZE 0 +#endif /*------------------------------------------------------------------------------ - * Extra size -- interrupt frame plus coprocessor save area plus hook space. - * NOTE: Make sure XT_INTEXC_HOOKS is undefined unless you really need the hooks. - * ------------------------------------------------------------------------------*/ + Extra size -- interrupt frame plus coprocessor save area plus hook space. + NOTE: Make sure XT_INTEXC_HOOKS is undefined unless you really need the hooks. +------------------------------------------------------------------------------*/ #ifdef __XTENSA_CALL0_ABI__ - #define XT_XTRA_SIZE ( XT_STK_FRMSZ + STK_INTEXC_EXTRA + 0x10 + XT_CP_SIZE ) + #define XT_XTRA_SIZE (XT_STK_FRMSZ + STK_INTEXC_EXTRA + 0x10 + XT_CP_SIZE) #else - #define XT_XTRA_SIZE ( XT_STK_FRMSZ + STK_INTEXC_EXTRA + 0x20 + XT_CP_SIZE ) + #define XT_XTRA_SIZE (XT_STK_FRMSZ + STK_INTEXC_EXTRA + 0x20 + XT_CP_SIZE) #endif /*------------------------------------------------------------------------------ - * Space allocated for user code -- function calls and local variables. - * NOTE: This number can be adjusted to suit your needs. You must verify that the - * amount of space you reserve is adequate for the worst-case conditions in your - * application. - * NOTE: The windowed ABI requires more stack, since space has to be reserved - * for spilling register windows. - * ------------------------------------------------------------------------------*/ + Space allocated for user code -- function calls and local variables. + NOTE: This number can be adjusted to suit your needs. You must verify that the + amount of space you reserve is adequate for the worst-case conditions in your + application. + NOTE: The windowed ABI requires more stack, since space has to be reserved + for spilling register windows. +------------------------------------------------------------------------------*/ #ifdef __XTENSA_CALL0_ABI__ - #define XT_USER_SIZE 0x200 + #define XT_USER_SIZE 0x200 #else - #define XT_USER_SIZE 0x400 + #define XT_USER_SIZE 0x400 #endif /* Minimum recommended stack size. */ -#define XT_STACK_MIN_SIZE ( ( XT_XTRA_SIZE + XT_USER_SIZE ) / sizeof( unsigned char ) ) +#define XT_STACK_MIN_SIZE ((XT_XTRA_SIZE + XT_USER_SIZE) / sizeof(unsigned char)) /* OS overhead with and without C library thread context. */ -#define XT_STACK_EXTRA ( XT_XTRA_SIZE ) -#define XT_STACK_EXTRA_CLIB ( XT_XTRA_SIZE + XT_CLIB_CONTEXT_AREA_SIZE ) +#define XT_STACK_EXTRA (XT_XTRA_SIZE) +#define XT_STACK_EXTRA_CLIB (XT_XTRA_SIZE + XT_CLIB_CONTEXT_AREA_SIZE) /* *INDENT-OFF* */ diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_context.h b/portable/ThirdParty/XCC/Xtensa/xtensa_context.h index 5d243d3c0..579c62ea2 100644 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_context.h +++ b/portable/ThirdParty/XCC/Xtensa/xtensa_context.h @@ -1,4 +1,4 @@ -/* + /* * FreeRTOS Kernel * Copyright (C) 2015-2019 Cadence Design Systems, Inc. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -44,7 +44,7 @@ #define XTENSA_CONTEXT_H #ifdef __ASSEMBLER__ - #include +#include #endif #include @@ -53,307 +53,303 @@ /* Align a value up to nearest n-byte boundary, where n is a power of 2. */ -#define ALIGNUP( n, val ) ( ( ( val ) + ( n ) - 1 ) & -( n ) ) +#define ALIGNUP(n, val) (((val) + (n)-1) & -(n)) /* - * ------------------------------------------------------------------------------- - * Macros that help define structures for both C and assembler. - * ------------------------------------------------------------------------------- - */ -#if defined( _ASMLANGUAGE ) || defined( __ASSEMBLER__ ) +------------------------------------------------------------------------------- + Macros that help define structures for both C and assembler. +------------------------------------------------------------------------------- +*/ +#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) - #define STRUCT_BEGIN .pushsection.text; .struct 0 - #define STRUCT_FIELD( ctype, size, asname, name ) asname :.space size - #define STRUCT_AFIELD( ctype, size, asname, name, n ) asname :.space( size ) *( n ) - #define STRUCT_END( sname ) sname ## Size:; .popsection +#define STRUCT_BEGIN .pushsection .text; .struct 0 +#define STRUCT_FIELD(ctype,size,asname,name) asname: .space size +#define STRUCT_AFIELD(ctype,size,asname,name,n) asname: .space (size)*(n) +#define STRUCT_END(sname) sname##Size:; .popsection #else - #define STRUCT_BEGIN typedef struct { - #define STRUCT_FIELD( ctype, size, asname, name ) ctype name; - #define STRUCT_AFIELD( ctype, size, asname, name, n ) ctype name[ n ]; - #define STRUCT_END( sname ) \ -} \ - sname; +#define STRUCT_BEGIN typedef struct { +#define STRUCT_FIELD(ctype,size,asname,name) ctype name; +#define STRUCT_AFIELD(ctype,size,asname,name,n) ctype name[n]; +#define STRUCT_END(sname) } sname; #endif //_ASMLANGUAGE || __ASSEMBLER__ /* - * ------------------------------------------------------------------------------- - * INTERRUPT/EXCEPTION STACK FRAME FOR A THREAD OR NESTED INTERRUPT - * - * A stack frame of this structure is allocated for any interrupt or exception. - * It goes on the current stack. If the RTOS has a system stack for handling - * interrupts, every thread stack must allow space for just one interrupt stack - * frame, then nested interrupt stack frames go on the system stack. - * - * The frame includes basic registers (explicit) and "extra" registers introduced - * by user TIE or the use of the MAC16 option in the user's Xtensa config. - * The frame size is minimized by omitting regs not applicable to user's config. - * - * For Windowed ABI, this stack frame includes the interruptee's base save area, - * another base save area to manage gcc nested functions, and a little temporary - * space to help manage the spilling of the register windows. - * ------------------------------------------------------------------------------- - */ +------------------------------------------------------------------------------- + INTERRUPT/EXCEPTION STACK FRAME FOR A THREAD OR NESTED INTERRUPT -STRUCT_BEGIN STRUCT_FIELD( long, - 4, - XT_STK_EXIT, - exit ) /* exit point for dispatch */ -STRUCT_FIELD( long, 4, XT_STK_PC, pc ) /* return PC */ -STRUCT_FIELD( long, 4, XT_STK_PS, ps ) /* return PS */ -STRUCT_FIELD( long, 4, XT_STK_A0, a0 ) -STRUCT_FIELD( long, 4, XT_STK_A1, a1 ) /* stack pointer before interrupt */ -STRUCT_FIELD( long, 4, XT_STK_A2, a2 ) -STRUCT_FIELD( long, 4, XT_STK_A3, a3 ) -STRUCT_FIELD( long, 4, XT_STK_A4, a4 ) -STRUCT_FIELD( long, 4, XT_STK_A5, a5 ) -STRUCT_FIELD( long, 4, XT_STK_A6, a6 ) -STRUCT_FIELD( long, 4, XT_STK_A7, a7 ) -STRUCT_FIELD( long, 4, XT_STK_A8, a8 ) -STRUCT_FIELD( long, 4, XT_STK_A9, a9 ) -STRUCT_FIELD( long, 4, XT_STK_A10, a10 ) -STRUCT_FIELD( long, 4, XT_STK_A11, a11 ) -STRUCT_FIELD( long, 4, XT_STK_A12, a12 ) -STRUCT_FIELD( long, 4, XT_STK_A13, a13 ) -STRUCT_FIELD( long, 4, XT_STK_A14, a14 ) -STRUCT_FIELD( long, 4, XT_STK_A15, a15 ) -STRUCT_FIELD( long, 4, XT_STK_SAR, sar ) -STRUCT_FIELD( long, 4, XT_STK_EXCCAUSE, exccause ) -STRUCT_FIELD( long, 4, XT_STK_EXCVADDR, excvaddr ) + A stack frame of this structure is allocated for any interrupt or exception. + It goes on the current stack. If the RTOS has a system stack for handling + interrupts, every thread stack must allow space for just one interrupt stack + frame, then nested interrupt stack frames go on the system stack. + + The frame includes basic registers (explicit) and "extra" registers introduced + by user TIE or the use of the MAC16 option in the user's Xtensa config. + The frame size is minimized by omitting regs not applicable to user's config. + + For Windowed ABI, this stack frame includes the interruptee's base save area, + another base save area to manage gcc nested functions, and a little temporary + space to help manage the spilling of the register windows. +------------------------------------------------------------------------------- +*/ + +STRUCT_BEGIN +STRUCT_FIELD (long, 4, XT_STK_EXIT, exit) /* exit point for dispatch */ +STRUCT_FIELD (long, 4, XT_STK_PC, pc) /* return PC */ +STRUCT_FIELD (long, 4, XT_STK_PS, ps) /* return PS */ +STRUCT_FIELD (long, 4, XT_STK_A0, a0) +STRUCT_FIELD (long, 4, XT_STK_A1, a1) /* stack pointer before interrupt */ +STRUCT_FIELD (long, 4, XT_STK_A2, a2) +STRUCT_FIELD (long, 4, XT_STK_A3, a3) +STRUCT_FIELD (long, 4, XT_STK_A4, a4) +STRUCT_FIELD (long, 4, XT_STK_A5, a5) +STRUCT_FIELD (long, 4, XT_STK_A6, a6) +STRUCT_FIELD (long, 4, XT_STK_A7, a7) +STRUCT_FIELD (long, 4, XT_STK_A8, a8) +STRUCT_FIELD (long, 4, XT_STK_A9, a9) +STRUCT_FIELD (long, 4, XT_STK_A10, a10) +STRUCT_FIELD (long, 4, XT_STK_A11, a11) +STRUCT_FIELD (long, 4, XT_STK_A12, a12) +STRUCT_FIELD (long, 4, XT_STK_A13, a13) +STRUCT_FIELD (long, 4, XT_STK_A14, a14) +STRUCT_FIELD (long, 4, XT_STK_A15, a15) +STRUCT_FIELD (long, 4, XT_STK_SAR, sar) +STRUCT_FIELD (long, 4, XT_STK_EXCCAUSE, exccause) +STRUCT_FIELD (long, 4, XT_STK_EXCVADDR, excvaddr) #if XCHAL_HAVE_LOOPS - STRUCT_FIELD( long, 4, XT_STK_LBEG, lbeg ) - STRUCT_FIELD( long, 4, XT_STK_LEND, lend ) - STRUCT_FIELD( long, 4, XT_STK_LCOUNT, lcount ) +STRUCT_FIELD (long, 4, XT_STK_LBEG, lbeg) +STRUCT_FIELD (long, 4, XT_STK_LEND, lend) +STRUCT_FIELD (long, 4, XT_STK_LCOUNT, lcount) #endif #ifndef __XTENSA_CALL0_ABI__ /* Temporary space for saving stuff during window spill */ - STRUCT_FIELD( long, 4, XT_STK_TMP0, tmp0 ) - STRUCT_FIELD( long, 4, XT_STK_TMP1, tmp1 ) - STRUCT_FIELD( long, 4, XT_STK_TMP2, tmp2 ) +STRUCT_FIELD (long, 4, XT_STK_TMP0, tmp0) +STRUCT_FIELD (long, 4, XT_STK_TMP1, tmp1) +STRUCT_FIELD (long, 4, XT_STK_TMP2, tmp2) #endif #ifdef XT_USE_SWPRI /* Storage for virtual priority mask */ - STRUCT_FIELD( long, 4, XT_STK_VPRI, vpri ) +STRUCT_FIELD (long, 4, XT_STK_VPRI, vpri) #endif #ifdef XT_USE_OVLY /* Storage for overlay state */ - STRUCT_FIELD( long, 4, XT_STK_OVLY, ovly ) +STRUCT_FIELD (long, 4, XT_STK_OVLY, ovly) #endif -STRUCT_END( XtExcFrame ) +STRUCT_END(XtExcFrame) -#if defined( _ASMLANGUAGE ) || defined( __ASSEMBLER__ ) -#define XT_STK_NEXT1 XtExcFrameSize +#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) +#define XT_STK_NEXT1 XtExcFrameSize #else -#define XT_STK_NEXT1 sizeof( XtExcFrame ) +#define XT_STK_NEXT1 sizeof(XtExcFrame) #endif /* Allocate extra storage if needed */ #if XCHAL_EXTRA_SA_SIZE != 0 - #if XCHAL_EXTRA_SA_ALIGN <= 16 -#define XT_STK_EXTRA ALIGNUP( XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1 ) - #else +#if XCHAL_EXTRA_SA_ALIGN <= 16 +#define XT_STK_EXTRA ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1) +#else /* If need more alignment than stack, add space for dynamic alignment */ -#define XT_STK_EXTRA ( ALIGNUP( XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1 ) + XCHAL_EXTRA_SA_ALIGN ) - #endif -#define XT_STK_NEXT2 ( XT_STK_EXTRA + XCHAL_EXTRA_SA_SIZE ) +#define XT_STK_EXTRA (ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1) + XCHAL_EXTRA_SA_ALIGN) +#endif +#define XT_STK_NEXT2 (XT_STK_EXTRA + XCHAL_EXTRA_SA_SIZE) #else -#define XT_STK_NEXT2 XT_STK_NEXT1 +#define XT_STK_NEXT2 XT_STK_NEXT1 -#endif /* if XCHAL_EXTRA_SA_SIZE != 0 */ +#endif /* - * ------------------------------------------------------------------------------- - * This is the frame size. Add space for 4 registers (interruptee's base save - * area) and some space for gcc nested functions if any. - * ------------------------------------------------------------------------------- - */ -#define XT_STK_FRMSZ ( ALIGNUP( 0x10, XT_STK_NEXT2 ) + 0x20 ) +------------------------------------------------------------------------------- + This is the frame size. Add space for 4 registers (interruptee's base save + area) and some space for gcc nested functions if any. +------------------------------------------------------------------------------- +*/ +#define XT_STK_FRMSZ (ALIGNUP(0x10, XT_STK_NEXT2) + 0x20) /* - * ------------------------------------------------------------------------------- - * SOLICITED STACK FRAME FOR A THREAD - * - * A stack frame of this structure is allocated whenever a thread enters the - * RTOS kernel intentionally (and synchronously) to submit to thread scheduling. - * It goes on the current thread's stack. - * - * The solicited frame only includes registers that are required to be preserved - * by the callee according to the compiler's ABI conventions, some space to save - * the return address for returning to the caller, and the caller's PS register. - * - * For Windowed ABI, this stack frame includes the caller's base save area. - * - * Note on XT_SOL_EXIT field: - * It is necessary to distinguish a solicited from an interrupt stack frame. - * This field corresponds to XT_STK_EXIT in the interrupt stack frame and is - * always at the same offset (0). It can be written with a code (usually 0) - * to distinguish a solicted frame from an interrupt frame. An RTOS port may - * opt to ignore this field if it has another way of distinguishing frames. - * ------------------------------------------------------------------------------- - */ +------------------------------------------------------------------------------- + SOLICITED STACK FRAME FOR A THREAD + + A stack frame of this structure is allocated whenever a thread enters the + RTOS kernel intentionally (and synchronously) to submit to thread scheduling. + It goes on the current thread's stack. + + The solicited frame only includes registers that are required to be preserved + by the callee according to the compiler's ABI conventions, some space to save + the return address for returning to the caller, and the caller's PS register. + + For Windowed ABI, this stack frame includes the caller's base save area. + + Note on XT_SOL_EXIT field: + It is necessary to distinguish a solicited from an interrupt stack frame. + This field corresponds to XT_STK_EXIT in the interrupt stack frame and is + always at the same offset (0). It can be written with a code (usually 0) + to distinguish a solicted frame from an interrupt frame. An RTOS port may + opt to ignore this field if it has another way of distinguishing frames. +------------------------------------------------------------------------------- +*/ STRUCT_BEGIN #ifdef __XTENSA_CALL0_ABI__ - STRUCT_FIELD( long, 4, XT_SOL_EXIT, exit ) - STRUCT_FIELD( long, 4, XT_SOL_PC, pc ) - STRUCT_FIELD( long, 4, XT_SOL_PS, ps ) - STRUCT_FIELD( long, 4, XT_SOL_NEXT, next ) - STRUCT_FIELD( long, 4, XT_SOL_A12, a12 ) /* should be on 16-byte alignment */ - STRUCT_FIELD( long, 4, XT_SOL_A13, a13 ) - STRUCT_FIELD( long, 4, XT_SOL_A14, a14 ) - STRUCT_FIELD( long, 4, XT_SOL_A15, a15 ) +STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit) +STRUCT_FIELD (long, 4, XT_SOL_PC, pc) +STRUCT_FIELD (long, 4, XT_SOL_PS, ps) +STRUCT_FIELD (long, 4, XT_SOL_NEXT, next) +STRUCT_FIELD (long, 4, XT_SOL_A12, a12) /* should be on 16-byte alignment */ +STRUCT_FIELD (long, 4, XT_SOL_A13, a13) +STRUCT_FIELD (long, 4, XT_SOL_A14, a14) +STRUCT_FIELD (long, 4, XT_SOL_A15, a15) #else - STRUCT_FIELD( long, 4, XT_SOL_EXIT, exit ) - STRUCT_FIELD( long, 4, XT_SOL_PC, pc ) - STRUCT_FIELD( long, 4, XT_SOL_PS, ps ) - STRUCT_FIELD( long, 4, XT_SOL_NEXT, next ) - STRUCT_FIELD( long, 4, XT_SOL_A0, a0 ) /* should be on 16-byte alignment */ - STRUCT_FIELD( long, 4, XT_SOL_A1, a1 ) - STRUCT_FIELD( long, 4, XT_SOL_A2, a2 ) - STRUCT_FIELD( long, 4, XT_SOL_A3, a3 ) -#endif /* ifdef __XTENSA_CALL0_ABI__ */ -STRUCT_END( XtSolFrame ) +STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit) +STRUCT_FIELD (long, 4, XT_SOL_PC, pc) +STRUCT_FIELD (long, 4, XT_SOL_PS, ps) +STRUCT_FIELD (long, 4, XT_SOL_NEXT, next) +STRUCT_FIELD (long, 4, XT_SOL_A0, a0) /* should be on 16-byte alignment */ +STRUCT_FIELD (long, 4, XT_SOL_A1, a1) +STRUCT_FIELD (long, 4, XT_SOL_A2, a2) +STRUCT_FIELD (long, 4, XT_SOL_A3, a3) +#endif +STRUCT_END(XtSolFrame) /* Size of solicited stack frame */ -#define XT_SOL_FRMSZ ALIGNUP( 0x10, XtSolFrameSize ) +#define XT_SOL_FRMSZ ALIGNUP(0x10, XtSolFrameSize) /* - * ------------------------------------------------------------------------------- - * CO-PROCESSOR STATE SAVE AREA FOR A THREAD - * - * The RTOS must provide an area per thread to save the state of co-processors - * when that thread does not have control. Co-processors are context-switched - * lazily (on demand) only when a new thread uses a co-processor instruction, - * otherwise a thread retains ownership of the co-processor even when it loses - * control of the processor. An Xtensa co-processor exception is triggered when - * any co-processor instruction is executed by a thread that is not the owner, - * and the context switch of that co-processor is then peformed by the handler. - * Ownership represents which thread's state is currently in the co-processor. - * - * Co-processors may not be used by interrupt or exception handlers. If an - * co-processor instruction is executed by an interrupt or exception handler, - * the co-processor exception handler will trigger a kernel panic and freeze. - * This restriction is introduced to reduce the overhead of saving and restoring - * co-processor state (which can be quite large) and in particular remove that - * overhead from interrupt handlers. - * - * The co-processor state save area may be in any convenient per-thread location - * such as in the thread control block or above the thread stack area. It need - * not be in the interrupt stack frame since interrupts don't use co-processors. - * - * Along with the save area for each co-processor, two bitmasks with flags per - * co-processor (laid out as in the CPENABLE reg) help manage context-switching - * co-processors as efficiently as possible: - * - * XT_CPENABLE - * The contents of a non-running thread's CPENABLE register. - * It represents the co-processors owned (and whose state is still needed) - * by the thread. When a thread is preempted, its CPENABLE is saved here. - * When a thread solicits a context-swtich, its CPENABLE is cleared - the - * compiler has saved the (caller-saved) co-proc state if it needs to. - * When a non-running thread loses ownership of a CP, its bit is cleared. - * When a thread runs, it's XT_CPENABLE is loaded into the CPENABLE reg. - * Avoids co-processor exceptions when no change of ownership is needed. - * - * XT_CPSTORED - * A bitmask with the same layout as CPENABLE, a bit per co-processor. - * Indicates whether the state of each co-processor is saved in the state - * save area. When a thread enters the kernel, only the state of co-procs - * still enabled in CPENABLE is saved. When the co-processor exception - * handler assigns ownership of a co-processor to a thread, it restores - * the saved state only if this bit is set, and clears this bit. - * - * XT_CP_CS_ST - * A bitmask with the same layout as CPENABLE, a bit per co-processor. - * Indicates whether callee-saved state is saved in the state save area. - * Callee-saved state is saved by itself on a solicited context switch, - * and restored when needed by the coprocessor exception handler. - * Unsolicited switches will cause the entire coprocessor to be saved - * when necessary. - * - * XT_CP_ASA - * Pointer to the aligned save area. Allows it to be aligned more than - * the overall save area (which might only be stack-aligned or TCB-aligned). - * Especially relevant for Xtensa cores configured with a very large data - * path that requires alignment greater than 16 bytes (ABI stack alignment). - * ------------------------------------------------------------------------------- - */ +------------------------------------------------------------------------------- + CO-PROCESSOR STATE SAVE AREA FOR A THREAD + + The RTOS must provide an area per thread to save the state of co-processors + when that thread does not have control. Co-processors are context-switched + lazily (on demand) only when a new thread uses a co-processor instruction, + otherwise a thread retains ownership of the co-processor even when it loses + control of the processor. An Xtensa co-processor exception is triggered when + any co-processor instruction is executed by a thread that is not the owner, + and the context switch of that co-processor is then peformed by the handler. + Ownership represents which thread's state is currently in the co-processor. + + Co-processors may not be used by interrupt or exception handlers. If an + co-processor instruction is executed by an interrupt or exception handler, + the co-processor exception handler will trigger a kernel panic and freeze. + This restriction is introduced to reduce the overhead of saving and restoring + co-processor state (which can be quite large) and in particular remove that + overhead from interrupt handlers. + + The co-processor state save area may be in any convenient per-thread location + such as in the thread control block or above the thread stack area. It need + not be in the interrupt stack frame since interrupts don't use co-processors. + + Along with the save area for each co-processor, two bitmasks with flags per + co-processor (laid out as in the CPENABLE reg) help manage context-switching + co-processors as efficiently as possible: + + XT_CPENABLE + The contents of a non-running thread's CPENABLE register. + It represents the co-processors owned (and whose state is still needed) + by the thread. When a thread is preempted, its CPENABLE is saved here. + When a thread solicits a context-swtich, its CPENABLE is cleared - the + compiler has saved the (caller-saved) co-proc state if it needs to. + When a non-running thread loses ownership of a CP, its bit is cleared. + When a thread runs, it's XT_CPENABLE is loaded into the CPENABLE reg. + Avoids co-processor exceptions when no change of ownership is needed. + + XT_CPSTORED + A bitmask with the same layout as CPENABLE, a bit per co-processor. + Indicates whether the state of each co-processor is saved in the state + save area. When a thread enters the kernel, only the state of co-procs + still enabled in CPENABLE is saved. When the co-processor exception + handler assigns ownership of a co-processor to a thread, it restores + the saved state only if this bit is set, and clears this bit. + + XT_CP_CS_ST + A bitmask with the same layout as CPENABLE, a bit per co-processor. + Indicates whether callee-saved state is saved in the state save area. + Callee-saved state is saved by itself on a solicited context switch, + and restored when needed by the coprocessor exception handler. + Unsolicited switches will cause the entire coprocessor to be saved + when necessary. + + XT_CP_ASA + Pointer to the aligned save area. Allows it to be aligned more than + the overall save area (which might only be stack-aligned or TCB-aligned). + Especially relevant for Xtensa cores configured with a very large data + path that requires alignment greater than 16 bytes (ABI stack alignment). +------------------------------------------------------------------------------- +*/ #if XCHAL_CP_NUM > 0 /* Offsets of each coprocessor save area within the 'aligned save area': */ -#define XT_CP0_SA 0 -#define XT_CP1_SA ALIGNUP( XCHAL_CP1_SA_ALIGN, XT_CP0_SA + XCHAL_CP0_SA_SIZE ) -#define XT_CP2_SA ALIGNUP( XCHAL_CP2_SA_ALIGN, XT_CP1_SA + XCHAL_CP1_SA_SIZE ) -#define XT_CP3_SA ALIGNUP( XCHAL_CP3_SA_ALIGN, XT_CP2_SA + XCHAL_CP2_SA_SIZE ) -#define XT_CP4_SA ALIGNUP( XCHAL_CP4_SA_ALIGN, XT_CP3_SA + XCHAL_CP3_SA_SIZE ) -#define XT_CP5_SA ALIGNUP( XCHAL_CP5_SA_ALIGN, XT_CP4_SA + XCHAL_CP4_SA_SIZE ) -#define XT_CP6_SA ALIGNUP( XCHAL_CP6_SA_ALIGN, XT_CP5_SA + XCHAL_CP5_SA_SIZE ) -#define XT_CP7_SA ALIGNUP( XCHAL_CP7_SA_ALIGN, XT_CP6_SA + XCHAL_CP6_SA_SIZE ) -#define XT_CP_SA_SIZE ALIGNUP( 16, XT_CP7_SA + XCHAL_CP7_SA_SIZE ) +#define XT_CP0_SA 0 +#define XT_CP1_SA ALIGNUP(XCHAL_CP1_SA_ALIGN, XT_CP0_SA + XCHAL_CP0_SA_SIZE) +#define XT_CP2_SA ALIGNUP(XCHAL_CP2_SA_ALIGN, XT_CP1_SA + XCHAL_CP1_SA_SIZE) +#define XT_CP3_SA ALIGNUP(XCHAL_CP3_SA_ALIGN, XT_CP2_SA + XCHAL_CP2_SA_SIZE) +#define XT_CP4_SA ALIGNUP(XCHAL_CP4_SA_ALIGN, XT_CP3_SA + XCHAL_CP3_SA_SIZE) +#define XT_CP5_SA ALIGNUP(XCHAL_CP5_SA_ALIGN, XT_CP4_SA + XCHAL_CP4_SA_SIZE) +#define XT_CP6_SA ALIGNUP(XCHAL_CP6_SA_ALIGN, XT_CP5_SA + XCHAL_CP5_SA_SIZE) +#define XT_CP7_SA ALIGNUP(XCHAL_CP7_SA_ALIGN, XT_CP6_SA + XCHAL_CP6_SA_SIZE) +#define XT_CP_SA_SIZE ALIGNUP(16, XT_CP7_SA + XCHAL_CP7_SA_SIZE) /* Offsets within the overall save area: */ -#define XT_CPENABLE 0 /* (2 bytes) coprocessors active for this thread */ -#define XT_CPSTORED 2 /* (2 bytes) coprocessors saved for this thread */ -#define XT_CP_CS_ST 4 /* (2 bytes) coprocessor callee-saved regs stored for this thread */ -#define XT_CP_ASA 8 /* (4 bytes) ptr to aligned save area */ +#define XT_CPENABLE 0 /* (2 bytes) coprocessors active for this thread */ +#define XT_CPSTORED 2 /* (2 bytes) coprocessors saved for this thread */ +#define XT_CP_CS_ST 4 /* (2 bytes) coprocessor callee-saved regs stored for this thread */ +#define XT_CP_ASA 8 /* (4 bytes) ptr to aligned save area */ /* Overall size allows for dynamic alignment: */ -#define XT_CP_SIZE ( 12 + XT_CP_SA_SIZE + XCHAL_TOTAL_SA_ALIGN ) -#else /* if XCHAL_CP_NUM > 0 */ -#define XT_CP_SIZE 0 -#endif /* if XCHAL_CP_NUM > 0 */ +#define XT_CP_SIZE (12 + XT_CP_SA_SIZE + XCHAL_TOTAL_SA_ALIGN) +#else +#define XT_CP_SIZE 0 +#endif /* - * ------------------------------------------------------------------------------- - * MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN - * - * Convenient where the frame size requirements are the same for both ABIs. - * ENTRY(sz), RET(sz) are for framed functions (have locals or make calls). - * ENTRY0, RET0 are for frameless functions (no locals, no calls). - * - * where size = size of stack frame in bytes (must be >0 and aligned to 16). - * For framed functions the frame is created and the return address saved at - * base of frame (Call0 ABI) or as determined by hardware (Windowed ABI). - * For frameless functions, there is no frame and return address remains in a0. - * Note: Because CPP macros expand to a single line, macros requiring multi-line - * expansions are implemented as assembler macros. - * ------------------------------------------------------------------------------- - */ +------------------------------------------------------------------------------- + MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN + + Convenient where the frame size requirements are the same for both ABIs. + ENTRY(sz), RET(sz) are for framed functions (have locals or make calls). + ENTRY0, RET0 are for frameless functions (no locals, no calls). + + where size = size of stack frame in bytes (must be >0 and aligned to 16). + For framed functions the frame is created and the return address saved at + base of frame (Call0 ABI) or as determined by hardware (Windowed ABI). + For frameless functions, there is no frame and return address remains in a0. + Note: Because CPP macros expand to a single line, macros requiring multi-line + expansions are implemented as assembler macros. +------------------------------------------------------------------------------- +*/ #ifdef __ASSEMBLER__ - #ifdef __XTENSA_CALL0_ABI__ - /* Call0 */ -#define ENTRY( sz ) entry1 sz - .macro entry1 size = 0x10 - addi sp, sp, -\ size - s32i a0, sp, 0 - .endm -#define ENTRY0 -#define RET( sz ) ret1 sz - .macro ret1 size = 0x10 - l32i a0, sp, 0 - addi sp, sp, \ size - ret - .endm -#define RET0 ret - #else /* ifdef __XTENSA_CALL0_ABI__ */ - /* Windowed */ -#define ENTRY( sz ) entry sp, sz -#define ENTRY0 entry sp, 0x10 -#define RET( sz ) retw -#define RET0 retw - #endif /* ifdef __XTENSA_CALL0_ABI__ */ -#endif /* ifdef __ASSEMBLER__ */ +#ifdef __XTENSA_CALL0_ABI__ + /* Call0 */ + #define ENTRY(sz) entry1 sz + .macro entry1 size=0x10 + addi sp, sp, -\size + s32i a0, sp, 0 + .endm + #define ENTRY0 + #define RET(sz) ret1 sz + .macro ret1 size=0x10 + l32i a0, sp, 0 + addi sp, sp, \size + ret + .endm + #define RET0 ret +#else + /* Windowed */ + #define ENTRY(sz) entry sp, sz + #define ENTRY0 entry sp, 0x10 + #define RET(sz) retw + #define RET0 retw +#endif +#endif #endif /* XTENSA_CONTEXT_H */ diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_init.c b/portable/ThirdParty/XCC/Xtensa/xtensa_init.c index 7ee6f3d63..c18520350 100644 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_init.c +++ b/portable/ThirdParty/XCC/Xtensa/xtensa_init.c @@ -1,4 +1,4 @@ -/* + /* * FreeRTOS Kernel * Copyright (C) 2015-2019 Cadence Design Systems, Inc. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -36,31 +36,35 @@ #ifdef XT_BOARD - #include +#include #endif #include "xtensa_rtos.h" #ifdef XT_RTOS_TIMER_INT - unsigned _xt_tick_divisor = 0; /* cached number of cycles per tick */ +unsigned _xt_tick_divisor = 0; /* cached number of cycles per tick */ /* - * Compute and initialize at run-time the tick divisor (the number of - * processor clock cycles in an RTOS tick, used to set the tick timer). - * Called when the processor clock frequency is not known at compile-time. - */ - void _xt_tick_divisor_init( void ) - { - #ifdef XT_CLOCK_FREQ - _xt_tick_divisor = ( XT_CLOCK_FREQ / XT_TICK_PER_SEC ); - #else - #ifdef XT_BOARD - _xt_tick_divisor = xtbsp_clock_freq_hz() / XT_TICK_PER_SEC; - #else - #error "No way to obtain processor clock frequency" - #endif /* XT_BOARD */ - #endif /* XT_CLOCK_FREQ */ - } +Compute and initialize at run-time the tick divisor (the number of +processor clock cycles in an RTOS tick, used to set the tick timer). +Called when the processor clock frequency is not known at compile-time. +*/ +void _xt_tick_divisor_init(void) +{ +#ifdef XT_CLOCK_FREQ + + _xt_tick_divisor = (XT_CLOCK_FREQ / XT_TICK_PER_SEC); + +#else + + #ifdef XT_BOARD + _xt_tick_divisor = xtbsp_clock_freq_hz() / XT_TICK_PER_SEC; + #else + #error "No way to obtain processor clock frequency" + #endif /* XT_BOARD */ + +#endif /* XT_CLOCK_FREQ */ +} #endif /* XT_RTOS_TIMER_INT */ diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_intr.c b/portable/ThirdParty/XCC/Xtensa/xtensa_intr.c index 87bf63cb4..88ed191e3 100644 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_intr.c +++ b/portable/ThirdParty/XCC/Xtensa/xtensa_intr.c @@ -1,4 +1,4 @@ -/* + /* * FreeRTOS Kernel * Copyright (C) 2015-2019 Cadence Design Systems, Inc. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -43,110 +43,95 @@ /* Handler table is in xtensa_intr_asm.S */ - extern xt_exc_handler _xt_exception_table[ XCHAL_EXCCAUSE_NUM ]; +extern xt_exc_handler _xt_exception_table[XCHAL_EXCCAUSE_NUM]; /* - * Default handler for unhandled exceptions. - */ - void xt_unhandled_exception( XtExcFrame * frame ) - { - exit( -1 ); - } + Default handler for unhandled exceptions. +*/ +void xt_unhandled_exception(XtExcFrame *frame) +{ + exit(-1); +} /* - * This function registers a handler for the specified exception. - * The function returns the address of the previous handler. - * On error, it returns 0. - */ - xt_exc_handler xt_set_exception_handler( int n, - xt_exc_handler f ) - { - xt_exc_handler old; - - if( ( n < 0 ) || ( n >= XCHAL_EXCCAUSE_NUM ) ) - { - return 0; /* invalid exception number */ - } - - old = _xt_exception_table[ n ]; - - if( f ) - { - _xt_exception_table[ n ] = f; - } - else - { - _xt_exception_table[ n ] = &xt_unhandled_exception; - } - - return( ( old == &xt_unhandled_exception ) ? 0 : old ); + This function registers a handler for the specified exception. + The function returns the address of the previous handler. + On error, it returns 0. +*/ +xt_exc_handler xt_set_exception_handler(int n, xt_exc_handler f) +{ + xt_exc_handler old; + + if( n < 0 || n >= XCHAL_EXCCAUSE_NUM ) + return 0; /* invalid exception number */ + + old = _xt_exception_table[n]; + + if (f) { + _xt_exception_table[n] = f; } + else { + _xt_exception_table[n] = &xt_unhandled_exception; + } + + return ((old == &xt_unhandled_exception) ? 0 : old); +} -#endif /* if XCHAL_HAVE_EXCEPTIONS */ +#endif #if XCHAL_HAVE_INTERRUPTS /* Handler table is in xtensa_intr_asm.S */ - typedef struct xt_handler_table_entry - { - void * handler; - void * arg; - } xt_handler_table_entry; +typedef struct xt_handler_table_entry { + void * handler; + void * arg; +} xt_handler_table_entry; - extern xt_handler_table_entry _xt_interrupt_table[ XCHAL_NUM_INTERRUPTS ]; +extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS]; /* - * Default handler for unhandled interrupts. - */ - void xt_unhandled_interrupt( void * arg ) - { - exit( -1 ); - } + Default handler for unhandled interrupts. +*/ +void xt_unhandled_interrupt(void * arg) +{ + exit(-1); +} /* - * This function registers a handler for the specified interrupt. The "arg" - * parameter specifies the argument to be passed to the handler when it is - * invoked. The function returns the address of the previous handler. - * On error, it returns 0. - */ - xt_handler xt_set_interrupt_handler( int n, - xt_handler f, - void * arg ) - { - xt_handler_table_entry * entry; - xt_handler old; - - if( ( n < 0 ) || ( n >= XCHAL_NUM_INTERRUPTS ) ) - { - return 0; /* invalid interrupt number */ - } - - if( Xthal_intlevel[ n ] > XCHAL_EXCM_LEVEL ) - { - return 0; /* priority level too high to safely handle in C */ - } - - entry = _xt_interrupt_table + n; - old = entry->handler; - - if( f ) - { - entry->handler = f; - entry->arg = arg; - } - else - { - entry->handler = &xt_unhandled_interrupt; - entry->arg = ( void * ) n; - } - - return( ( old == &xt_unhandled_interrupt ) ? 0 : old ); + This function registers a handler for the specified interrupt. The "arg" + parameter specifies the argument to be passed to the handler when it is + invoked. The function returns the address of the previous handler. + On error, it returns 0. +*/ +xt_handler xt_set_interrupt_handler(int n, xt_handler f, void * arg) +{ + xt_handler_table_entry * entry; + xt_handler old; + + if( n < 0 || n >= XCHAL_NUM_INTERRUPTS ) + return 0; /* invalid interrupt number */ + if( Xthal_intlevel[n] > XCHAL_EXCM_LEVEL ) + return 0; /* priority level too high to safely handle in C */ + + entry = _xt_interrupt_table + n; + old = entry->handler; + + if (f) { + entry->handler = f; + entry->arg = arg; + } + else { + entry->handler = &xt_unhandled_interrupt; + entry->arg = (void*)n; } + return ((old == &xt_unhandled_interrupt) ? 0 : old); +} + #endif /* XCHAL_HAVE_INTERRUPTS */ diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_overlay_os_hook.c b/portable/ThirdParty/XCC/Xtensa/xtensa_overlay_os_hook.c index fcbc57386..2a8506a01 100644 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_overlay_os_hook.c +++ b/portable/ThirdParty/XCC/Xtensa/xtensa_overlay_os_hook.c @@ -1,4 +1,4 @@ -/* + /* * FreeRTOS Kernel * Copyright (C) 2015-2019 Cadence Design Systems, Inc. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -39,7 +39,7 @@ /* Mutex object that controls access to the overlay. Currently only one * overlay region is supported so one mutex suffices. */ - static SemaphoreHandle_t xt_overlay_mutex; +static SemaphoreHandle_t xt_overlay_mutex; /* This function should be overridden to provide OS specific init such @@ -47,30 +47,30 @@ * Typically this mutex would be set up with priority inheritance. See * overlay manager documentation for more details. */ - void xt_overlay_init_os( void ) - { - /* Create the mutex for overlay access. Priority inheritance is - * required. - */ - xt_overlay_mutex = xSemaphoreCreateMutex(); - } +void xt_overlay_init_os(void) +{ + /* Create the mutex for overlay access. Priority inheritance is + * required. + */ + xt_overlay_mutex = xSemaphoreCreateMutex(); +} /* This function locks access to shared overlay resources, typically * by acquiring a mutex. */ - void xt_overlay_lock( void ) - { - xSemaphoreTake( xt_overlay_mutex, 0 ); - } +void xt_overlay_lock(void) +{ + xSemaphoreTake(xt_overlay_mutex, 0); +} /* This function releases access to shared overlay resources, typically * by unlocking a mutex. */ - void xt_overlay_unlock( void ) - { - xSemaphoreGive( xt_overlay_mutex ); - } +void xt_overlay_unlock(void) +{ + xSemaphoreGive(xt_overlay_mutex); +} -#endif /* if configUSE_MUTEX */ +#endif diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_rtos.h b/portable/ThirdParty/XCC/Xtensa/xtensa_rtos.h index 54f4d0b7e..2c917c832 100644 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_rtos.h +++ b/portable/ThirdParty/XCC/Xtensa/xtensa_rtos.h @@ -1,4 +1,4 @@ -/* + /* * FreeRTOS Kernel * Copyright (C) 2015-2019 Cadence Design Systems, Inc. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -49,9 +49,9 @@ #define XTENSA_RTOS_H #ifdef __ASSEMBLER__ - #include +#include #else - #include +#include #endif #include @@ -59,180 +59,180 @@ #include /* - * Include any RTOS specific definitions that are needed by this header. - */ +Include any RTOS specific definitions that are needed by this header. +*/ #include /* - * Convert FreeRTOSConfig definitions to XTENSA definitions. - * However these can still be overridden from the command line. - */ +Convert FreeRTOSConfig definitions to XTENSA definitions. +However these can still be overridden from the command line. +*/ #ifndef XT_SIMULATOR - #if configXT_SIMULATOR - #define XT_SIMULATOR 1 /* Simulator mode */ - #endif + #if configXT_SIMULATOR + #define XT_SIMULATOR 1 /* Simulator mode */ + #endif #endif #ifndef XT_BOARD - #if configXT_BOARD - #define XT_BOARD 1 /* Board mode */ - #endif + #if configXT_BOARD + #define XT_BOARD 1 /* Board mode */ + #endif #endif #ifndef XT_TIMER_INDEX - #if defined configXT_TIMER_INDEX - #define XT_TIMER_INDEX configXT_TIMER_INDEX /* Index of hardware timer to be used */ - #endif + #if defined configXT_TIMER_INDEX + #define XT_TIMER_INDEX configXT_TIMER_INDEX /* Index of hardware timer to be used */ + #endif #endif #ifndef XT_INTEXC_HOOKS - #if configXT_INTEXC_HOOKS - #define XT_INTEXC_HOOKS 1 /* Enables exception hooks */ - #endif + #if configXT_INTEXC_HOOKS + #define XT_INTEXC_HOOKS 1 /* Enables exception hooks */ + #endif #endif -#if ( !XT_SIMULATOR ) && ( !XT_BOARD ) - #error Either XT_SIMULATOR or XT_BOARD must be defined. +#if (!XT_SIMULATOR) && (!XT_BOARD) + #error Either XT_SIMULATOR or XT_BOARD must be defined. #endif /* - * Name of RTOS (for messages). - */ +Name of RTOS (for messages). +*/ #define XT_RTOS_NAME FreeRTOS /* - * Check some Xtensa configuration requirements and report error if not met. - * Error messages can be customize to the RTOS port. - */ +Check some Xtensa configuration requirements and report error if not met. +Error messages can be customize to the RTOS port. +*/ #if !XCHAL_HAVE_XEA2 - #error "FreeRTOS/Xtensa requires XEA2 (exception architecture 2)." +#error "FreeRTOS/Xtensa requires XEA2 (exception architecture 2)." #endif /******************************************************************************* -* -* RTOS CALLOUT MACROS MAPPED TO RTOS PORT-SPECIFIC FUNCTIONS. -* -* Define callout macros used in generic Xtensa code to interact with the RTOS. -* The macros are simply the function names for use in calls from assembler code. -* Some of these functions may call back to generic functions in xtensa_context.h . -* + +RTOS CALLOUT MACROS MAPPED TO RTOS PORT-SPECIFIC FUNCTIONS. + +Define callout macros used in generic Xtensa code to interact with the RTOS. +The macros are simply the function names for use in calls from assembler code. +Some of these functions may call back to generic functions in xtensa_context.h . + *******************************************************************************/ /* - * Inform RTOS of entry into an interrupt handler that will affect it. - * Allows RTOS to manage switch to any system stack and count nesting level. - * Called after minimal context has been saved, with interrupts disabled. - * RTOS port can call0 _xt_context_save to save the rest of the context. - * May only be called from assembly code by the 'call0' instruction. - */ -/* void XT_RTOS_INT_ENTER(void) */ -#define XT_RTOS_INT_ENTER _frxt_int_enter +Inform RTOS of entry into an interrupt handler that will affect it. +Allows RTOS to manage switch to any system stack and count nesting level. +Called after minimal context has been saved, with interrupts disabled. +RTOS port can call0 _xt_context_save to save the rest of the context. +May only be called from assembly code by the 'call0' instruction. +*/ +// void XT_RTOS_INT_ENTER(void) +#define XT_RTOS_INT_ENTER _frxt_int_enter /* - * Inform RTOS of completion of an interrupt handler, and give control to - * RTOS to perform thread/task scheduling, switch back from any system stack - * and restore the context, and return to the exit dispatcher saved in the - * stack frame at XT_STK_EXIT. RTOS port can call0 _xt_context_restore - * to save the context saved in XT_RTOS_INT_ENTER via _xt_context_save, - * leaving only a minimal part of the context to be restored by the exit - * dispatcher. This function does not return to the place it was called from. - * May only be called from assembly code by the 'call0' instruction. - */ -/* void XT_RTOS_INT_EXIT(void) */ +Inform RTOS of completion of an interrupt handler, and give control to +RTOS to perform thread/task scheduling, switch back from any system stack +and restore the context, and return to the exit dispatcher saved in the +stack frame at XT_STK_EXIT. RTOS port can call0 _xt_context_restore +to save the context saved in XT_RTOS_INT_ENTER via _xt_context_save, +leaving only a minimal part of the context to be restored by the exit +dispatcher. This function does not return to the place it was called from. +May only be called from assembly code by the 'call0' instruction. +*/ +// void XT_RTOS_INT_EXIT(void) #define XT_RTOS_INT_EXIT _frxt_int_exit /* - * Inform RTOS of the occurrence of a tick timer interrupt. - * If RTOS has no tick timer, leave XT_RTOS_TIMER_INT undefined. - * May be coded in or called from C or assembly, per ABI conventions. - * RTOS may optionally define XT_TICK_PER_SEC in its own way (eg. macro). - */ -/* void XT_RTOS_TIMER_INT(void) */ -#define XT_RTOS_TIMER_INT _frxt_timer_int -#define XT_TICK_PER_SEC configTICK_RATE_HZ +Inform RTOS of the occurrence of a tick timer interrupt. +If RTOS has no tick timer, leave XT_RTOS_TIMER_INT undefined. +May be coded in or called from C or assembly, per ABI conventions. +RTOS may optionally define XT_TICK_PER_SEC in its own way (eg. macro). +*/ +// void XT_RTOS_TIMER_INT(void) +#define XT_RTOS_TIMER_INT _frxt_timer_int +#define XT_TICK_PER_SEC configTICK_RATE_HZ /* - * Return in a15 the base address of the co-processor state save area for the - * thread that triggered a co-processor exception, or 0 if no thread was running. - * The state save area is structured as defined in xtensa_context.h and has size - * XT_CP_SIZE. Co-processor instructions should only be used in thread code, never - * in interrupt handlers or the RTOS kernel. May only be called from assembly code - * and by the 'call0' instruction. A result of 0 indicates an unrecoverable error. - * The implementation may use only a2-4, a15 (all other regs must be preserved). - */ -/* void* XT_RTOS_CP_STATE(void) */ +Return in a15 the base address of the co-processor state save area for the +thread that triggered a co-processor exception, or 0 if no thread was running. +The state save area is structured as defined in xtensa_context.h and has size +XT_CP_SIZE. Co-processor instructions should only be used in thread code, never +in interrupt handlers or the RTOS kernel. May only be called from assembly code +and by the 'call0' instruction. A result of 0 indicates an unrecoverable error. +The implementation may use only a2-4, a15 (all other regs must be preserved). +*/ +// void* XT_RTOS_CP_STATE(void) #define XT_RTOS_CP_STATE _frxt_task_coproc_state /******************************************************************************* -* -* HOOKS TO DYNAMICALLY INSTALL INTERRUPT AND EXCEPTION HANDLERS PER LEVEL. -* -* This Xtensa RTOS port provides hooks for dynamically installing exception -* and interrupt handlers to facilitate automated testing where each test -* case can install its own handler for user exceptions and each interrupt -* priority (level). This consists of an array of function pointers indexed -* by interrupt priority, with index 0 being the user exception handler hook. -* Each entry in the array is initially 0, and may be replaced by a function -* pointer of type XT_INTEXC_HOOK. A handler may be uninstalled by installing 0. -* -* The handler for low and medium priority obeys ABI conventions so may be coded -* in C. For the exception handler, the cause is the contents of the EXCCAUSE -* reg, and the result is -1 if handled, else the cause (still needs handling). -* For interrupt handlers, the cause is a mask of pending enabled interrupts at -* that level, and the result is the same mask with the bits for the handled -* interrupts cleared (those not cleared still need handling). This allows a test -* case to either pre-handle or override the default handling for the exception -* or interrupt level (see xtensa_vectors.S). -* -* High priority handlers (including NMI) must be coded in assembly, are always -* called by 'call0' regardless of ABI, must preserve all registers except a0, -* and must not use or modify the interrupted stack. The hook argument 'cause' -* is not passed and the result is ignored, so as not to burden the caller with -* saving and restoring a2 (it assumes only one interrupt per level - see the -* discussion in high priority interrupts in xtensa_vectors.S). The handler -* therefore should be coded to prototype 'void h(void)' even though it plugs -* into an array of handlers of prototype 'unsigned h(unsigned)'. -* -* To enable interrupt/exception hooks, compile the RTOS with '-DXT_INTEXC_HOOKS'. -* + +HOOKS TO DYNAMICALLY INSTALL INTERRUPT AND EXCEPTION HANDLERS PER LEVEL. + +This Xtensa RTOS port provides hooks for dynamically installing exception +and interrupt handlers to facilitate automated testing where each test +case can install its own handler for user exceptions and each interrupt +priority (level). This consists of an array of function pointers indexed +by interrupt priority, with index 0 being the user exception handler hook. +Each entry in the array is initially 0, and may be replaced by a function +pointer of type XT_INTEXC_HOOK. A handler may be uninstalled by installing 0. + +The handler for low and medium priority obeys ABI conventions so may be coded +in C. For the exception handler, the cause is the contents of the EXCCAUSE +reg, and the result is -1 if handled, else the cause (still needs handling). +For interrupt handlers, the cause is a mask of pending enabled interrupts at +that level, and the result is the same mask with the bits for the handled +interrupts cleared (those not cleared still need handling). This allows a test +case to either pre-handle or override the default handling for the exception +or interrupt level (see xtensa_vectors.S). + +High priority handlers (including NMI) must be coded in assembly, are always +called by 'call0' regardless of ABI, must preserve all registers except a0, +and must not use or modify the interrupted stack. The hook argument 'cause' +is not passed and the result is ignored, so as not to burden the caller with +saving and restoring a2 (it assumes only one interrupt per level - see the +discussion in high priority interrupts in xtensa_vectors.S). The handler +therefore should be coded to prototype 'void h(void)' even though it plugs +into an array of handlers of prototype 'unsigned h(unsigned)'. + +To enable interrupt/exception hooks, compile the RTOS with '-DXT_INTEXC_HOOKS'. + *******************************************************************************/ -#define XT_INTEXC_HOOK_NUM ( 1 + XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI ) +#define XT_INTEXC_HOOK_NUM (1 + XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI) #ifndef __ASSEMBLER__ - typedef unsigned (* XT_INTEXC_HOOK)( unsigned cause ); - extern volatile XT_INTEXC_HOOK _xt_intexc_hooks[ XT_INTEXC_HOOK_NUM ]; +typedef unsigned (*XT_INTEXC_HOOK)(unsigned cause); +extern volatile XT_INTEXC_HOOK _xt_intexc_hooks[XT_INTEXC_HOOK_NUM]; #endif /******************************************************************************* -* -* CONVENIENCE INCLUSIONS. -* -* Ensures RTOS specific files need only include this one Xtensa-generic header. -* These headers are included last so they can use the RTOS definitions above. -* + +CONVENIENCE INCLUSIONS. + +Ensures RTOS specific files need only include this one Xtensa-generic header. +These headers are included last so they can use the RTOS definitions above. + *******************************************************************************/ #include "xtensa_context.h" #ifdef XT_RTOS_TIMER_INT - #include "xtensa_timer.h" +#include "xtensa_timer.h" #endif /******************************************************************************* -* -* Xtensa Port Version. -* + +Xtensa Port Version. + *******************************************************************************/ -#define XTENSA_PORT_VERSION 1.7 -#define XTENSA_PORT_VERSION_STRING "1.7" +#define XTENSA_PORT_VERSION 1.7 +#define XTENSA_PORT_VERSION_STRING "1.7" #endif /* XTENSA_RTOS_H */ diff --git a/portable/ThirdParty/XCC/Xtensa/xtensa_timer.h b/portable/ThirdParty/XCC/Xtensa/xtensa_timer.h index ecaf3f4e9..cefac70f2 100644 --- a/portable/ThirdParty/XCC/Xtensa/xtensa_timer.h +++ b/portable/ThirdParty/XCC/Xtensa/xtensa_timer.h @@ -1,4 +1,4 @@ -/* + /* * FreeRTOS Kernel * Copyright (C) 2015-2019 Cadence Design Systems, Inc. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -47,118 +47,118 @@ #define XTENSA_TIMER_H #ifdef __ASSEMBLER__ - #include +#include #endif #include #include -#include "xtensa_rtos.h" /* in case this wasn't included directly */ +#include "xtensa_rtos.h" /* in case this wasn't included directly */ #include /* - * Select timer to use for periodic tick, and determine its interrupt number - * and priority. User may specify a timer by defining XT_TIMER_INDEX with -D, - * in which case its validity is checked (it must exist in this core and must - * not be on a high priority interrupt - an error will be reported in invalid). - * Otherwise select the first low or medium priority interrupt timer available. - */ +Select timer to use for periodic tick, and determine its interrupt number +and priority. User may specify a timer by defining XT_TIMER_INDEX with -D, +in which case its validity is checked (it must exist in this core and must +not be on a high priority interrupt - an error will be reported in invalid). +Otherwise select the first low or medium priority interrupt timer available. +*/ #if XCHAL_NUM_TIMERS == 0 - #error "This Xtensa configuration is unsupported, it has no timers." + #error "This Xtensa configuration is unsupported, it has no timers." #else - #ifndef XT_TIMER_INDEX - #if XCHAL_TIMER3_INTERRUPT != XTHAL_TIMER_UNCONFIGURED - #if XCHAL_INT_LEVEL( XCHAL_TIMER3_INTERRUPT ) <= XCHAL_EXCM_LEVEL - #undef XT_TIMER_INDEX - #define XT_TIMER_INDEX 3 - #endif - #endif - #if XCHAL_TIMER2_INTERRUPT != XTHAL_TIMER_UNCONFIGURED - #if XCHAL_INT_LEVEL( XCHAL_TIMER2_INTERRUPT ) <= XCHAL_EXCM_LEVEL - #undef XT_TIMER_INDEX - #define XT_TIMER_INDEX 2 - #endif - #endif - #if XCHAL_TIMER1_INTERRUPT != XTHAL_TIMER_UNCONFIGURED - #if XCHAL_INT_LEVEL( XCHAL_TIMER1_INTERRUPT ) <= XCHAL_EXCM_LEVEL - #undef XT_TIMER_INDEX - #define XT_TIMER_INDEX 1 - #endif - #endif - #if XCHAL_TIMER0_INTERRUPT != XTHAL_TIMER_UNCONFIGURED - #if XCHAL_INT_LEVEL( XCHAL_TIMER0_INTERRUPT ) <= XCHAL_EXCM_LEVEL - #undef XT_TIMER_INDEX - #define XT_TIMER_INDEX 0 - #endif - #endif - #endif /* ifndef XT_TIMER_INDEX */ - #ifndef XT_TIMER_INDEX - #error "There is no suitable timer in this Xtensa configuration." +#ifndef XT_TIMER_INDEX + #if XCHAL_TIMER3_INTERRUPT != XTHAL_TIMER_UNCONFIGURED + #if XCHAL_INT_LEVEL(XCHAL_TIMER3_INTERRUPT) <= XCHAL_EXCM_LEVEL + #undef XT_TIMER_INDEX + #define XT_TIMER_INDEX 3 + #endif + #endif + #if XCHAL_TIMER2_INTERRUPT != XTHAL_TIMER_UNCONFIGURED + #if XCHAL_INT_LEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL + #undef XT_TIMER_INDEX + #define XT_TIMER_INDEX 2 + #endif + #endif + #if XCHAL_TIMER1_INTERRUPT != XTHAL_TIMER_UNCONFIGURED + #if XCHAL_INT_LEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL + #undef XT_TIMER_INDEX + #define XT_TIMER_INDEX 1 #endif + #endif + #if XCHAL_TIMER0_INTERRUPT != XTHAL_TIMER_UNCONFIGURED + #if XCHAL_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL + #undef XT_TIMER_INDEX + #define XT_TIMER_INDEX 0 + #endif + #endif +#endif +#ifndef XT_TIMER_INDEX + #error "There is no suitable timer in this Xtensa configuration." +#endif - #define XT_CCOMPARE ( CCOMPARE + XT_TIMER_INDEX ) - #define XT_TIMER_INTNUM XCHAL_TIMER_INTERRUPT( XT_TIMER_INDEX ) - #define XT_TIMER_INTPRI XCHAL_INT_LEVEL( XT_TIMER_INTNUM ) - #define XT_TIMER_INTEN ( 1 << XT_TIMER_INTNUM ) +#define XT_CCOMPARE (CCOMPARE + XT_TIMER_INDEX) +#define XT_TIMER_INTNUM XCHAL_TIMER_INTERRUPT(XT_TIMER_INDEX) +#define XT_TIMER_INTPRI XCHAL_INT_LEVEL(XT_TIMER_INTNUM) +#define XT_TIMER_INTEN (1 << XT_TIMER_INTNUM) - #if XT_TIMER_INTNUM == XTHAL_TIMER_UNCONFIGURED - #error "The timer selected by XT_TIMER_INDEX does not exist in this core." - #elif XT_TIMER_INTPRI > XCHAL_EXCM_LEVEL - #error "The timer interrupt cannot be high priority (use medium or low)." - #endif +#if XT_TIMER_INTNUM == XTHAL_TIMER_UNCONFIGURED + #error "The timer selected by XT_TIMER_INDEX does not exist in this core." +#elif XT_TIMER_INTPRI > XCHAL_EXCM_LEVEL + #error "The timer interrupt cannot be high priority (use medium or low)." +#endif #endif /* XCHAL_NUM_TIMERS */ /* - * Set processor clock frequency, used to determine clock divisor for timer tick. - * User should BE SURE TO ADJUST THIS for the Xtensa platform being used. - * If using a supported board via the board-independent API defined in xtbsp.h, - * this may be left undefined and frequency and tick divisor will be computed - * and cached during run-time initialization. - * - * NOTE ON SIMULATOR: - * Under the Xtensa instruction set simulator, the frequency can only be estimated - * because it depends on the speed of the host and the version of the simulator. - * Also because it runs much slower than hardware, it is not possible to achieve - * real-time performance for most applications under the simulator. A frequency - * too low does not allow enough time between timer interrupts, starving threads. - * To obtain a more convenient but non-real-time tick duration on the simulator, - * compile with xt-xcc option "-DXT_SIMULATOR". - * Adjust this frequency to taste (it's not real-time anyway!). - */ -#if defined( XT_SIMULATOR ) && !defined( XT_CLOCK_FREQ ) - #define XT_CLOCK_FREQ configCPU_CLOCK_HZ +Set processor clock frequency, used to determine clock divisor for timer tick. +User should BE SURE TO ADJUST THIS for the Xtensa platform being used. +If using a supported board via the board-independent API defined in xtbsp.h, +this may be left undefined and frequency and tick divisor will be computed +and cached during run-time initialization. + +NOTE ON SIMULATOR: +Under the Xtensa instruction set simulator, the frequency can only be estimated +because it depends on the speed of the host and the version of the simulator. +Also because it runs much slower than hardware, it is not possible to achieve +real-time performance for most applications under the simulator. A frequency +too low does not allow enough time between timer interrupts, starving threads. +To obtain a more convenient but non-real-time tick duration on the simulator, +compile with xt-xcc option "-DXT_SIMULATOR". +Adjust this frequency to taste (it's not real-time anyway!). +*/ +#if defined(XT_SIMULATOR) && !defined(XT_CLOCK_FREQ) +#define XT_CLOCK_FREQ configCPU_CLOCK_HZ #endif -#if !defined( XT_CLOCK_FREQ ) && !defined( XT_BOARD ) - #error "XT_CLOCK_FREQ must be defined for the target platform." +#if !defined(XT_CLOCK_FREQ) && !defined(XT_BOARD) + #error "XT_CLOCK_FREQ must be defined for the target platform." #endif /* - * Default number of timer "ticks" per second (default 100 for 10ms tick). - * RTOS may define this in its own way (if applicable) in xtensa_rtos.h. - * User may redefine this to an optimal value for the application, either by - * editing this here or in xtensa_rtos.h, or compiling with xt-xcc option - * "-DXT_TICK_PER_SEC=" where is a suitable number. - */ +Default number of timer "ticks" per second (default 100 for 10ms tick). +RTOS may define this in its own way (if applicable) in xtensa_rtos.h. +User may redefine this to an optimal value for the application, either by +editing this here or in xtensa_rtos.h, or compiling with xt-xcc option +"-DXT_TICK_PER_SEC=" where is a suitable number. +*/ #ifndef XT_TICK_PER_SEC - #define XT_TICK_PER_SEC configTICK_RATE_HZ /* 10 ms tick = 100 ticks per second */ +#define XT_TICK_PER_SEC configTICK_RATE_HZ /* 10 ms tick = 100 ticks per second */ #endif /* - * Derivation of clock divisor for timer tick and interrupt (one per tick). - */ +Derivation of clock divisor for timer tick and interrupt (one per tick). +*/ #ifdef XT_CLOCK_FREQ - #define XT_TICK_DIVISOR ( XT_CLOCK_FREQ / XT_TICK_PER_SEC ) +#define XT_TICK_DIVISOR (XT_CLOCK_FREQ / XT_TICK_PER_SEC) #endif #ifndef __ASSEMBLER__ - extern unsigned _xt_tick_divisor; - extern void _xt_tick_divisor_init( void ); +extern unsigned _xt_tick_divisor; +extern void _xt_tick_divisor_init(void); #endif -#endif /* XTENSA_TIMER_H */ +#endif /* XTENSA_TIMER_H */ -- cgit v1.2.3