1 /* Copyright (c) 2020, XMOS Ltd, All rights reserved */
2 
3 #ifndef PORTMACRO_H
4     #define PORTMACRO_H
5 
6     #ifndef __ASSEMBLER__
7 
8 /* Inclusion of xc1.h will result in clock being defined as a type.
9  * By default, FreeRTOS will require standard time.h, where clock is a function.
10  */
11         #ifndef USE_XCORE_CLOCK_TYPE
12             #define _clock_defined
13         #endif
14 
15         #include <xs1.h>
16         #include "rtos_support.h"
17 
18         #ifdef __cplusplus
19         extern "C" {
20         #endif
21 
22 /* Type definitions. */
23         #define portSTACK_TYPE    uint32_t
24         typedef portSTACK_TYPE   StackType_t;
25         typedef double           portDOUBLE;
26         typedef int32_t          BaseType_t;
27         typedef uint32_t         UBaseType_t;
28 
29         #define portBASE_TYPE    BaseType_t
30 
31         #if ( configUSE_16_BIT_TICKS == 1 )
32             typedef uint16_t     TickType_t;
33             #define portMAX_DELAY              ( TickType_t ) 0xffff
34         #else
35             typedef uint32_t     TickType_t;
36             #define portMAX_DELAY              ( TickType_t ) 0xffffffffUL
37 
38 /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
39  * not need to be guarded with a critical section. */
40             #define portTICK_TYPE_IS_ATOMIC    1
41         #endif
42 /*-----------------------------------------------------------*/
43 
44     #endif /* __ASSEMBLER__ */
45 
46 /* Architecture specifics. These can be used by assembly files as well. */
47     #define portSTACK_GROWTH               ( -1 )
48     #define portTICK_PERIOD_MS             ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
49     #define portBYTE_ALIGNMENT             8
50     #define portCRITICAL_NESTING_IN_TCB    1
51     #define portMAX_CORE_COUNT             8
52     #ifndef configNUMBER_OF_CORES
53         #define configNUMBER_OF_CORES      1
54     #endif
55 
56 /* This may be set to zero in the config file if the rtos_time
57  *  functions are not needed or if it is incremented elsewhere. */
58     #ifndef configUPDATE_RTOS_TIME_FROM_TICK_ISR
59         #define configUPDATE_RTOS_TIME_FROM_TICK_ISR    1
60     #endif
61 
62 /*
63  * When entering an ISR we need to grow the stack by one more word than
64  * we actually need to save the thread context. This is because there are
65  * some functions, written in assembly *cough* memcpy() *cough*, that think
66  * it is OK to store words at SP[0]. Therefore the ISR must leave SP[0] alone
67  * even though it is normally not necessary to do so.
68  */
69     #define portTHREAD_CONTEXT_STACK_GROWTH    RTOS_SUPPORT_INTERRUPT_STACK_GROWTH
70 
71     #ifndef __ASSEMBLER__
72 
73 /* Check validity of number of cores specified in config */
74         #if ( configNUMBER_OF_CORES < 1 || portMAX_CORE_COUNT < configNUMBER_OF_CORES )
75             #error "Invalid number of cores specified in config!"
76         #endif
77 
78         #define portMEMORY_BARRIER()                  RTOS_MEMORY_BARRIER()
79         #define portTASK_STACK_DEPTH( pxTaskCode )    RTOS_THREAD_STACK_SIZE( pxTaskCode )
80 /*-----------------------------------------------------------*/
81 
82 /* Scheduler utilities. */
83         #define portYIELD()    asm volatile ( "KCALLI_lu6 0" ::: "memory" )
84 
85         #define portEND_SWITCHING_ISR( xSwitchRequired )               \
86     do                                                                 \
87     {                                                                  \
88         if( xSwitchRequired != pdFALSE )                               \
89         {                                                              \
90             extern uint32_t ulPortYieldRequired[ portMAX_CORE_COUNT ]; \
91             ulPortYieldRequired[ portGET_CORE_ID() ] = pdTRUE;         \
92         }                                                              \
93     } while( 0 )
94 
95         #define portYIELD_FROM_ISR( x )    portEND_SWITCHING_ISR( x )
96 /*-----------------------------------------------------------*/
97 
98 /* SMP utilities. */
99         #define portGET_CORE_ID()      rtos_core_id_get()
100 
101         void vPortYieldOtherCore( int xOtherCoreID );
102         #define portYIELD_CORE( x )    vPortYieldOtherCore( x )
103 /*-----------------------------------------------------------*/
104 
105 /* Architecture specific optimisations. */
106         #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
107             #define configUSE_PORT_OPTIMISED_TASK_SELECTION    0
108         #endif
109 
110         #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
111 
112 /* Store/clear the ready priorities in a bit map. */
113             #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities )    ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
114             #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities )     ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
115 
116 /*-----------------------------------------------------------*/
117 
118             #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities )    uxTopPriority = ( 31UL - ( uint32_t ) __builtin_clz( uxReadyPriorities ) )
119 
120         #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
121 /*-----------------------------------------------------------*/
122 
123 /* Critical section management. */
124 
125         #define portGET_INTERRUPT_STATE()                 rtos_interrupt_mask_get()
126 
127 /*
128  * This differs from the standard portDISABLE_INTERRUPTS()
129  * in that it also returns what the interrupt state was
130  * before it disabling interrupts.
131  */
132         #define portDISABLE_INTERRUPTS()                  rtos_interrupt_mask_all()
133 
134         #define portENABLE_INTERRUPTS()                   rtos_interrupt_unmask_all()
135 
136 /*
137  * Port set interrupt mask and clear interrupt mask.
138  */
139         #define portSET_INTERRUPT_MASK()                  rtos_interrupt_mask_all()
140         #define portCLEAR_INTERRUPT_MASK( ulState )       rtos_interrupt_mask_set( ulState )
141 
142 /*
143  * Will enable interrupts if ulState is non-zero.
144  */
145         #define portRESTORE_INTERRUPTS( ulState )         rtos_interrupt_mask_set( ulState )
146 
147 /*
148  * Returns non-zero if currently running in an
149  * ISR or otherwise in kernel mode.
150  */
151         #define portCHECK_IF_IN_ISR()                     rtos_isr_running()
152 
153         #define portASSERT_IF_IN_ISR()                    configASSERT( portCHECK_IF_IN_ISR() == 0 )
154 
155         #define portGET_ISR_LOCK( xCoreID )               do{ ( void )( xCoreID ); rtos_lock_acquire( 0 ); } while( 0 )
156         #define portRELEASE_ISR_LOCK( xCoreID )           do{ ( void )( xCoreID ); rtos_lock_release( 0 ); } while( 0 )
157         #define portGET_TASK_LOCK( xCoreID )              do{ ( void )( xCoreID ); rtos_lock_acquire( 1 ); } while( 0 )
158         #define portRELEASE_TASK_LOCK( xCoreID )          do{ ( void )( xCoreID ); rtos_lock_release( 1 ); } while( 0 )
159 
160 
161         void vTaskEnterCritical( void );
162         void vTaskExitCritical( void );
163         #define portENTER_CRITICAL()    vTaskEnterCritical()
164         #define portEXIT_CRITICAL()     vTaskExitCritical()
165 
166         extern UBaseType_t vTaskEnterCriticalFromISR( void );
167         extern void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus );
168         #define portENTER_CRITICAL_FROM_ISR    vTaskEnterCriticalFromISR
169         #define portEXIT_CRITICAL_FROM_ISR     vTaskExitCriticalFromISR
170 
171 /*-----------------------------------------------------------*/
172 
173 /* Runtime stats support */
174         #if ( configGENERATE_RUN_TIME_STATS == 1 )
175             int xscope_gettime( void );
176             #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()    /* nothing needed here */
177             #define portGET_RUN_TIME_COUNTER_VALUE()            xscope_gettime()
178         #endif
179 /*-----------------------------------------------------------*/
180 
181 /* Maps sprintf and snprintf to the lite version in lib_rtos_support */
182         #if ( configUSE_DEBUG_SPRINTF == 1 )
183             #define sprintf( ... )     rtos_sprintf( __VA_ARGS__ )
184             #define snprintf( ... )    rtos_snprintf( __VA_ARGS__ )
185         #endif
186 
187 /* Attribute for the pxCallbackFunction member of the Timer_t struct.
188  * Required by xcc to calculate stack usage. */
189         #define portTIMER_CALLBACK_ATTRIBUTE    __attribute__( ( fptrgroup( "timerCallbackGroup" ) ) )
190 
191 /* Timer callback function macros. For xcc this ensures they get added to the timer callback
192  * group so that stack usage for certain functions in timers.c can be calculated. */
193         #define portTIMER_CALLBACK_FUNCTION_PROTO( vFunction, xTimer )    void vFunction( TimerHandle_t xTimer )
194         #define portTIMER_CALLBACK_FUNCTION( vFunction, xTimer )          portTIMER_CALLBACK_ATTRIBUTE void vFunction( TimerHandle_t xTimer )
195 
196 /*-----------------------------------------------------------*/
197 
198 /* Task function macros as described on the FreeRTOS.org WEB site.  These are
199  * not necessary for to use this port.  They are defined so the common demo files
200  * (which build with all the ports) will build. */
201         #define portTASK_FUNCTION_PROTO( vFunction, pvParameters )    void vFunction( void * pvParameters )
202         #define portTASK_FUNCTION( vFunction, pvParameters )          void vFunction( void * pvParameters )
203 /*-----------------------------------------------------------*/
204 
205 
206         #ifdef __cplusplus
207 }
208         #endif
209 
210     #endif /* __ASSEMBLER__ */
211 
212 #endif /* PORTMACRO_H */
213