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-Portspull/1158/head
parent
f5cf45d86e
commit
5f3bab1a32
@ -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…
Reference in New Issue