Xtensa support updated and moved to Partner-Supported submodules (#1156)

* Xtensa support moved to Partner-Supported ports

Removing legacy Xtensa port; leave README with pointer to latest code

* Updated submodule ThirdParty/FreeRTOS-Kernel-Partner-Supported-Ports
pull/1158/head
Ian Thompson 4 months ago committed by GitHub
parent f5cf45d86e
commit 5f3bab1a32
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1 +1 @@
Subproject commit dc3afc6e837426b4bda81bbb6cf45bfb6f34c7e9 Subproject commit abc22103e1e6634b33457d4127bff1ab62f27f90

@ -1,97 +0,0 @@
### Makefile to build the FreeRTOS library ###
# Build target (options: sim, board)
TARGET = sim
SMALL =
# Tools
CC = xt-xcc
AS = xt-xcc
AR = xt-ar
XT_CORE = $(patsubst %-params,%,$(notdir $(shell xt-xcc --show-config=core)))
CONFIGDIR = $(shell xt-xcc --show-config=config)
# For platform-specific commands
include $(CONFIGDIR)/misc/hostenv.mk
# Source code and build locations
SRCROOT = $(subst /,$(S),$(CURDIR))
TSTROOT = $(abspath $(SRCROOT)$(S)..$(S)..$(S)..$(S)..$(S)..$(S)demos$(S)cadence$(S)sim$(SMALL))
BLDROOT = $(TSTROOT)$(S)build
BLDDIR = $(BLDROOT)$(S)$(XT_CORE)
FR_SRCDIR = $(abspath $(SRCROOT)$(S)..$(S)..$(S)..)
FR_SRCDIR2 = $(FR_SRCDIR)$(S)portable$(S)MemMang
XT_SRCDIR = $(SRCROOT)
vpath %.c $(FR_SRCDIR) $(FR_SRCDIR2) $(XT_SRCDIR)
vpath %.S $(XT_SRCDIR)
# File lists
FR_C_FILES = $(notdir $(wildcard $(FR_SRCDIR)/*.c)) $(notdir $(wildcard $(FR_SRCDIR2)/*.c))
XT_C_FILES = $(notdir $(wildcard $(XT_SRCDIR)/*.c))
XT_S_FILES = $(notdir $(wildcard $(XT_SRCDIR)/*.S))
# List of all .o files that will go into the library
LIB_C_O = $(patsubst %.c,%.o,$(XT_C_FILES) $(FR_C_FILES))
LIB_S_O = $(patsubst %.S,%.o,$(XT_S_FILES))
LIB_O_LIST = $(addprefix $(BLDDIR)/,$(LIB_C_O) $(LIB_S_O))
# Output files
OSLIB = $(BLDDIR)$(S)libfreertos.a
# Build options
ifeq ($(TARGET),sim)
DFLAGS = -DXT_SIMULATOR
endif
ifeq ($(TARGET),board)
DFLAGS = -DXT_BOARD
endif
IFLAGS = \
-I$(FR_SRCDIR)$(S)..$(S)include -I$(FR_SRCDIR)$(S)..$(S)include$(S)private \
-I$(XT_SRCDIR) -I$(TSTROOT)$(S)common$(S)config_files -I$(BLDDIR)
CFLAGS = -O2 -g
CCFLAGS = $(CFLAGS) -Wall -mno-coproc -mlongcalls -ffunction-sections -mno-l32r-flix $(DFLAGS)
ASFLAGS = $(CCFLAGS)
# Include dependency rules (generated using -MD)
-include $(wildcard $(BLDDIR)/*.d)
# Targets
all : mkdir $(OSLIB)
mkdir : $(BLDDIR)/.mkdir
$(BLDDIR)/.mkdir :
@$(MKPATH) $(BLDDIR)
@echo "" > $@
-$(CP) $(CONFIGDIR)/xtensa-elf/include/sys/reent.h $(BLDDIR)/reent.h
$(OSLIB) : $(LIB_O_LIST)
$(AR) -rs $@ $^
$(BLDDIR)/%.o : %.c
$(CC) $(CCFLAGS) $(IFLAGS) -MD -MF $(subst .o,.d,$@) -c -o $@ $<
$(BLDDIR)/%.o : %.S
$(CC) $(ASFLAGS) $(IFLAGS) -MD -MF $(subst .o,.d,$@) -c -o $@ $<
clean :
$(RM_R) $(BLDDIR)
clean_all :
$(RM_R) $(BLDROOT)
.PHONY : all mkdir clean clean_all

@ -1,209 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2015-2019 Cadence Design Systems, Inc.
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#include <stdlib.h>
#include <xtensa/config/core.h>
#include "xtensa_rtos.h"
#include "FreeRTOS.h"
#include "task.h"
/* Defined in portasm.h */
extern void _frxt_tick_timer_init(void);
/* Defined in xtensa_context.S */
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. */
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
/*-----------------------------------------------------------*/
// 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 )
#else
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
#endif
{
StackType_t * sp;
StackType_t * tp;
XtExcFrame * frame;
#if XCHAL_CP_NUM > 0
uint32_t * p;
#endif
/* Create interrupt stack frame aligned to 16 byte boundary */
sp = ( StackType_t * ) ( ( ( UBaseType_t ) pxTopOfStack - XT_CP_SIZE - XT_STK_FRMSZ ) & ~0xf );
/* Clear the entire frame (do not use memset() because we don't depend on C library) */
for( tp = sp; tp <= pxTopOfStack; ++tp )
{
*tp = 0;
}
frame = ( XtExcFrame * ) sp;
/* Explicitly initialize certain saved registers */
frame->pc = ( UBaseType_t ) pxCode; /* task entrypoint */
frame->a0 = 0; /* to terminate GDB backtrace */
frame->a1 = ( UBaseType_t ) sp + XT_STK_FRMSZ; /* physical top of stack frame */
frame->exit = ( UBaseType_t ) _xt_user_exit; /* user exception exit dispatcher */
/* Set initial PS to int level 0, EXCM disabled ('rfe' will enable), user mode. */
/* Also set entry point argument parameter. */
#ifdef __XTENSA_CALL0_ABI__
frame->a2 = ( UBaseType_t ) pvParameters;
frame->ps = PS_UM | PS_EXCM;
#else
/* + for windowed ABI also set WOE and CALLINC (pretend task was 'call4'd). */
frame->a6 = ( UBaseType_t ) pvParameters;
frame->ps = PS_UM | PS_EXCM | PS_WOE | PS_CALLINC( 1 );
#endif
#ifdef XT_USE_SWPRI
/* Set the initial virtual priority mask value to all 1's. */
frame->vpri = 0xFFFFFFFF;
#endif
#if XCHAL_CP_NUM > 0
/* Init the coprocessor save area (see xtensa_context.h) */
/* No access to TCB here, so derive indirectly. Stack growth is top to bottom.
* //p = (uint32_t *) xMPUSettings->coproc_area;
*/
p = ( uint32_t * ) ( ( ( uint32_t ) pxTopOfStack - XT_CP_SIZE ) & ~0xf );
configASSERT( ( uint32_t ) p >= frame->a1 );
p[ 0 ] = 0;
p[ 1 ] = 0;
p[ 2 ] = ( ( ( uint32_t ) p ) + 12 + XCHAL_TOTAL_SA_ALIGN - 1 ) & -XCHAL_TOTAL_SA_ALIGN;
#endif
return sp;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the Xtensa port will get stopped. If required simply
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
#if XCHAL_CP_NUM > 0
/* Initialize co-processor management for tasks. Leave CPENABLE alone. */
_xt_coproc_init();
#endif
/* Init the tick divisor value */
_xt_tick_divisor_init();
/* Setup the hardware to generate the tick. */
_frxt_tick_timer_init();
#if XT_USE_THREAD_SAFE_CLIB
// Init C library
vPortClibInit();
#endif
port_xSchedulerRunning = 1;
// Cannot be directly called from C; never returns
__asm__ volatile ("call0 _frxt_dispatch\n");
/* Should not get here. */
return pdTRUE;
}
/*-----------------------------------------------------------*/
BaseType_t xPortSysTickHandler( void )
{
BaseType_t ret;
uint32_t interruptMask;
portbenchmarkIntLatency();
/* Interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY must be
* disabled before calling xTaskIncrementTick as it access the
* kernel lists. */
interruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
{
ret = xTaskIncrementTick();
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( interruptMask );
portYIELD_FROM_ISR( ret );
return ret;
}
/*-----------------------------------------------------------*/
/*
* 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,
configSTACK_DEPTH_TYPE uxStackDepth )
{
#if XCHAL_CP_NUM > 0
xMPUSettings->coproc_area = ( StackType_t * ) ( ( uint32_t ) ( pxBottomOfStack + uxStackDepth - 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 */

@ -1,600 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2015-2019 Cadence Design Systems, Inc.
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#include "xtensa_rtos.h"
#define TOPOFSTACK_OFFS 0x00 /* StackType_t *pxTopOfStack */
#define CP_TOPOFSTACK_OFFS 0x04 /* xMPU_SETTINGS.coproc_area */
.extern pxCurrentTCB
/*
*******************************************************************************
* Interrupt stack. The size of the interrupt stack is determined by the config
* parameter "configISR_STACK_SIZE" in FreeRTOSConfig.h
*******************************************************************************
*/
.data
.align 16
.global port_IntStack
port_IntStack:
.space configISR_STACK_SIZE
port_IntStackTop:
.word 0
port_switch_flag:
.word 0
.text
/*
*******************************************************************************
* _frxt_setup_switch
* void _frxt_setup_switch(void);
*
* Sets an internal flag indicating that a task switch is required on return
* from interrupt handling.
*
*******************************************************************************
*/
.global _frxt_setup_switch
.type _frxt_setup_switch,@function
.align 4
_frxt_setup_switch:
ENTRY(16)
movi a2, port_switch_flag
movi a3, 1
s32i a3, a2, 0
RET(16)
/*
*******************************************************************************
* _frxt_int_enter
* void _frxt_int_enter(void)
*
* Implements the Xtensa RTOS porting layer's XT_RTOS_INT_ENTER function for
* freeRTOS. Saves the rest of the interrupt context (not already saved).
* May only be called from assembly code by the 'call0' instruction, with
* interrupts disabled.
* See the detailed description of the XT_RTOS_ENTER macro in xtensa_rtos.h.
*
*******************************************************************************
*/
.globl _frxt_int_enter
.type _frxt_int_enter,@function
.align 4
_frxt_int_enter:
/* Save a12-13 in the stack frame as required by _xt_context_save. */
s32i a12, a1, XT_STK_A12
s32i a13, a1, XT_STK_A13
/* Save return address in a safe place (free a0). */
mov a12, a0
/* Save the rest of the interrupted context (preserves A12-13). */
call0 _xt_context_save
/*
Save interrupted task's SP in TCB only if not nesting.
Manage nesting directly rather than call the generic IntEnter()
(in windowed ABI we can't call a C function here anyway because PS.EXCM is still set).
*/
movi a2, port_xSchedulerRunning
movi a3, port_interruptNesting
l32i a2, a2, 0 /* a2 = port_xSchedulerRunning */
beqz a2, 1f /* scheduler not running, no tasks */
l32i a2, a3, 0 /* a2 = port_interruptNesting */
addi a2, a2, 1 /* increment nesting count */
s32i a2, a3, 0 /* save nesting count */
bnei a2, 1, .Lnested /* !=0 before incr, so nested */
movi a2, pxCurrentTCB
l32i a2, a2, 0 /* a2 = current TCB */
beqz a2, 1f
s32i a1, a2, TOPOFSTACK_OFFS /* pxCurrentTCB->pxTopOfStack = SP */
movi a1, port_IntStackTop /* a1 = top of intr stack */
.Lnested:
1:
mov a0, a12 /* restore return addr and return */
ret
/*
*******************************************************************************
* _frxt_int_exit
* void _frxt_int_exit(void)
*
* Implements the Xtensa RTOS porting layer's XT_RTOS_INT_EXIT function for
* FreeRTOS. If required, calls vPortYieldFromInt() to perform task context
* switching, restore the (possibly) new task's context, and return to the
* exit dispatcher saved in the task's stack frame at XT_STK_EXIT.
* May only be called from assembly code by the 'call0' instruction. Does not
* return to caller.
* See the description of the XT_RTOS_ENTER macro in xtensa_rtos.h.
*
*******************************************************************************
*/
.globl _frxt_int_exit
.type _frxt_int_exit,@function
.align 4
_frxt_int_exit:
movi a2, port_xSchedulerRunning
movi a3, port_interruptNesting
rsil a0, XCHAL_EXCM_LEVEL /* lock out interrupts */
l32i a2, a2, 0 /* a2 = port_xSchedulerRunning */
beqz a2, .Lnoswitch /* scheduler not running, no tasks */
l32i a2, a3, 0 /* a2 = port_interruptNesting */
addi a2, a2, -1 /* decrement nesting count */
s32i a2, a3, 0 /* save nesting count */
bnez a2, .Lnesting /* !=0 after decr so still nested */
movi a2, pxCurrentTCB
l32i a2, a2, 0 /* a2 = current TCB */
beqz a2, 1f /* no task ? go to dispatcher */
l32i a1, a2, TOPOFSTACK_OFFS /* SP = pxCurrentTCB->pxTopOfStack */
movi a2, port_switch_flag /* address of switch flag */
l32i a3, a2, 0 /* a3 = port_switch_flag */
beqz a3, .Lnoswitch /* flag = 0 means no switch reqd */
movi a3, 0
s32i a3, a2, 0 /* zero out the flag for next time */
1:
/*
Call0 ABI callee-saved regs a12-15 need to be saved before possible preemption.
However a12-13 were already saved by _frxt_int_enter().
*/
#ifdef __XTENSA_CALL0_ABI__
s32i a14, a1, XT_STK_A14
s32i a15, a1, XT_STK_A15
#endif
#ifdef __XTENSA_CALL0_ABI__
call0 vPortYieldFromInt /* call dispatch inside the function; never returns */
#else
call4 vPortYieldFromInt /* this one returns */
call0 _frxt_dispatch /* tail-call dispatcher */
/* Never returns here. */
#endif
.Lnoswitch:
/*
If we came here then about to resume the interrupted task.
*/
.Lnesting:
/*
We come here only if there was no context switch, that is if this
is a nested interrupt, or the interrupted task was not preempted.
In either case there's no need to load the SP.
*/
/* Restore full context from interrupt stack frame */
call0 _xt_context_restore
/*
Must return via the exit dispatcher corresponding to the entrypoint from which
this was called. Interruptee's A0, A1, PS, PC are restored and the interrupt
stack frame is deallocated in the exit dispatcher.
*/
l32i a0, a1, XT_STK_EXIT
ret
/*
**********************************************************************************************************
* _frxt_timer_int
* void _frxt_timer_int(void)
*
* Implements the Xtensa RTOS porting layer's XT_RTOS_TIMER_INT function for FreeRTOS.
* Called every timer interrupt.
* Manages the tick timer and calls xPortSysTickHandler() every tick.
* See the detailed description of the XT_RTOS_ENTER macro in xtensa_rtos.h.
*
* Callable from C (obeys ABI conventions). Implemented in assmebly code for performance.
*
**********************************************************************************************************
*/
.globl _frxt_timer_int
.type _frxt_timer_int,@function
.align 4
_frxt_timer_int:
/*
Xtensa timers work by comparing a cycle counter with a preset value. Once the match occurs
an interrupt is generated, and the handler has to set a new cycle count into the comparator.
To avoid clock drift due to interrupt latency, the new cycle count is computed from the old,
not the time the interrupt was serviced. However if a timer interrupt is ever serviced more
than one tick late, it is necessary to process multiple ticks until the new cycle count is
in the future, otherwise the next timer interrupt would not occur until after the cycle
counter had wrapped (2^32 cycles later).
do {
ticks++;
old_ccompare = read_ccompare_i();
write_ccompare_i( old_ccompare + divisor );
service one tick;
diff = read_ccount() - old_ccompare;
} while ( diff > divisor );
*/
ENTRY(16)
.L_xt_timer_int_catchup:
/* Update the timer comparator for the next tick. */
#ifdef XT_CLOCK_FREQ
movi a2, XT_TICK_DIVISOR /* a2 = comparator increment */
#else
movi a3, _xt_tick_divisor
l32i a2, a3, 0 /* a2 = comparator increment */
#endif
rsr a3, XT_CCOMPARE /* a3 = old comparator value */
add a4, a3, a2 /* a4 = new comparator value */
wsr a4, XT_CCOMPARE /* update comp. and clear interrupt */
esync
#ifdef __XTENSA_CALL0_ABI__
/* Preserve a2 and a3 across C calls. */
s32i a2, sp, 4
s32i a3, sp, 8
#endif
/* Call the FreeRTOS tick handler (see port.c). */
#ifdef __XTENSA_CALL0_ABI__
call0 xPortSysTickHandler
#else
call4 xPortSysTickHandler
#endif
#ifdef __XTENSA_CALL0_ABI__
/* Restore a2 and a3. */
l32i a2, sp, 4
l32i a3, sp, 8
#endif
/* Check if we need to process more ticks to catch up. */
esync /* ensure comparator update complete */
rsr a4, CCOUNT /* a4 = cycle count */
sub a4, a4, a3 /* diff = ccount - old comparator */
blt a2, a4, .L_xt_timer_int_catchup /* repeat while diff > divisor */
RET(16)
/*
**********************************************************************************************************
* _frxt_tick_timer_init
* void _frxt_tick_timer_init(void)
*
* Initialize timer and timer interrrupt handler (_xt_tick_divisor_init() has already been been called).
* Callable from C (obeys ABI conventions on entry).
*
**********************************************************************************************************
*/
.globl _frxt_tick_timer_init
.type _frxt_tick_timer_init,@function
.align 4
_frxt_tick_timer_init:
ENTRY(16)
/* Set up the periodic tick timer (assume enough time to complete init). */
#ifdef XT_CLOCK_FREQ
movi a3, XT_TICK_DIVISOR
#else
movi a2, _xt_tick_divisor
l32i a3, a2, 0
#endif
rsr a2, CCOUNT /* current cycle count */
add a2, a2, a3 /* time of first timer interrupt */
wsr a2, XT_CCOMPARE /* set the comparator */
/*
Enable the timer interrupt at the device level. Don't write directly
to the INTENABLE register because it may be virtualized.
*/
#ifdef __XTENSA_CALL0_ABI__
movi a2, XT_TIMER_INTEN
call0 xt_ints_on
#else
movi a6, XT_TIMER_INTEN
call4 xt_ints_on
#endif
RET(16)
/*
**********************************************************************************************************
* DISPATCH THE HIGH READY TASK
* void _frxt_dispatch(void)
*
* Switch context to the highest priority ready task, restore its state and dispatch control to it.
*
* This is a common dispatcher that acts as a shared exit path for all the context switch functions
* including vPortYield() and vPortYieldFromInt(), all of which tail-call this dispatcher
* (for windowed ABI vPortYieldFromInt() calls it indirectly via _frxt_int_exit() ).
*
* The Xtensa port uses different stack frames for solicited and unsolicited task suspension (see
* comments on stack frames in xtensa_context.h). This function restores the state accordingly.
* If restoring a task that solicited entry, restores the minimal state and leaves CPENABLE clear.
* If restoring a task that was preempted, restores all state including the task's CPENABLE.
*
* Entry:
* pxCurrentTCB points to the TCB of the task to suspend,
* Because it is tail-called without a true function entrypoint, it needs no 'entry' instruction.
*
* Exit:
* If incoming task called vPortYield() (solicited), this function returns as if from vPortYield().
* If incoming task was preempted by an interrupt, this function jumps to exit dispatcher.
*
**********************************************************************************************************
*/
.globl _frxt_dispatch
.type _frxt_dispatch,@function
.align 4
_frxt_dispatch:
#ifdef __XTENSA_CALL0_ABI__
call0 vTaskSwitchContext // Get next TCB to resume
movi a2, pxCurrentTCB
#else
movi a2, pxCurrentTCB
call4 vTaskSwitchContext // Get next TCB to resume
#endif
l32i a3, a2, 0
l32i sp, a3, TOPOFSTACK_OFFS /* SP = next_TCB->pxTopOfStack; */
s32i a3, a2, 0
/* Determine the type of stack frame. */
l32i a2, sp, XT_STK_EXIT /* exit dispatcher or solicited flag */
bnez a2, .L_frxt_dispatch_stk
.L_frxt_dispatch_sol:
/* Solicited stack frame. Restore minimal context and return from vPortYield(). */
l32i a3, sp, XT_SOL_PS
#ifdef __XTENSA_CALL0_ABI__
l32i a12, sp, XT_SOL_A12
l32i a13, sp, XT_SOL_A13
l32i a14, sp, XT_SOL_A14
l32i a15, sp, XT_SOL_A15
#endif
l32i a0, sp, XT_SOL_PC
#if XCHAL_CP_NUM > 0
/* Ensure wsr.CPENABLE is complete (should be, it was cleared on entry). */
rsync
#endif
/* As soons as PS is restored, interrupts can happen. No need to sync PS. */
wsr a3, PS
#ifdef __XTENSA_CALL0_ABI__
addi sp, sp, XT_SOL_FRMSZ
ret
#else
retw
#endif
.L_frxt_dispatch_stk:
#if XCHAL_CP_NUM > 0
/* Restore CPENABLE from task's co-processor save area. */
movi a3, pxCurrentTCB /* cp_state = */
l32i a3, a3, 0
l32i a2, a3, CP_TOPOFSTACK_OFFS /* StackType_t *pxStack; */
l16ui a3, a2, XT_CPENABLE /* CPENABLE = cp_state->cpenable; */
wsr a3, CPENABLE
#endif
/* Interrupt stack frame. Restore full context and return to exit dispatcher. */
call0 _xt_context_restore
/* In Call0 ABI, restore callee-saved regs (A12, A13 already restored). */
#ifdef __XTENSA_CALL0_ABI__
l32i a14, sp, XT_STK_A14
l32i a15, sp, XT_STK_A15
#endif
#if XCHAL_CP_NUM > 0
/* Ensure wsr.CPENABLE has completed. */
rsync
#endif
/*
Must return via the exit dispatcher corresponding to the entrypoint from which
this was called. Interruptee's A0, A1, PS, PC are restored and the interrupt
stack frame is deallocated in the exit dispatcher.
*/
l32i a0, sp, XT_STK_EXIT
ret
/*
**********************************************************************************************************
* PERFORM A SOLICTED CONTEXT SWITCH (from a task)
* void vPortYield(void)
*
* This function saves the minimal state needed for a solicited task suspension, clears CPENABLE,
* then tail-calls the dispatcher _frxt_dispatch() to perform the actual context switch
*
* At Entry:
* pxCurrentTCB points to the TCB of the task to suspend
* Callable from C (obeys ABI conventions on entry).
*
* Does not return to caller.
*
**********************************************************************************************************
*/
.globl vPortYield
.type vPortYield,@function
.align 4
vPortYield:
#ifdef __XTENSA_CALL0_ABI__
addi sp, sp, -XT_SOL_FRMSZ
#else
entry sp, XT_SOL_FRMSZ
#endif
rsr a2, PS
s32i a0, sp, XT_SOL_PC
s32i a2, sp, XT_SOL_PS
#ifdef __XTENSA_CALL0_ABI__
s32i a12, sp, XT_SOL_A12 /* save callee-saved registers */
s32i a13, sp, XT_SOL_A13
s32i a14, sp, XT_SOL_A14
s32i a15, sp, XT_SOL_A15
#else
/* Spill register windows. Calling xthal_window_spill() causes extra */
/* spills and reloads, so we will set things up to call the _nw version */
/* instead to save cycles. */
movi a6, ~(PS_WOE_MASK|PS_INTLEVEL_MASK) /* spills a4-a7 if needed */
and a2, a2, a6 /* clear WOE, INTLEVEL */
addi a2, a2, XCHAL_EXCM_LEVEL /* set INTLEVEL */
wsr a2, PS
rsync
call0 xthal_window_spill_nw
l32i a2, sp, XT_SOL_PS /* restore PS */
wsr a2, PS
#endif
rsil a2, XCHAL_EXCM_LEVEL /* disable low/med interrupts */
#if XCHAL_CP_NUM > 0
/* Save coprocessor callee-saved state (if any). At this point CPENABLE */
/* should still reflect which CPs were in use (enabled). */
call0 _xt_coproc_savecs
#endif
movi a2, pxCurrentTCB
movi a3, 0
l32i a2, a2, 0 /* a2 = pxCurrentTCB */
s32i a3, sp, XT_SOL_EXIT /* 0 to flag as solicited frame */
s32i sp, a2, TOPOFSTACK_OFFS /* pxCurrentTCB->pxTopOfStack = SP */
#if XCHAL_CP_NUM > 0
/* Clear CPENABLE, also in task's co-processor state save area. */
l32i a2, a2, CP_TOPOFSTACK_OFFS /* a2 = pxCurrentTCB->cp_state */
movi a3, 0
wsr a3, CPENABLE
beqz a2, 1f
s16i a3, a2, XT_CPENABLE /* clear saved cpenable */
1:
#endif
/* Tail-call dispatcher. */
call0 _frxt_dispatch
/* Never reaches here. */
/*
**********************************************************************************************************
* PERFORM AN UNSOLICITED CONTEXT SWITCH (from an interrupt)
* void vPortYieldFromInt(void)
*
* This calls the context switch hook (removed), saves and clears CPENABLE, then tail-calls the dispatcher
* _frxt_dispatch() to perform the actual context switch.
*
* At Entry:
* Interrupted task context has been saved in an interrupt stack frame at pxCurrentTCB->pxTopOfStack.
* pxCurrentTCB points to the TCB of the task to suspend,
* Callable from C (obeys ABI conventions on entry).
*
* At Exit:
* Windowed ABI defers the actual context switch until the stack is unwound to interrupt entry.
* Call0 ABI tail-calls the dispatcher directly (no need to unwind) so does not return to caller.
*
**********************************************************************************************************
*/
.globl vPortYieldFromInt
.type vPortYieldFromInt,@function
.align 4
vPortYieldFromInt:
ENTRY(16)
#if XCHAL_CP_NUM > 0
/* Save CPENABLE in task's co-processor save area, and clear CPENABLE. */
movi a3, pxCurrentTCB /* cp_state = */
l32i a3, a3, 0
l32i a2, a3, CP_TOPOFSTACK_OFFS
rsr a3, CPENABLE
s16i a3, a2, XT_CPENABLE /* cp_state->cpenable = CPENABLE; */
movi a3, 0
wsr a3, CPENABLE /* disable all co-processors */
#endif
#ifdef __XTENSA_CALL0_ABI__
/* Tail-call dispatcher. */
call0 _frxt_dispatch
/* Never reaches here. */
#else
RET(16)
#endif
/*
**********************************************************************************************************
* _frxt_task_coproc_state
* void _frxt_task_coproc_state(void)
*
* Implements the Xtensa RTOS porting layer's XT_RTOS_CP_STATE function for FreeRTOS.
*
* May only be called when a task is running, not within an interrupt handler (returns 0 in that case).
* May only be called from assembly code by the 'call0' instruction. Does NOT obey ABI conventions.
* Returns in A15 a pointer to the base of the co-processor state save area for the current task.
* See the detailed description of the XT_RTOS_ENTER macro in xtensa_rtos.h.
*
**********************************************************************************************************
*/
#if XCHAL_CP_NUM > 0
.globl _frxt_task_coproc_state
.type _frxt_task_coproc_state,@function
.align 4
_frxt_task_coproc_state:
movi a15, port_xSchedulerRunning /* if (port_xSchedulerRunning */
l32i a15, a15, 0
beqz a15, 1f
movi a15, port_interruptNesting /* && port_interruptNesting == 0 */
l32i a15, a15, 0
bnez a15, 1f
movi a15, pxCurrentTCB
l32i a15, a15, 0 /* && pxCurrentTCB != 0) { */
beqz a15, 2f
l32i a15, a15, CP_TOPOFSTACK_OFFS
ret
1: movi a15, 0
2: ret
#endif /* XCHAL_CP_NUM > 0 */

@ -1,51 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2015-2019 Cadence Design Systems, Inc.
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/*
* This utility helps benchmarking interrupt latency and context switches.
* In order to enable it, set configBENCHMARK to 1 in FreeRTOSConfig.h.
* You will also need to download the FreeRTOS_trace patch that contains
* portbenchmark.c and the complete version of portbenchmark.h
*/
#ifndef PORTBENCHMARK_H
#define PORTBENCHMARK_H
#if configBENCHMARK
#error "You need to download the FreeRTOS_trace patch that overwrites this file"
#endif
#define portbenchmarkINTERRUPT_DISABLE()
#define portbenchmarkINTERRUPT_RESTORE(newstate)
#define portbenchmarkIntLatency()
#define portbenchmarkIntWait()
#define portbenchmarkReset()
#define portbenchmarkPrint()
#endif /* PORTBENCHMARK */

@ -1,230 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2015-2019 Cadence Design Systems, Inc.
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#include "FreeRTOS.h"
#if XT_USE_THREAD_SAFE_CLIB
#if XSHAL_CLIB == XTHAL_CLIB_XCLIB
#include <errno.h>
#include <sys/reent.h>
#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 <errno.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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 */

@ -1,216 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2015-2019 Cadence Design Systems, Inc.
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
#ifndef __ASSEMBLER__
#include <stdint.h>
#include <xtensa/tie/xt_core.h>
#include <xtensa/hal.h>
#include <xtensa/config/core.h>
#include <xtensa/config/system.h> /* required for XSHAL_CLIB */
#include <xtensa/xtruntime.h>
//#include "xtensa_context.h"
/*-----------------------------------------------------------
* Port specific definitions.
*
* The settings in this file configure FreeRTOS correctly for the
* given hardware and compiler.
*
* These settings should not be altered.
*-----------------------------------------------------------
*/
/* Type definitions. */
#define portCHAR 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"
/* 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)
/*-----------------------------------------------------------*/
/* 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 portMEMORY_BARRIER() XT_MEMW()
/*-----------------------------------------------------------*/
/* Fine resolution time */
#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(); \
}
/*-----------------------------------------------------------*/
/* 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
#endif
// porttrace
#if configUSE_TRACE_FACILITY_2
#include "porttrace.h"
#endif
// configASSERT_2 if requested
#if configASSERT_2
#include <stdio.h>
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 <stdio.h>
#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__
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* PORTMACRO_H */

@ -1,49 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2015-2019 Cadence Design Systems, Inc.
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/*
* This utility helps tracing the entering and exiting from tasks.
* It maintains a circular buffer of tasks in the order they execute,
* and their execution time. To enable it, set configUSE_TRACE_FACILITY_2
* to 1 in FreeRTOSConfig.h. You will also need to download the
* FreeRTOS_trace patch that contains porttrace.c and the complete version
* of porttrace.h.
*/
#ifndef PORTTRACE_H
#define PORTTRACE_H
#if configUSE_TRACE_FACILITY_2
#error "You need to download the FreeRTOS_trace patch that overwrites this file"
#endif
#define porttracePrint(nelements)
#define porttraceStamp(stamp, count_incr)
#endif /* PORTTRACE_H */

@ -1,763 +1,11 @@
FreeRTOS Port for Xtensa Configurable and Diamond Processors FreeRTOS Port for Xtensa Configurable Processors
============================================================ ================================================
FreeRTOS Kernel Version 10.0.0 The Xtensa FreeRTOS port has moved and can be found in the
"FreeRTOS-Kernel-Partner-Supported-Ports" submodule of FreeRTOS-Kernel:
FreeRTOS/Source/portable/ThirdParty/Partner-Supported-Ports/Cadence/Xtensa
Introduction Please see the Xtensa-specific README in this location for more details.
------------
This document describes the Xtensa port for FreeRTOS multitasking RTOS.
For an introduction to FreeRTOS itself, please refer to FreeRTOS
documentation.
This port currently works with FreeRTOS kernel version 10.0.0.
Xtensa Configuration Requirements and Restrictions
--------------------------------------------------
The Xtensa configurable architecture supports a vast space of processor
features. This port supports all of them, including custom processor
extensions defined in the TIE language, with certain minimum
requirements. You must use Xtensa Tools to compile and link FreeRTOS and
your application for your Xtensa configuration. The port uses the Xtensa
Hardware Abstraction Layer (HAL) to adapt to your Xtensa configuration.
NOTE: It may be possible to build and run this with the open-source
xtensa-linux tools provided you have the correct overlay for your Xtensa
configuration. However, this has not been tested and is currently not
supported by Cadence.
This port includes optional reentrancy support for the 'newlib' and
'xclib' C runtime libraries distributed with Xtensa Tools, providing
thread-safety on a per task basis (for use in tasks only, not interrupt
handlers).
NOTE: At this time only 'newlib' and 'xclib' C libraries are supported
for thread safety. The 'uclibc' library is not reentrant and does not
provide thread safety at this time. However, if you are not concerned
with reentrancy then you can use any of these libraries.
This port also includes a simple example application that may run on
a supported board or the Xtensa instruction set simulator (ISS). There
are also a couple of test programs used in maintaining the port, which
serve as additional examples.
FreeRTOS for Xtensa configurable processors requires the following minimum
processor configuration options:
- Timer interrupt option with at least one interruptible timer.
- Interrupt option (implied by the timer interrupt option).
- Exception Architecture 2 (XEA2). Please note that XEA1 is NOT supported.
All 'Diamond', 'Xtensa 6', 'Xtensa LX' and 'Xtensa LX2' processors and
most 'Xtensa T1050' processors are configured with XEA2.
All Diamond processor cores meet these requirements and are supported.
Minimal support for certain evaluation boards is provided via a board
independent XTBSP API implemented by a board specific library distributed
with the Xtensa Tools. This provides the board clock frequency and basic
polled drivers for the display and console device. Note that XTBSP
is not a tradtional RTOS "board support package" with RTOS specific
interrupt-driven drivers - it is not specific to any RTOS. Note that
FreeRTOS can run on any Xtensa or Diamond board without this board support
(a "raw" platform), but you will have to provide the clock frequency
and drivers for any on-board devices you want to use.
Installation
------------
The Xtensa port of FreeRTOS is available at this location:
https://github.com/foss-xtensa/amazon-freertos
This download includes the core FreeRTOS source and include files needed
to build the port. You can also download the official release of FreeRTOS
version 1.0.0 or later from this location:
https://github.com/aws/amazon-freertos
The Xtensa port files are currently not included in the official package.
All source is provided along with a Makefile that works for any host
platform supported by Xtensa Tools (Windows, Linux). These instructions
are written for Windows users, but can easily be understood and adapted
to other host platforms.
First install the FreeRTOS common package in a directory of your choosing.
The structure of that package will look like this:
<install directory>
|-- demos
| `-- cadence
| `-- sim
| |-- common
| | |-- application_code
| | | `-- cadence_code
| | `-- config_files
| `-- xplorer
`-- lib
|-- FreeRTOS
| `-- portable
| |-- Common
| |-- MemMang
| `-- XCC
| `-- Xtensa
`-- include
`-- private
The Xtensa Tools are available from Cadence as part of a processor
license. Be sure you have installed the Xtensa Tools and your processor
configuration.
Building FreeRTOS for Xtensa
----------------------------
To build the FreeRTOS library and the example programs, go into the
directory 'demos/cadence/sim' and use the makefile in that directory.
"make all" will build all the examples. There is another makefile in
the 'lib/FreeRTOS/portable/XCC/Xtensa' directory that builds just the
FreeRTOS library.
By default, you will build for the Xtensa instruction set simulator. If
you have a supported emulation board, you can build to run on that. You
can also build to run on a raw Xtensa core with no board support, a
good starting point for supporting your own target platform. Cadence
recommends doing functional development on the simulator because it
is easier to debug with, then move to a board if/when you need to test
hardware drivers or real-time performance.
The provided makefile simplifies building FreeRTOS and the example
for your Xtensa configuration and platform (ISS, board, etc.). There
are detailed instructions in the comments at the top of the makefile.
The makefiles work on Windows and Linux and support incremental builds.
The build for each Xtensa configuration and target platform is placed in
a subdirectory so several core and platform builds can co-exist even with
incremental rebuilds. You may specify the root of the build area (if tou
want it to be elsewhere than under the source tree) by defining BLDROOT
either in the make command or your shell environment.
Building the FreeRTOS Library
-----------------------------
First, be sure you have installed Xtensa Tools and your processor
configuration, and be sure that Xtensa Tools are in your search path.
You can use xt-make, which comes with the Xtensa Tools, to run the
makefiles.
Change directories to the Xtensa port directory:
> cd lib/FreeRTOS/portable/XCC/Xtensa
Now build the FreeRTOS RTOS as a library (libfreertos.a) as follows:
> xt-make
which by default builds for the simulator (TARGET=sim), or:
> xt-make TARGET=board
which builds for a supported board. Note that the board type does not
need to be specified when building the FreeRTOS library.
If you are building for an Xtensa processor configuration that is not the
default you selected when you installed Xtensa Tools, you need to define the
environment variable XTENSA_CORE. If your configuration is not in the
default registry you selected when you installed Xtensa Tools, you also
need to define the environment variable XTENSA_SYSTEM. See tools manuals.
You can avoid defining these in your environment if you pass the variables
you need to redefine into xt-make as follows:
> xt-make XTENSA_CORE=<your_config_name> XTENSA_SYSTEM=<your_registry> ...
There are more details about build options in the comment in the Makefile.
After the library has been built, you must link your application with this
library in order to use FreeRTOS.
Building the FreeRTOS Examples
------------------------------
The provided examples are designed to run on the Xtensa instruction set
simulator (ISS) or a supported evaluation board programmed with your
Xtensa processor configuration.
To build the examples for the default platform (simulator):
> cd demos/cadence/sim
> xt-make all
which is the same as
> xt-make all TARGET=sim
The boards currently supported are the Xilinx ML605 and KC705 FPGA
development boards. To target these boards, type
> xt-make all TARGET=ml605
or
> xt-make all TARGET=kc705
To build in a location other than the default, specify the new location
using the BLDROOT variable. Note that this makefile will invoke the
FreeRTOS library build makefile automatically, passing on the relevant
parameters based on what you specified.
You can override the default compilation options by specifying the new
options via CFLAGS. For example:
> xt-make all TARGET=sim CFLAGS="-O2 -Os -g"
This compiles the examples and links them with the FreeRTOS library
libfreertos.a and the appropriate linker-support package (LSP) for your
target platform (you can override the LSP by adding LSP=<lsp> to the
xt-make command line). The resulting ELF files can be downloaded and
executed on the target. The example binaries appear in the platform
specific subdirectory described earlier.
To build your application with thread-safe C library support, you
need to make certain modifications to the application to plug in and
invoke the reentrancy support. This allows each task to use the library
without interference with other tasks (it is not safe for interrupt
handlers to call the C library).
First, you must define
XT_USE_THREAD_SAFE_CLIB
to a nonzero value either in xtensa_config.h or on the compiler's command
line. Note that the default xtensa_config.h provided with this port does
define this to 1 if either newlib or xclib is detected.
Then, you must also make sure to allocate extra space on the stack for
each task that will use the C library reentrant functions. This extra
space is to be allocated over and above the actual stack space required
by the task itself. The define
XT_STACK_EXTRA_CLIB
specifies the amount of extra space to be added on to the stack to allow
saving the context for the C library as well as the coprocessors if any.
E.g. if your task requires 2000 bytes of stack space, you must allocate
(2000 + XT_STACK_EXTRA_CLIB) bytes for the stack.
IMPORTANT NOTE
--------------
The header file FreeRTOS.h, which is a part of the core FreeRTOS sources,
includes <reent.h> if thread safety for the C libraries is enabled. For
xclib, this file exists in <sys/reent.h> and so is reported as missing.
To work around this, the makefiles supplied with this port will copy the
reent.h header into the build directory during the build process. If you
use a different build process, then you must make sure to copy this file
to a location that is included in the list of include paths. This can be
the build directory or the directory that contains the Xtensa port source
files.
Running or Debugging an Application
-----------------------------------
To execute the example application on the simulator:
> xt-run [--turbo] example.exe
The option --turbo provides much faster, but non-cycle-accurate simulation
(the --turbo option is only available with Xtensa Tools version 7 or later).
To execute on the simulator using the Xplorer GUI based debugger:
> xplorer --debug example.exe
To execute on a supported evaluation board, download example.exe per
instructions in the tools manuals. Be sure the board has been programmed
with the correct configuration and is set up to boot from RAM and debug
a downloaded program! Optionally you may connect a terminal or terminal
emulator to the serial port on the board with settings as described in
the board user manual, and see the output of printf on the terminal.
To obtain I/O on a "raw" platform such as an unsupported board, you need
to provide low level I/O drivers (eg. inbyte() and outbyte() for character
I/O if you want to use printf etc.). You can run "raw" executables on
any Xtensa platform, including simulator and any board, but you will not
see any behavior specific to the platform (eg. display, printed output,
stopping simulation at end of program). You can, while debugging, use a
debugger mechanism called GDBIO to obtain basic I/O. To use GDBIO, link
with the gdbio LSP. Refer to Xtensa tools documentation for details.
Task Stack Sizes
----------------
The application must ensure that every task has enough space for its
stack. Each task needs enough space for its own use, its own interrupt
stack frame (defined in xtensa_context.h) and space to save coprocessor
state, if any. Several factors influence the size of the stack required,
including the compiler optimization level and the use of the C library.
Calls to standard output functions such as printf() can use up a lot of
stack space. The tool xt-stack-usage is helpful in determining safe stack
sizes for your application.
Some macros are provided in xtensa_config.h to help determine the stack
size for tasks that do and do not use the C library. Use these as the
basis for each task's stack size. They are minimum requirements taking
into account your configuration and use of the C library. In particular,
the define
XT_STACK_MIN_SIZE
defines the minimum stack size for any task. Be very careful if you try
to use a stack size smaller than this minimum. Stack overruns can cause
all kinds of hard-to-debug errors. It is recommended that you enable the
FreeRTOS stack checking features during development.
WARNING: The newlib printf() function uses a lot of stack space. Be very
careful in using it. Optionally you can use the 'libxtutil' library for
output - it implements a subset of printf() that has smaller code size
and uses far less stack space. More information about this library is in
the Xtensa Tools documentation.
Interrupt Stack
---------------
Beginning with port version 1.2, the port uses a separate interrupt stack
for handling interrupts. Thus, it is no longer necessary for each task to
reserve space on its stack to handle interrupts. The size of the interrupt
stack is controlled by the parameter "configISR_STACK_SIZE" defined in
FreeRTOSConfig.h. Define this carefully to match your system requirements.
Assembler / Compiler Switches
-----------------------------
The following are compiler switches are used by the provided
Makefile in building the FreeRTOS library and example application.
These can be modified by editing the Makefile or by overriding the
CFLAGS variable in the make command line, for example:
> xt-make CFLAGS="-O2 -DXT_USE_THREAD_SAFE_CLIB"
-g Specifies debug information.
-c Specifies object code generation.
-On Sets compiler optimization level n (default -O0).
-mlongcalls Allows assembler and linker to convert call
instructions to longer indirect call sequences
when target is out of range.
-x assembler-with-cpp Passes .s and .S files through C preprocessor.
-Dmacro Define a preprocessor macro with no value.
-Dmacro=value Define a preprocessor macro with a value.
See the compiler / linker documentation for a full list of switches and
their use.
Many definitions can be provided at compile-time via the -D option
without editing the source code. Here are some of the more useful ones:
XT_USE_THREAD_SAFE_CLIB Enable support for the reentrancy to provide
thread-safety for the newlib and xclib libraries
supplied with Xtensa Tools. Default ON.
Note, the follwing defines are unique to the Xtensa port so have names
beginning with "XT_".
XT_SIMULATOR Set this if building to run on the simulator.
Takes advantage of certain simulator control
and reporting facilities, and adjusts timing
of periodic tick to provide a more acceptable
performance in simulation (see XT_CLOCK_FREQ).
Set by default unless PLATFORM is overridden.
XT_BOARD Set this if building for a supported board.
Be sure to specify the correct LSP for the
board. See the example makefile for usage.
XT_CLOCK_FREQ=freq Specifies the target processor's clock
frequency in Hz. Used primarily to set the
timer that generates the periodic interrupt.
Defaults are provided and may be edited in
xtensa_timer.h (see comments there also).
Default for simulator provides more acceptable
performance, but cannot provide real-time
performance due to variation in simulation
speed per host platform and insufficient
cycles between interrupts to process them.
Supported board platforms by default leave
this undefined and compute the clock frequency
at initialization unless this is explicitly
defined.
XT_TICK_PER_SEC=n Specifies the frequency of the periodic tick.
XT_TIMER_INDEX=n Specifies which timer to use for periodic tick.
Set this if your Xtensa processor configuration
provides more than one suitable timer and you
want to override the default. See xtensa_timer.h .
XT_INTEXC_HOOKS Enables hooks in interrupt vector handlers
to support dynamic installation of exception
and interrupt handlers. Disabled by default.
XT_USE_OVLY Enable code overlay support. It uses a mutex,
hence configUSE_MUTEX must be enabled. This
option is currently unsupported.
XT_USE_SWPRI Enable software prioritization of interrupts.
Enabling this will prioritize interrupts with
higher bit numbers over those with lower bit
numbers at the same level. This works only for
low and medium priority interrupts that can be
dispatched to C handlers.
Register Usage and Stack Frames
-------------------------------
The Xtensa architecture specifies two ABIs that determine how the general
purpose registers a0-a15 are used: the standard windowed ABI use with
the Xtensa windowed register file architecture, and the optional and
more conventional Call0 ABI (required for Xtensa configurations without
a windowed register file).
Xtensa processors may have other special registers (including co-processor
registers and other TIE "states") that are independent of this choice
of ABI. See Xtensa documentation for more details.
In the windowed ABI the registers of the current window are used as follows:
a0 = return address
a1 = stack pointer (alias sp)
a2 = first argument and result of call (in simple cases)
a3-7 = second through sixth arguments of call (in simple cases).
Note that complex or large arguments are passed on the
stack. Details are in the Xtensa Tools manuals.
a8-a15 = available for use as temporaries.
There are no callee-save registers. The windowed hardware automatically
saves registers a0-a3 on a call4, a0-a8 on a call8, a0-a12 on a call12,
by rotating the register window. Hardware triggers window overflow and
underflow exceptions as necessary when registers outside the current
window need to be spilled to preallocated space in the stack frame, or
restored. Complete details are in the Xtensa manuals. The entire windowed
register file is saved and restored on interrupt or task context switch.
The Call0 ABI does not make use of register windows, relying instead
on a fixed set of 16 registers without window rotation.
The Call0 ABI is more conventional and uses registers as follows:
a0 = return address
a1 = stack pointer (alias sp)
a2 = first argument and result of call (in simple cases)
a3-7 = second through sixth arguments of call (in simple cases).
Note that complex or large arguments are passed on the
stack. Details are in the Xtensa Tools manuals.
a8-a11 = scratch.
a12-a15 = callee-save (a function must preserve these for its caller).
On a FreeRTOS API call, callee-save registers are saved only when a task
context switch occurs, and other registers are not saved at all (the caller
does not expect them to be preserved). On an interrupt, callee-saved
registers might only be saved and restored when a task context-switch
occurs, but all other registers are always saved and restored.
An Xtensa processor has other special registers independent of the ABI,
depending on the configuration (including co-processor registers and other
TIE state) that are part of the task context. FreeRTOS preserves all such
registers over an unsolicited context-switch triggered by an interrupt.
However it does NOT preserve these over a solicited context-switch during
a FreeRTOS API call. This bears some explanation. These special registers
are either ignored by the compiler or treated as caller-saved, meaning
that if kept "live" over a function call (ie. need to be preserved)
they must be saved and restored by the caller. Since solicited entry to
FreeRTOS is always made by a function call, FreeRTOS assumes the caller
has saved any of these registers that are "live". FreeRTOS avoids a lot
of overhead by not having to save and restore every special register
(there can be many) on every solicited context switch.
As a consequence, the application developer should NOT assume that special
registers are preserved over a FreeRTOS API call such as vTaskDelay().
If multiple tasks use a register, the caller must save and restore it.
The saved context stack frames for context switches that occur as
a result of interrupt handling (interrupt frame) or from task-level
API calls (solicited frame) are described in human readable form in
xtensa_context.h . All suspended tasks have one of these two types
of stack frames. The top of the suspended task's stack is pointed to
by pxCurrentTCB->pxTopOfStack. A special location common to both stack
frames differentiates solicited and interrupt stack frames.
Improving Performance, Footprint, or Ease of Debugging
------------------------------------------------------
By default FreeRTOS for Xtensa is built with debug (-g) and without
compiler optimizations (-O0). This makes debugging easier. Of course,
-O0 costs performance and usually also increases stack usage. To make
FreeRTOS run faster you can change the Makefile to enable the desired
optimizations or set a predefined optimization level (-O<level>) .
Maximum performance is achieved with -O3 -ipa, but that might increase
the footprint substantially. A good compromise is -O2. See the compiler
manual for details.
Minimal footprint is achieved by optimizing for space with -Os, at the
cost of some performance. See the compiler manual for details.
The Xtensa architecture port-specific assembly files are coded with no
file-scope labels inside functions (all labels inside functions begin with
".L"). This allows a profiler to accurately associate an address with a
function, and also allows the debugger's stack trace to show the correct
function wherever the program counter is within that function. However
there are some tradeoffs in debugging. Local (".L") labels are not
visible to the debugger, so the following limitations may be observed
during debugging:
- You cannot set a breakpoint on a local label inside a function.
- Disassembly will show the entire function, but will get out of sync and
show incorrect opcodes if it crosses any padding before an aligned local
branch target (".L" label, not ".Ln"). Restart disassembly specifying an
address range explicitly between points where there is padding.
Since FreeRTOS is provided in source form, it is not difficult to remove
the ".L" and ".Ln" prefixes from local labels if you want them visible.
They can also be made visible by passing the '-L' option to the assembler
and linker (see the assembler and linker manuals for details).
Interrupt and Exception Handling
--------------------------------
FreeRTOS provides a complete set of efficient exception and first-level
interrupt handlers installed at the appropriate exception and interrupt
vector locations. The Xtensa architecture supports several different
classes of exceptions and interrupts. Being a configurable architecture,
many of these are optional, and the vector locations are determined by
your processor configuration. (Note that Diamond cores are pre-configured
with specific vector locations.) The handlers provided use conditional
compilation to adapt to your processor configuration and include only
the code that is needed.
Xtensa vector locations may reside almost anywhere, including in ROM.
The amount of code space available at each of these locations is
often very small (e.g. due to following vectors). A small stub of
code installed at the vector jumps to the corresponding handler,
usually in RAM. The exception and interrupt handlers are defined in
xtensa_vectors.S. They are not specific to FreeRTOS, but call into
FreeRTOS where appropriate via macros defined in xtensa_rtos.h .
The handlers provided for low and medium priority interrupts are just
dispatchers that save relevant state and call user-definable handlers.
See the files xtensa_vectors.S and xtensa_api.h for more details of how
to create and install application-specific user interrupt handlers.
Similarly, user-defined handlers can be installed for exceptions (other
than a few which are always handled by the OS).
The high priority interrupt handlers provided may be considered templates
into which the application adds code to service specific interrupts.
The places where application handlers should be inserted are tagged with
the comment "USER_EDIT" in xtensa_vectors.S.
This FreeRTOS port supports strict priority-based nesting of interrupts.
An interrupt may only nest on top of one of strictly lower priority.
Equal priority interrupts concurrently pending are handled in an
application-defined sequence before any lower priority interrupts
are handled. During interrupt and exception handling, the processor's
interrupt level (PS.INTLEVEL) is used to control the interrupt priority
level that can be accepted; interrupt sources are not controlled
individually by FreeRTOS (the application is free to access the INTENABLE
register directly to enable/disable individual interrupts, eg. using
Xtensa HAL services). This approach provides the most deterministic
bounds on interrupt latency (for a given priority) and stack depth.
Software prioritization of interrupts at the same priority is controlled
by the definition of XT_USE_SWPRI. See above for a description of this
parameter.
The following subsections describe the handling of each class of exception
and interrupt in more detail. Many have nothing to do with FreeRTOS but
are mentioned because there is code to handle them in xtensa_vectors.S.
User Exception and Interrupt Handler (Low/Medium Priority):
All Xtensa 'general exceptions' come to the user, kernel, or double
exception vector. The exception type is identified by the EXCCAUSE
special register (level 1 interrupts are one particular cause of a
general exception). This port sets up PS to direct all such exceptions
to the user vector. Exceptions taken at the other two vectors usually
indicate a kernel or application bug.
Level 1 interrupts are identified at the beginning of the handler
and are dispatched to a dedicated handler. Then, syscall and alloca
exceptions are identified and dispatched to special handlers described
below. After this, coprocessor exceptions are identified and dispatched
to the coprocessor handler.
Any remaining exceptions are processed as follows:
Having allocated the exception stack frame, the user exception handler
saves the current task state and sets up a C environment and enables
the high-priority class of interrupts (which do not interact with
FreeRTOS), then reads EXCCAUSE and uses the cause (number) to index
into a table of user-specified handlers. The correct handler is then
called. If the handler returns, the context is restored and control is
returned to the code that caused the exception. The user-defined handler
may alter the saved context, or any other system state, that allows the
faulting instruction to be retried.
If the cause is a level 1 (low-priority) or medium-priority interrupt,
the handler enables all interrupts above that priority level after
saving the task context. It then sets up the environment for C code
and then calls the handler (found in the handler table) for the
interrupt number. If the user has not specified a handler, then the
default handler will be called, which will terminate the program.
If the interrupt is for the system timer, it calls a special interrupt
handler for the system timer tick, which calls _frxt_timer_int then
clears its bit from the mask. This interrupt cannot be hooked by the
user-defined handler.
Finally, the handler calls _frxt_int_exit to allow FreeRTOS to perform
any scheduling necessary and return either to the interrupted task
or another.
If software prioritization is enabled, the handler will re-enable all
interrupts at the same level that are numerically higher than the current
one, before calling the user handler. This allows a higher priority
interrupt to pre-empt the lower priority handler.
Medium Priority Interrupt Handlers:
Medium priority interrupts are those at levels 2 up to XCHAL_EXCM_LEVEL,
a configuration-specific maximum interrupt level affected by the global
'exception mode' bit in the processor status word (PS.EXCM).
Interrupt levels above XCHAL_EXCM_LEVEL are of the high-priority class.
The Xtensa hardware documentation considers medium priority interrupts
to be a special case of high-priority interrupts, but from a software
perspective they are very different.
Dispatch of medium-priority interrupts is discussed in the section
above.
High Priority Interrupt Handlers:
High priority interrupts are those strictly above XCHAL_EXCM_LEVEL,
a configuration-specific maximum interrupt level affected by the
global 'exception mode' bit in the processor status word (PS.EXCM).
High priority handlers may not directly interact with FreeRTOS at all,
and are described here only for the sake of completeness. They must
be coded in assembler (may not be coded in C) and are intended to be
used for handling extremely high frequency hardware events that need
to be handled in only a few cycles. A high priority interrupt handler
may trigger a software interrupt at a medium or low priority level to
occasionally signal FreeRTOS. Please see Xtensa documentation.
There is a separate vector and a few special registers for each high
priority interrupt, providing for fast dispatch and efficient nesting
on top of lower priority interrupts. Handlers are templates included
only for the vectors that exist in your Xtensa processor configuration.
These templates are written for only one interrupt per high priority
level to minimize latency servicing very fast time-critical interrupts.
The vector code jumps to the corresponding first-level interrupt handler,
which then executes application-provided assembler code before returning
quickly to the interrupted task or lower priority handler.
Kernel Exception Handler:
Kernel mode is not used in this port of FreeRTOS, and therefore kernel
exceptions should not happen. A stub is provided for the vector that
triggers the debugger (if connected) or calls _xt_panic to freeze the
processor should a kernel exception occur.
Alloca Exception Handler:
Alloca exceptions are generated by the 'movsp' instruction, which
is used only in the windowed ABI. Its purpose is to allocate some
space on top of the stack. Because the window hardware may have
spilled some registers to the 16 byte "base save" area below the
stack pointer, it is necessary to protect those values. The alloca
handler accomplishes this quickly without setting up an interrupt
frame or entering FreeRTOS, by emulating a register underflow and
re-executing 'movsp'.
Syscall Exception Handler:
Syscall exceptions are generated by a 'syscall' instruction.
The windowed ABI specifies that executing this instruction with
a value of zero in register a2 must spill any unsaved registers
in the windowed register file to their pre-determined locations
on the caller's stack. The handler does exactly that, and skips
over the 'syscall' instruction before returning to the caller.
If a2 is non-zero, the handler returns a2 == -1 to the caller.
Co-Processor Exception Handler:
A co-processor exception is generated when a task accesses a
co-processor that it does not "own". Ownership represents which
task's state is currently in the co-processor. Co-processors are
context-switched "lazily" (on demand) only when a non-owning task
uses a co-processor instruction, otherwise a task retains ownership
even when it is preempted from the main processor. The co-processor
exception handler performs the context-switch and manages ownership.
Co-processors may not be used by any code outside the context of a
task. A co-processor exception triggered by code that is not part
of a running task is a fatal error and FreeRTOS for Xtensa will panic.
This restriction is intended 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.
Debug Exception Handler:
A debug exception is caused as a result of running code, such as by
a 'break' instruction or hardware breakpoints and watchpoints, or
as a result of an external debug interrupt, such as from an OCD based
debugger or multiprocessor debug events ("breakin/breakout"). If the
processor is running in OCD mode under control of an OCD-based debugger,
the trigger event immediately halts the processor and gives control to
the OCD debugger. Otherwise control is transferred to the debug vector.
The debug vector handler calls the simulator if running on the ISS,
which then takes control and interacts with any attached debugger.
If running on hardware and not in OCD mode, debug exceptions are not
expected, so the debug handler calls _xt_panic to freeze the processor.
Double Exception Handler:
A double exception is a general exception that happens while the
processor is in exception mode (PS.EXCM set), and thus indicates a
bug in kernel code. The double exception vector handler triggers
the debugger (if connected) or calls _xt_panic to freeze the
processor.
Window Overflow and Underflow Exception Handlers:
Window overflow and underflow handlers are required for use of the
windowed ABI. Each has its own dedicated vector and highly optimized
code that is independent of OS. See Xtensa documentation for details.
Hooks for Dynamic Installation of Handlers:
Optional hooks are provided in the user exception and low level
interrupt handler and all medium and high priority interrupt handlers,
to dynamically install a handler function (which may be coded in C,
unless in a high-priority interrupt handler). These hooks are enabled
and used by automatic regression tests, they are not part of a normal
FreeRTOS build. However an application is free to take advantage of
them. The interrupt/exception hooks are described in xtensa_rtos.h .
It is recommended that the application not make use of these hooks, but
rather use xt_set_interrupt_handler() and xt_set_exception_handler()
to install application-specific handlers. This method is more convenient
and allows arguments to be passed to the handlers. Software prioritization
of interrupts works only with this method. See xtensa_api.h for details.
Overlay Support
Code overlays are currently not supported for FreeRTOS. This will be
supported in a future release. Make sure that the option XT_USE_OVLY is
never defined when building.
-End- -End-

@ -1,127 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2015-2019 Cadence Design Systems, Inc.
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/*
* Xtensa-specific API for RTOS ports.
*/
#ifndef __XTENSA_API_H__
#define __XTENSA_API_H__
#include <xtensa/hal.h>
#include "xtensa_context.h"
/* Typedef for C-callable interrupt handler function */
typedef void (*xt_handler)(void *);
/* Typedef for C-callable exception handler function */
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 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 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)
{
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)
{
xthal_set_intclear(arg);
}
#endif /* __XTENSA_API_H__ */

@ -1,191 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2015-2019 Cadence Design Systems, Inc.
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/*
* Configuration-specific information for Xtensa build. This file must be
* included in FreeRTOSConfig.h to properly set up the config-dependent
* parameters correctly.
*
* NOTE: 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.
*/
#ifndef XTENSA_CONFIG_H
#define XTENSA_CONFIG_H
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
#include <xtensa/hal.h>
#include <xtensa/config/core.h>
#include <xtensa/config/system.h> /* 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.
*
-----------------------------------------------------------------------------*/
/* 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
#else
#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
#else
#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 <sys/reent.h>
#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 <sys/reent.h>
#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.
------------------------------------------------------------------------------*/
#ifdef __XTENSA_CALL0_ABI__
#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)
#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.
------------------------------------------------------------------------------*/
#ifdef __XTENSA_CALL0_ABI__
#define XT_USER_SIZE 0x200
#else
#define XT_USER_SIZE 0x400
#endif
/* Minimum recommended stack size. */
#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)
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* XTENSA_CONFIG_H */

@ -1,630 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2015-2019 Cadence Design Systems, Inc.
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/*
* XTENSA CONTEXT SAVE AND RESTORE ROUTINES
*
* Low-level Call0 functions for handling generic context save and restore of
* registers not specifically addressed by the interrupt vectors and handlers.
* Those registers (not handled by these functions) are PC, PS, A0, A1 (SP).
* Except for the calls to RTOS functions, this code is generic to Xtensa.
*
* Note that in Call0 ABI, interrupt handlers are expected to preserve the callee-
* save regs (A12-A15), which is always the case if the handlers are coded in C.
* However A12, A13 are made available as scratch registers for interrupt dispatch
* code, so are presumed saved anyway, and are always restored even in Call0 ABI.
* Only A14, A15 are truly handled as callee-save regs.
*
* Because Xtensa is a configurable architecture, this port supports all user
* generated configurations (except restrictions stated in the release notes).
* This is accomplished by conditional compilation using macros and functions
* defined in the Xtensa HAL (hardware adaptation layer) for your configuration.
* Only the processor state included in your configuration is saved and restored,
* including any processor state added by user configuration options or TIE.
*/
/* Warn nicely if this file gets named with a lowercase .s instead of .S: */
#define NOERROR #
NOERROR: .error "C preprocessor needed for this file: make sure its filename\
ends in uppercase .S, or use xt-xcc's -x assembler-with-cpp option."
#include "xtensa_rtos.h"
#ifdef XT_USE_OVLY
#include <xtensa/overlay_os_asm.h>
#endif
.text
.literal_position
/*******************************************************************************
_xt_context_save
!! MUST BE CALLED ONLY BY 'CALL0' INSTRUCTION !!
Saves all Xtensa processor state except PC, PS, A0, A1 (SP), A12, A13, in the
interrupt stack frame defined in xtensa_rtos.h.
Its counterpart is _xt_context_restore (which also restores A12, A13).
Caller is expected to have saved PC, PS, A0, A1 (SP), A12, A13 in the frame.
This function preserves A12 & A13 in order to provide the caller with 2 scratch
regs that need not be saved over the call to this function. The choice of which
2 regs to provide is governed by xthal_window_spill_nw and xthal_save_extra_nw,
to avoid moving data more than necessary. Caller can assign regs accordingly.
Entry Conditions:
A0 = Return address in caller.
A1 = Stack pointer of interrupted thread or handler ("interruptee").
Original A12, A13 have already been saved in the interrupt stack frame.
Other processor state except PC, PS, A0, A1 (SP), A12, A13, is as at the
point of interruption.
If windowed ABI, PS.EXCM = 1 (exceptions disabled).
Exit conditions:
A0 = Return address in caller.
A1 = Stack pointer of interrupted thread or handler ("interruptee").
A12, A13 as at entry (preserved).
If windowed ABI, PS.EXCM = 1 (exceptions disabled).
*******************************************************************************/
.global _xt_context_save
.type _xt_context_save,@function
.align 4
_xt_context_save:
s32i a2, sp, XT_STK_A2
s32i a3, sp, XT_STK_A3
s32i a4, sp, XT_STK_A4
s32i a5, sp, XT_STK_A5
s32i a6, sp, XT_STK_A6
s32i a7, sp, XT_STK_A7
s32i a8, sp, XT_STK_A8
s32i a9, sp, XT_STK_A9
s32i a10, sp, XT_STK_A10
s32i a11, sp, XT_STK_A11
/*
Call0 ABI callee-saved regs a12-15 do not need to be saved here.
a12-13 are the caller's responsibility so it can use them as scratch.
So only need to save a14-a15 here for Windowed ABI (not Call0).
*/
#ifndef __XTENSA_CALL0_ABI__
s32i a14, sp, XT_STK_A14
s32i a15, sp, XT_STK_A15
#endif
rsr a3, SAR
s32i a3, sp, XT_STK_SAR
#if XCHAL_HAVE_LOOPS
rsr a3, LBEG
s32i a3, sp, XT_STK_LBEG
rsr a3, LEND
s32i a3, sp, XT_STK_LEND
rsr a3, LCOUNT
s32i a3, sp, XT_STK_LCOUNT
#endif
#if XT_USE_SWPRI
/* Save virtual priority mask */
movi a3, _xt_vpri_mask
l32i a3, a3, 0
s32i a3, sp, XT_STK_VPRI
#endif
#if XCHAL_EXTRA_SA_SIZE > 0 || !defined(__XTENSA_CALL0_ABI__)
mov a9, a0 /* preserve ret addr */
#endif
#ifndef __XTENSA_CALL0_ABI__
/*
To spill the reg windows, temp. need pre-interrupt stack ptr and a4-15.
Need to save a9,12,13 temporarily (in frame temps) and recover originals.
Interrupts need to be disabled below XCHAL_EXCM_LEVEL and window overflow
and underflow exceptions disabled (assured by PS.EXCM == 1).
*/
s32i a12, sp, XT_STK_TMP0 /* temp. save stuff in stack frame */
s32i a13, sp, XT_STK_TMP1
s32i a9, sp, XT_STK_TMP2
/*
Save the overlay state if we are supporting overlays. Since we just saved
three registers, we can conveniently use them here. Note that as of now,
overlays only work for windowed calling ABI.
*/
#ifdef XT_USE_OVLY
l32i a9, sp, XT_STK_PC /* recover saved PC */
_xt_overlay_get_state a9, a12, a13
s32i a9, sp, XT_STK_OVLY /* save overlay state */
#endif
l32i a12, sp, XT_STK_A12 /* recover original a9,12,13 */
l32i a13, sp, XT_STK_A13
l32i a9, sp, XT_STK_A9
addi sp, sp, XT_STK_FRMSZ /* restore the interruptee's SP */
call0 xthal_window_spill_nw /* preserves only a4,5,8,9,12,13 */
addi sp, sp, -XT_STK_FRMSZ
l32i a12, sp, XT_STK_TMP0 /* recover stuff from stack frame */
l32i a13, sp, XT_STK_TMP1
l32i a9, sp, XT_STK_TMP2
#endif
#if XCHAL_EXTRA_SA_SIZE > 0
/*
NOTE: Normally the xthal_save_extra_nw macro only affects address
registers a2-a5. It is theoretically possible for Xtensa processor
designers to write TIE that causes more address registers to be
affected, but it is generally unlikely. If that ever happens,
more registers need to be saved/restored around this macro invocation.
Here we assume a9,12,13 are preserved.
Future Xtensa tools releases might limit the regs that can be affected.
*/
addi a2, sp, XT_STK_EXTRA /* where to save it */
# if XCHAL_EXTRA_SA_ALIGN > 16
movi a3, -XCHAL_EXTRA_SA_ALIGN
and a2, a2, a3 /* align dynamically >16 bytes */
# endif
call0 xthal_save_extra_nw /* destroys a0,2,3,4,5 */
#endif
#if XCHAL_EXTRA_SA_SIZE > 0 || !defined(__XTENSA_CALL0_ABI__)
mov a0, a9 /* retrieve ret addr */
#endif
ret
/*******************************************************************************
_xt_context_restore
!! MUST BE CALLED ONLY BY 'CALL0' INSTRUCTION !!
Restores all Xtensa processor state except PC, PS, A0, A1 (SP) (and in Call0
ABI, A14, A15 which are preserved by all interrupt handlers) from an interrupt
stack frame defined in xtensa_rtos.h .
Its counterpart is _xt_context_save (whose caller saved A12, A13).
Caller is responsible to restore PC, PS, A0, A1 (SP).
Entry Conditions:
A0 = Return address in caller.
A1 = Stack pointer of interrupted thread or handler ("interruptee").
Exit conditions:
A0 = Return address in caller.
A1 = Stack pointer of interrupted thread or handler ("interruptee").
Other processor state except PC, PS, A0, A1 (SP), is as at the point
of interruption.
*******************************************************************************/
.global _xt_context_restore
.type _xt_context_restore,@function
.align 4
_xt_context_restore:
#if XCHAL_EXTRA_SA_SIZE > 0
/*
NOTE: Normally the xthal_restore_extra_nw macro only affects address
registers a2-a5. It is theoretically possible for Xtensa processor
designers to write TIE that causes more address registers to be
affected, but it is generally unlikely. If that ever happens,
more registers need to be saved/restored around this macro invocation.
Here we only assume a13 is preserved.
Future Xtensa tools releases might limit the regs that can be affected.
*/
mov a13, a0 /* preserve ret addr */
addi a2, sp, XT_STK_EXTRA /* where to find it */
# if XCHAL_EXTRA_SA_ALIGN > 16
movi a3, -XCHAL_EXTRA_SA_ALIGN
and a2, a2, a3 /* align dynamically >16 bytes */
# endif
call0 xthal_restore_extra_nw /* destroys a0,2,3,4,5 */
mov a0, a13 /* retrieve ret addr */
#endif
#if XCHAL_HAVE_LOOPS
l32i a2, sp, XT_STK_LBEG
l32i a3, sp, XT_STK_LEND
wsr a2, LBEG
l32i a2, sp, XT_STK_LCOUNT
wsr a3, LEND
wsr a2, LCOUNT
#endif
#ifdef XT_USE_OVLY
/*
If we are using overlays, this is a good spot to check if we need
to restore an overlay for the incoming task. Here we have a bunch
of registers to spare. Note that this step is going to use a few
bytes of storage below SP (SP-20 to SP-32) if an overlay is going
to be restored.
*/
l32i a2, sp, XT_STK_PC /* retrieve PC */
l32i a3, sp, XT_STK_PS /* retrieve PS */
l32i a4, sp, XT_STK_OVLY /* retrieve overlay state */
l32i a5, sp, XT_STK_A1 /* retrieve stack ptr */
_xt_overlay_check_map a2, a3, a4, a5, a6
s32i a2, sp, XT_STK_PC /* save updated PC */
s32i a3, sp, XT_STK_PS /* save updated PS */
#endif
#ifdef XT_USE_SWPRI
/* Restore virtual interrupt priority and interrupt enable */
movi a3, _xt_intdata
l32i a4, a3, 0 /* a4 = _xt_intenable */
l32i a5, sp, XT_STK_VPRI /* a5 = saved _xt_vpri_mask */
and a4, a4, a5
wsr a4, INTENABLE /* update INTENABLE */
s32i a5, a3, 4 /* restore _xt_vpri_mask */
#endif
l32i a3, sp, XT_STK_SAR
l32i a2, sp, XT_STK_A2
wsr a3, SAR
l32i a3, sp, XT_STK_A3
l32i a4, sp, XT_STK_A4
l32i a5, sp, XT_STK_A5
l32i a6, sp, XT_STK_A6
l32i a7, sp, XT_STK_A7
l32i a8, sp, XT_STK_A8
l32i a9, sp, XT_STK_A9
l32i a10, sp, XT_STK_A10
l32i a11, sp, XT_STK_A11
/*
Call0 ABI callee-saved regs a12-15 do not need to be restored here.
However a12-13 were saved for scratch before XT_RTOS_INT_ENTER(),
so need to be restored anyway, despite being callee-saved in Call0.
*/
l32i a12, sp, XT_STK_A12
l32i a13, sp, XT_STK_A13
#ifndef __XTENSA_CALL0_ABI__
l32i a14, sp, XT_STK_A14
l32i a15, sp, XT_STK_A15
#endif
ret
/*******************************************************************************
_xt_coproc_init
Initializes global co-processor management data, setting all co-processors
to "unowned". Leaves CPENABLE as it found it (does NOT clear it).
Called during initialization of the RTOS, before any threads run.
This may be called from normal Xtensa single-threaded application code which
might use co-processors. The Xtensa run-time initialization enables all
co-processors. They must remain enabled here, else a co-processor exception
might occur outside of a thread, which the exception handler doesn't expect.
Entry Conditions:
Xtensa single-threaded run-time environment is in effect.
No thread is yet running.
Exit conditions:
None.
Obeys ABI conventions per prototype:
void _xt_coproc_init(void)
*******************************************************************************/
#if XCHAL_CP_NUM > 0
.global _xt_coproc_init
.type _xt_coproc_init,@function
.align 4
_xt_coproc_init:
ENTRY0
/* Initialize thread co-processor ownerships to 0 (unowned). */
movi a2, _xt_coproc_owner_sa /* a2 = base of owner array */
addi a3, a2, XCHAL_CP_MAX << 2 /* a3 = top+1 of owner array */
movi a4, 0 /* a4 = 0 (unowned) */
1: s32i a4, a2, 0
addi a2, a2, 4
bltu a2, a3, 1b
RET0
#endif
/*******************************************************************************
_xt_coproc_release
Releases any and all co-processors owned by a given thread. The thread is
identified by it's co-processor state save area defined in xtensa_context.h .
Must be called before a thread's co-proc save area is deleted to avoid
memory corruption when the exception handler tries to save the state.
May be called when a thread terminates or completes but does not delete
the co-proc save area, to avoid the exception handler having to save the
thread's co-proc state before another thread can use it (optimization).
Entry Conditions:
A2 = Pointer to base of co-processor state save area.
Exit conditions:
None.
Obeys ABI conventions per prototype:
void _xt_coproc_release(void * coproc_sa_base)
*******************************************************************************/
#if XCHAL_CP_NUM > 0
.global _xt_coproc_release
.type _xt_coproc_release,@function
.align 4
_xt_coproc_release:
ENTRY0 /* a2 = base of save area */
movi a3, _xt_coproc_owner_sa /* a3 = base of owner array */
addi a4, a3, XCHAL_CP_MAX << 2 /* a4 = top+1 of owner array */
movi a5, 0 /* a5 = 0 (unowned) */
rsil a6, XCHAL_EXCM_LEVEL /* lock interrupts */
1: l32i a7, a3, 0 /* a7 = owner at a3 */
bne a2, a7, 2f /* if (coproc_sa_base == owner) */
s32i a5, a3, 0 /* owner = unowned */
2: addi a3, a3, 1<<2 /* a3 = next entry in owner array */
bltu a3, a4, 1b /* repeat until end of array */
3: wsr a6, PS /* restore interrupts */
RET0
#endif
/*******************************************************************************
_xt_coproc_savecs
If there is a current thread and it has a coprocessor state save area, then
save all callee-saved state into this area. This function is called from the
solicited context switch handler. It calls a system-specific function to get
the coprocessor save area base address.
Entry conditions:
- The thread being switched out is still the current thread.
- CPENABLE state reflects which coprocessors are active.
- Registers have been saved/spilled already.
Exit conditions:
- All necessary CP callee-saved state has been saved.
- Registers a2-a7, a13-a15 have been trashed.
Must be called from assembly code only, using CALL0.
*******************************************************************************/
#if XCHAL_CP_NUM > 0
.extern _xt_coproc_sa_offset /* external reference */
.global _xt_coproc_savecs
.type _xt_coproc_savecs,@function
.align 4
_xt_coproc_savecs:
/* At entry, CPENABLE should be showing which CPs are enabled. */
rsr a2, CPENABLE /* a2 = which CPs are enabled */
beqz a2, .Ldone /* quick exit if none */
mov a14, a0 /* save return address */
call0 XT_RTOS_CP_STATE /* get address of CP save area */
mov a0, a14 /* restore return address */
beqz a15, .Ldone /* if none then nothing to do */
s16i a2, a15, XT_CP_CS_ST /* save mask of CPs being stored */
movi a13, _xt_coproc_sa_offset /* array of CP save offsets */
l32i a15, a15, XT_CP_ASA /* a15 = base of aligned save area */
#if XCHAL_CP0_SA_SIZE
bbci.l a2, 0, 2f /* CP 0 not enabled */
l32i a14, a13, 0 /* a14 = _xt_coproc_sa_offset[0] */
add a3, a14, a15 /* a3 = save area for CP 0 */
xchal_cp0_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP1_SA_SIZE
bbci.l a2, 1, 2f /* CP 1 not enabled */
l32i a14, a13, 4 /* a14 = _xt_coproc_sa_offset[1] */
add a3, a14, a15 /* a3 = save area for CP 1 */
xchal_cp1_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP2_SA_SIZE
bbci.l a2, 2, 2f
l32i a14, a13, 8
add a3, a14, a15
xchal_cp2_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP3_SA_SIZE
bbci.l a2, 3, 2f
l32i a14, a13, 12
add a3, a14, a15
xchal_cp3_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP4_SA_SIZE
bbci.l a2, 4, 2f
l32i a14, a13, 16
add a3, a14, a15
xchal_cp4_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP5_SA_SIZE
bbci.l a2, 5, 2f
l32i a14, a13, 20
add a3, a14, a15
xchal_cp5_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP6_SA_SIZE
bbci.l a2, 6, 2f
l32i a14, a13, 24
add a3, a14, a15
xchal_cp6_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP7_SA_SIZE
bbci.l a2, 7, 2f
l32i a14, a13, 28
add a3, a14, a15
xchal_cp7_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
.Ldone:
ret
#endif
/*******************************************************************************
_xt_coproc_restorecs
Restore any callee-saved coprocessor state for the incoming thread.
This function is called from coprocessor exception handling, when giving
ownership to a thread that solicited a context switch earlier. It calls a
system-specific function to get the coprocessor save area base address.
Entry conditions:
- The incoming thread is set as the current thread.
- CPENABLE is set up correctly for all required coprocessors.
- a2 = mask of coprocessors to be restored.
Exit conditions:
- All necessary CP callee-saved state has been restored.
- CPENABLE - unchanged.
- Registers a2-a7, a13-a15 have been trashed.
Must be called from assembly code only, using CALL0.
*******************************************************************************/
#if XCHAL_CP_NUM > 0
.global _xt_coproc_restorecs
.type _xt_coproc_restorecs,@function
.align 4
_xt_coproc_restorecs:
mov a14, a0 /* save return address */
call0 XT_RTOS_CP_STATE /* get address of CP save area */
mov a0, a14 /* restore return address */
beqz a15, .Ldone2 /* if none then nothing to do */
l16ui a3, a15, XT_CP_CS_ST /* a3 = which CPs have been saved */
xor a3, a3, a2 /* clear the ones being restored */
s32i a3, a15, XT_CP_CS_ST /* update saved CP mask */
movi a13, _xt_coproc_sa_offset /* array of CP save offsets */
l32i a15, a15, XT_CP_ASA /* a15 = base of aligned save area */
#if XCHAL_CP0_SA_SIZE
bbci.l a2, 0, 2f /* CP 0 not enabled */
l32i a14, a13, 0 /* a14 = _xt_coproc_sa_offset[0] */
add a3, a14, a15 /* a3 = save area for CP 0 */
xchal_cp0_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP1_SA_SIZE
bbci.l a2, 1, 2f /* CP 1 not enabled */
l32i a14, a13, 4 /* a14 = _xt_coproc_sa_offset[1] */
add a3, a14, a15 /* a3 = save area for CP 1 */
xchal_cp1_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP2_SA_SIZE
bbci.l a2, 2, 2f
l32i a14, a13, 8
add a3, a14, a15
xchal_cp2_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP3_SA_SIZE
bbci.l a2, 3, 2f
l32i a14, a13, 12
add a3, a14, a15
xchal_cp3_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP4_SA_SIZE
bbci.l a2, 4, 2f
l32i a14, a13, 16
add a3, a14, a15
xchal_cp4_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP5_SA_SIZE
bbci.l a2, 5, 2f
l32i a14, a13, 20
add a3, a14, a15
xchal_cp5_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP6_SA_SIZE
bbci.l a2, 6, 2f
l32i a14, a13, 24
add a3, a14, a15
xchal_cp6_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP7_SA_SIZE
bbci.l a2, 7, 2f
l32i a14, a13, 28
add a3, a14, a15
xchal_cp7_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
.Ldone2:
ret
#endif

@ -1,355 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2015-2019 Cadence Design Systems, Inc.
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/*
* XTENSA CONTEXT FRAMES AND MACROS FOR RTOS ASSEMBLER SOURCES
*
* This header contains definitions and macros for use primarily by Xtensa
* RTOS assembly coded source files. It includes and uses the Xtensa hardware
* abstraction layer (HAL) to deal with config specifics. It may also be
* included in C source files.
*
* !! Supports only Xtensa Exception Architecture 2 (XEA2). XEA1 not supported. !!
*
* NOTE: The Xtensa architecture requires stack pointer alignment to 16 bytes.
*/
#ifndef XTENSA_CONTEXT_H
#define XTENSA_CONTEXT_H
#ifdef __ASSEMBLER__
#include <xtensa/coreasm.h>
#endif
#include <xtensa/config/tie.h>
#include <xtensa/corebits.h>
#include <xtensa/config/system.h>
/* Align a value up to nearest n-byte boundary, where n is a power of 2. */
#define ALIGNUP(n, val) (((val) + (n)-1) & -(n))
/*
-------------------------------------------------------------------------------
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
#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;
#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.
-------------------------------------------------------------------------------
*/
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)
#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)
#endif
#ifdef XT_USE_SWPRI
/* Storage for virtual priority mask */
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)
#endif
STRUCT_END(XtExcFrame)
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
#define XT_STK_NEXT1 XtExcFrameSize
#else
#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 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)
#else
#define XT_STK_NEXT2 XT_STK_NEXT1
#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)
/*
-------------------------------------------------------------------------------
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)
#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
STRUCT_END(XtSolFrame)
/* Size of solicited stack frame */
#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-switch, 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)
/* 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 */
/* Overall size allows for dynamic alignment: */
#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.
-------------------------------------------------------------------------------
*/
#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 */

@ -1,70 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2015-2019 Cadence Design Systems, Inc.
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/*
* XTENSA INITIALIZATION ROUTINES CODED IN C
*
* This file contains miscellaneous Xtensa RTOS-generic initialization functions
* that are implemented in C.
*/
#ifdef XT_BOARD
#include <xtensa/xtbsp.h>
#endif
#include "xtensa_rtos.h"
#ifdef XT_RTOS_TIMER_INT
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 */
}
#endif /* XT_RTOS_TIMER_INT */

@ -1,137 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2015-2019 Cadence Design Systems, Inc.
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/*
* Xtensa-specific interrupt and exception functions for RTOS ports.
* Also see xtensa_intr_asm.S.
*/
#include <stdlib.h>
#include <xtensa/config/core.h>
#include "xtensa_api.h"
#if XCHAL_HAVE_EXCEPTIONS
/* Handler table is in xtensa_intr_asm.S */
extern xt_exc_handler _xt_exception_table[XCHAL_EXCCAUSE_NUM];
/*
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);
}
#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;
extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS];
/*
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);
}
#endif /* XCHAL_HAVE_INTERRUPTS */

@ -1,183 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2015-2019 Cadence Design Systems, Inc.
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/*
* Xtensa interrupt handling data and assembly routines.
* Also see xtensa_intr.c and xtensa_vectors.S.
*/
#include <xtensa/hal.h>
#include <xtensa/config/core.h>
#include "xtensa_context.h"
#if XCHAL_HAVE_INTERRUPTS
/*
-------------------------------------------------------------------------------
INTENABLE virtualization information.
-------------------------------------------------------------------------------
*/
.data
.global _xt_intdata
.align 8
_xt_intdata:
.global _xt_intenable
.type _xt_intenable,@object
.size _xt_intenable,4
.global _xt_vpri_mask
.type _xt_vpri_mask,@object
.size _xt_vpri_mask,4
_xt_intenable: .word 0 /* Virtual INTENABLE */
_xt_vpri_mask: .word 0xFFFFFFFF /* Virtual priority mask */
/*
-------------------------------------------------------------------------------
Table of C-callable interrupt handlers for each interrupt. Note that not all
slots can be filled, because interrupts at level > EXCM_LEVEL will not be
dispatched to a C handler by default.
-------------------------------------------------------------------------------
*/
.data
.global _xt_interrupt_table
.align 8
_xt_interrupt_table:
.set i, 0
.rept XCHAL_NUM_INTERRUPTS
.word xt_unhandled_interrupt /* handler address */
.word i /* handler arg (default: intnum) */
.set i, i+1
.endr
#endif /* XCHAL_HAVE_INTERRUPTS */
#if XCHAL_HAVE_EXCEPTIONS
/*
-------------------------------------------------------------------------------
Table of C-callable exception handlers for each exception. Note that not all
slots will be active, because some exceptions (e.g. coprocessor exceptions)
are always handled by the OS and cannot be hooked by user handlers.
-------------------------------------------------------------------------------
*/
.data
.global _xt_exception_table
.align 4
_xt_exception_table:
.rept XCHAL_EXCCAUSE_NUM
.word xt_unhandled_exception /* handler address */
.endr
#endif
/*
-------------------------------------------------------------------------------
unsigned int xt_ints_on ( unsigned int mask )
Enables a set of interrupts. Does not simply set INTENABLE directly, but
computes it as a function of the current virtual priority.
Can be called from interrupt handlers.
-------------------------------------------------------------------------------
*/
.text
.align 4
.global xt_ints_on
.type xt_ints_on,@function
xt_ints_on:
ENTRY0
#if XCHAL_HAVE_INTERRUPTS
movi a3, 0
movi a4, _xt_intdata
xsr a3, INTENABLE /* Disables all interrupts */
rsync
l32i a3, a4, 0 /* a3 = _xt_intenable */
l32i a6, a4, 4 /* a6 = _xt_vpri_mask */
or a5, a3, a2 /* a5 = _xt_intenable | mask */
s32i a5, a4, 0 /* _xt_intenable |= mask */
and a5, a5, a6 /* a5 = _xt_intenable & _xt_vpri_mask */
wsr a5, INTENABLE /* Reenable interrupts */
mov a2, a3 /* Previous mask */
#else
movi a2, 0 /* Return zero */
#endif
RET0
.size xt_ints_on, . - xt_ints_on
/*
-------------------------------------------------------------------------------
unsigned int xt_ints_off ( unsigned int mask )
Disables a set of interrupts. Does not simply set INTENABLE directly,
but computes it as a function of the current virtual priority.
Can be called from interrupt handlers.
-------------------------------------------------------------------------------
*/
.text
.align 4
.global xt_ints_off
.type xt_ints_off,@function
xt_ints_off:
ENTRY0
#if XCHAL_HAVE_INTERRUPTS
movi a3, 0
movi a4, _xt_intdata
xsr a3, INTENABLE /* Disables all interrupts */
rsync
l32i a3, a4, 0 /* a3 = _xt_intenable */
l32i a6, a4, 4 /* a6 = _xt_vpri_mask */
or a5, a3, a2 /* a5 = _xt_intenable | mask */
xor a5, a5, a2 /* a5 = _xt_intenable & ~mask */
s32i a5, a4, 0 /* _xt_intenable &= ~mask */
and a5, a5, a6 /* a5 = _xt_intenable & _xt_vpri_mask */
wsr a5, INTENABLE /* Reenable interrupts */
mov a2, a3 /* Previous mask */
#else
movi a2, 0 /* return zero */
#endif
RET0
.size xt_ints_off, . - xt_ints_off

@ -1,76 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2015-2019 Cadence Design Systems, Inc.
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/*
* xtensa_overlay_os_hook.c -- Overlay manager OS hooks for FreeRTOS.
*/
#include "FreeRTOS.h"
#include "semphr.h"
#if configUSE_MUTEX
/* 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;
/* This function should be overridden to provide OS specific init such
* as the creation of a mutex lock that can be used for overlay locking.
* 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();
}
/* This function locks access to shared overlay resources, typically
* by acquiring a mutex.
*/
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);
}
#endif

@ -1,238 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2015-2019 Cadence Design Systems, Inc.
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/*
* RTOS-SPECIFIC INFORMATION FOR XTENSA RTOS ASSEMBLER SOURCES
* (FreeRTOS Port)
*
* This header is the primary glue between generic Xtensa RTOS support
* sources and a specific RTOS port for Xtensa. It contains definitions
* and macros for use primarily by Xtensa assembly coded source files.
*
* Macros in this header map callouts from generic Xtensa files to specific
* RTOS functions. It may also be included in C source files.
*
* Xtensa RTOS ports support all RTOS-compatible configurations of the Xtensa
* architecture, using the Xtensa hardware abstraction layer (HAL) to deal
* with configuration specifics.
*
* Should be included by all Xtensa generic and RTOS port-specific sources.
*/
#ifndef XTENSA_RTOS_H
#define XTENSA_RTOS_H
#ifdef __ASSEMBLER__
#include <xtensa/coreasm.h>
#else
#include <xtensa/config/core.h>
#endif
#include <xtensa/corebits.h>
#include <xtensa/config/system.h>
#include <xtensa/simcall.h>
/*
Include any RTOS specific definitions that are needed by this header.
*/
#include <FreeRTOSConfig.h>
/*
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
#endif
#ifndef XT_BOARD
#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
#endif
#ifndef XT_INTEXC_HOOKS
#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.
#endif
/*
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.
*/
#if !XCHAL_HAVE_XEA2
#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 .
*******************************************************************************/
/*
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)
#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
/*
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'.
*******************************************************************************/
#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];
#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.
*******************************************************************************/
#include "xtensa_context.h"
#ifdef XT_RTOS_TIMER_INT
#include "xtensa_timer.h"
#endif
/*******************************************************************************
Xtensa Port Version.
*******************************************************************************/
#define XTENSA_PORT_VERSION 1.7
#define XTENSA_PORT_VERSION_STRING "1.7"
#endif /* XTENSA_RTOS_H */

@ -1,164 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2015-2019 Cadence Design Systems, Inc.
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/*
* XTENSA INFORMATION FOR RTOS TICK TIMER AND CLOCK FREQUENCY
*
* This header contains definitions and macros for use primarily by Xtensa
* RTOS assembly coded source files. It includes and uses the Xtensa hardware
* abstraction layer (HAL) to deal with config specifics. It may also be
* included in C source files.
*
* Edit this file to modify timer selection and to specify clock frequency and
* tick duration to match timer interrupt to the real-time tick duration.
*
* If the RTOS has no timer interrupt, then there is no tick timer and the
* clock frequency is irrelevant, so all of these macros are left undefined
* and the Xtensa core configuration need not have a timer.
*/
#ifndef XTENSA_TIMER_H
#define XTENSA_TIMER_H
#ifdef __ASSEMBLER__
#include <xtensa/coreasm.h>
#endif
#include <xtensa/corebits.h>
#include <xtensa/config/system.h>
#include "xtensa_rtos.h" /* in case this wasn't included directly */
#include <FreeRTOSConfig.h>
/*
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."
#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
#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)
#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
#endif
#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=<value>" where <value> is a suitable number.
*/
#ifndef XT_TICK_PER_SEC
#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).
*/
#ifdef XT_CLOCK_FREQ
#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);
#endif
#endif /* XTENSA_TIMER_H */

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save