1 /*
2  * FreeRTOS Kernel V11.0.1
3  * Copyright (C) 2015-2019 Cadence Design Systems, Inc.
4  * Copyright (C) 2021 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
5  *
6  * SPDX-License-Identifier: MIT
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy of
9  * this software and associated documentation files (the "Software"), to deal in
10  * the Software without restriction, including without limitation the rights to
11  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
12  * the Software, and to permit persons to whom the Software is furnished to do so,
13  * subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in all
16  * copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
20  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
21  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  * https://www.FreeRTOS.org
26  * https://github.com/FreeRTOS
27  *
28  */
29 
30 #ifndef PORTMACRO_H
31 #define PORTMACRO_H
32 
33 /* *INDENT-OFF* */
34 #ifdef __cplusplus
35     extern "C" {
36 #endif
37 /* *INDENT-ON* */
38 
39 #ifndef __ASSEMBLER__
40 
41     #include <stdint.h>
42 
43     #include <xtensa/tie/xt_core.h>
44     #include <xtensa/hal.h>
45     #include <xtensa/config/core.h>
46     #include <xtensa/config/system.h> /* required for XSHAL_CLIB */
47     #include <xtensa/xtruntime.h>
48 
49 /*#include "xtensa_context.h" */
50 
51 /*-----------------------------------------------------------
52  * Port specific definitions.
53  *
54  * The settings in this file configure FreeRTOS correctly for the
55  * given hardware and compiler.
56  *
57  * These settings should not be altered.
58  *-----------------------------------------------------------
59  */
60 
61 /* Type definitions. */
62 
63     #define portCHAR          int8_t
64     #define portFLOAT         float
65     #define portDOUBLE        double
66     #define portLONG          int32_t
67     #define portSHORT         int16_t
68     #define portSTACK_TYPE    uint32_t
69     #define portBASE_TYPE     int
70 
71     typedef portSTACK_TYPE           StackType_t;
72     typedef portBASE_TYPE            BaseType_t;
73     typedef unsigned portBASE_TYPE   UBaseType_t;
74 
75     #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
76         typedef uint16_t             TickType_t;
77         #define portMAX_DELAY    ( TickType_t ) 0xffff
78     #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
79         typedef uint32_t             TickType_t;
80         #define portMAX_DELAY    ( TickType_t ) 0xffffffffUL
81     #else
82         #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
83     #endif
84 /*-----------------------------------------------------------*/
85 
86 /* portbenchmark */
87     #include "portbenchmark.h"
88 
89 /* Critical section management. NW-TODO: replace XTOS_SET_INTLEVEL with more efficient version, if any? */
90 /* These cannot be nested. They should be used with a lot of care and cannot be called from interrupt level. */
91     #define portDISABLE_INTERRUPTS()    do { XTOS_SET_INTLEVEL( XCHAL_EXCM_LEVEL ); portbenchmarkINTERRUPT_DISABLE(); } while( 0 )
92     #define portENABLE_INTERRUPTS()     do { portbenchmarkINTERRUPT_RESTORE( 0 ); XTOS_SET_INTLEVEL( 0 ); } while( 0 )
93 
94 /* These can be nested */
95     #define portCRITICAL_NESTING_IN_TCB    1 /* For now, let FreeRTOS' (tasks.c) manage critical nesting */
96     void vTaskEnterCritical( void );
97     void vTaskExitCritical( void );
98     #define portENTER_CRITICAL()    vTaskEnterCritical()
99     #define portEXIT_CRITICAL()     vTaskExitCritical()
100 
101 /* Cleaner and preferred solution allows nested interrupts disabling and restoring via local registers or stack. */
102 /* They can be called from interrupts too. */
portENTER_CRITICAL_NESTED()103     static inline unsigned portENTER_CRITICAL_NESTED()
104     {
105         unsigned state = XTOS_SET_INTLEVEL( XCHAL_EXCM_LEVEL );
106 
107         portbenchmarkINTERRUPT_DISABLE();
108         return state;
109     }
110     #define portEXIT_CRITICAL_NESTED( state )             do { portbenchmarkINTERRUPT_RESTORE( state ); XTOS_RESTORE_JUST_INTLEVEL( state ); } while( 0 )
111 
112 /* These FreeRTOS versions are similar to the nested versions above */
113     #define portSET_INTERRUPT_MASK_FROM_ISR()             portENTER_CRITICAL_NESTED()
114     #define portCLEAR_INTERRUPT_MASK_FROM_ISR( state )    portEXIT_CRITICAL_NESTED( state )
115 
116 /*-----------------------------------------------------------*/
117 
118 /* Architecture specifics. */
119     #define portSTACK_GROWTH      ( -1 )
120     #define portTICK_PERIOD_MS    ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
121     #define portBYTE_ALIGNMENT    4
122     #define portNOP()    XT_NOP()
123 /*-----------------------------------------------------------*/
124 
125 /* Fine resolution time */
126     #define portGET_RUN_TIME_COUNTER_VALUE()    xthal_get_ccount()
127 
128 /* Kernel utilities. */
129     void vPortYield( void );
130     void _frxt_setup_switch( void );
131     #define portYIELD()    vPortYield()
132     #define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) \
133     if( ( xHigherPriorityTaskWoken ) != 0 ) {              \
134         _frxt_setup_switch();                              \
135     }
136 
137 /*-----------------------------------------------------------*/
138 
139 /* Task function macros as described on the FreeRTOS.org WEB site. */
140     #define portTASK_FUNCTION_PROTO( vFunction, pvParameters )    void vFunction( void * pvParameters )
141     #define portTASK_FUNCTION( vFunction, pvParameters )          void vFunction( void * pvParameters )
142 
143 /* When coprocessors are defined, we to maintain a pointer to coprocessors area. */
144 /* We currently use a hack: redefine field xMPU_SETTINGS in TCB block as a structure that can hold: */
145 /* MPU wrappers, coprocessor area pointer, trace code structure, and more if needed. */
146 /* The field is normally used for memory protection. FreeRTOS should create another general purpose field. */
147     typedef struct
148     {
149         #if XCHAL_CP_NUM > 0
150             volatile StackType_t * coproc_area; /* Pointer to coprocessor save area; MUST BE FIRST */
151         #endif
152 
153         #if portUSING_MPU_WRAPPERS
154             /* Define here mpu_settings, which is port dependent */
155             int mpu_setting; /* Just a dummy example here; MPU not ported to Xtensa yet */
156         #endif
157 
158         #if configUSE_TRACE_FACILITY_2
159             struct
160             {
161                 /* Cf. porttraceStamp() */
162                 int taskstamp;      /* Stamp from inside task to see where we are */
163                 int taskstampcount; /* A counter usually incremented when we restart the task's loop */
164             } porttrace;
165         #endif
166     } xMPU_SETTINGS;
167 
168 /* 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) */
169     #if ( XCHAL_CP_NUM > 0 || configUSE_TRACE_FACILITY_2 ) && !portUSING_MPU_WRAPPERS /* If MPU wrappers not used, we still need to allocate coproc area */
170         #undef portUSING_MPU_WRAPPERS
171         #define portUSING_MPU_WRAPPERS    1                                           /* Enable it to allocate coproc area */
172         #define MPU_WRAPPERS_H                                                        /* Override mpu_wrapper.h to disable unwanted code */
173         #define PRIVILEGED_FUNCTION
174         #define PRIVILEGED_DATA
175     #endif
176 
177 /* porttrace */
178     #if configUSE_TRACE_FACILITY_2
179         #include "porttrace.h"
180     #endif
181 
182 /* configASSERT_2 if requested */
183     #if configASSERT_2
184         #include <stdio.h>
185         void exit( int );
186         #define configASSERT( x )    if( !( x ) ) { porttracePrint( -1 ); printf( "\nAssertion failed in %s:%d\n", __FILE__, __LINE__ ); exit( -1 ); }
187     #endif
188 
189 
190 /* C library support -- only XCLIB and NEWLIB are supported. */
191 
192 /* To enable thread-safe C library support, XT_USE_THREAD_SAFE_CLIB must be
193  * defined to be > 0 somewhere above or on the command line. */
194 
195     #if ( XT_USE_THREAD_SAFE_CLIB > 0u ) && ( XSHAL_CLIB == XTHAL_CLIB_XCLIB )
196         extern void vPortClibInit( void );
197     #endif // XCLIB support
198 
199     #if ( XT_USE_THREAD_SAFE_CLIB > 0u ) && ( XSHAL_CLIB == XTHAL_CLIB_NEWLIB )
200         extern void vPortClibInit( void );
201 
202 /* This C library cleanup is not currently done by FreeRTOS when deleting a task */
203         #include <stdio.h>
204         #define portCLEAN_UP_TCB( pxTCB )    vPortCleanUpTcbClib( &( ( pxTCB )->xNewLib_reent ) )
vPortCleanUpTcbClib(struct _reent * ptr)205         static inline void vPortCleanUpTcbClib( struct _reent * ptr )
206         {
207             FILE * fp = &( ptr->__sf[ 0 ] );
208             int i;
209 
210             for( i = 0; i < 3; ++i, ++fp )
211             {
212                 fp->_close = NULL;
213             }
214         }
215     #endif // NEWLIB support
216 
217 #endif // __ASSEMBLER__
218 
219 /* *INDENT-OFF* */
220 #ifdef __cplusplus
221     }
222 #endif
223 /* *INDENT-ON* */
224 
225 #endif /* PORTMACRO_H */
226