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()                        rtos_lock_acquire( 0 )
156         #define portRELEASE_ISR_LOCK()                    rtos_lock_release( 0 )
157         #define portGET_TASK_LOCK()                       rtos_lock_acquire( 1 )
158         #define portRELEASE_TASK_LOCK()                   rtos_lock_release( 1 )
159 
160         void vTaskEnterCritical( void );
161         void vTaskExitCritical( void );
162         #define portENTER_CRITICAL()    vTaskEnterCritical()
163         #define portEXIT_CRITICAL()     vTaskExitCritical()
164 
165         extern UBaseType_t vTaskEnterCriticalFromISR( void );
166         extern void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus );
167         #define portENTER_CRITICAL_FROM_ISR    vTaskEnterCriticalFromISR
168         #define portEXIT_CRITICAL_FROM_ISR     vTaskExitCriticalFromISR
169 
170 /*-----------------------------------------------------------*/
171 
172 /* Runtime stats support */
173         #if ( configGENERATE_RUN_TIME_STATS == 1 )
174             int xscope_gettime( void );
175             #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()    /* nothing needed here */
176             #define portGET_RUN_TIME_COUNTER_VALUE()            xscope_gettime()
177         #endif
178 /*-----------------------------------------------------------*/
179 
180 /* Maps sprintf and snprintf to the lite version in lib_rtos_support */
181         #if ( configUSE_DEBUG_SPRINTF == 1 )
182             #define sprintf( ... )     rtos_sprintf( __VA_ARGS__ )
183             #define snprintf( ... )    rtos_snprintf( __VA_ARGS__ )
184         #endif
185 
186 /* Attribute for the pxCallbackFunction member of the Timer_t struct.
187  * Required by xcc to calculate stack usage. */
188         #define portTIMER_CALLBACK_ATTRIBUTE    __attribute__( ( fptrgroup( "timerCallbackGroup" ) ) )
189 
190 /* Timer callback function macros. For xcc this ensures they get added to the timer callback
191  * group so that stack usage for certain functions in timers.c can be calculated. */
192         #define portTIMER_CALLBACK_FUNCTION_PROTO( vFunction, xTimer )    void vFunction( TimerHandle_t xTimer )
193         #define portTIMER_CALLBACK_FUNCTION( vFunction, xTimer )          portTIMER_CALLBACK_ATTRIBUTE void vFunction( TimerHandle_t xTimer )
194 
195 /*-----------------------------------------------------------*/
196 
197 /* Task function macros as described on the FreeRTOS.org WEB site.  These are
198  * not necessary for to use this port.  They are defined so the common demo files
199  * (which build with all the ports) will build. */
200         #define portTASK_FUNCTION_PROTO( vFunction, pvParameters )    void vFunction( void * pvParameters )
201         #define portTASK_FUNCTION( vFunction, pvParameters )          void vFunction( void * pvParameters )
202 /*-----------------------------------------------------------*/
203 
204 
205         #ifdef __cplusplus
206 }
207         #endif
208 
209     #endif /* __ASSEMBLER__ */
210 
211 #endif /* PORTMACRO_H */
212