xref: /Kernel-v10.6.2/portable/GCC/IA32_flat/portmacro.h (revision ef7b253b56c9788077f5ecd6c9deb4021923d646)
1 /*
2  * FreeRTOS Kernel V10.6.2
3  * Copyright (C) 2021 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * SPDX-License-Identifier: MIT
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy of
8  * this software and associated documentation files (the "Software"), to deal in
9  * the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11  * the Software, and to permit persons to whom the Software is furnished to do so,
12  * subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in all
15  * copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * https://www.FreeRTOS.org
25  * https://github.com/FreeRTOS
26  *
27  */
28 
29 #ifndef PORTMACRO_H
30 #define PORTMACRO_H
31 
32 /* *INDENT-OFF* */
33 #ifdef __cplusplus
34     extern "C" {
35 #endif
36 /* *INDENT-ON* */
37 
38 /*-----------------------------------------------------------
39  * Port specific definitions.
40  *
41  * The settings in this file configure FreeRTOS correctly for the given hardware
42  * and compiler.
43  *
44  * These settings should not be altered.
45  *-----------------------------------------------------------
46  */
47 
48 /* Type definitions. */
49 #define portCHAR        char
50 #define portFLOAT       float
51 #define portDOUBLE      double
52 #define portLONG        long
53 #define portSHORT       short
54 #define portSTACK_TYPE  uint32_t
55 #define portBASE_TYPE   long
56 
57 typedef portSTACK_TYPE StackType_t;
58 typedef long BaseType_t;
59 typedef unsigned long UBaseType_t;
60 
61 typedef uint32_t TickType_t;
62 #define portMAX_DELAY ( ( TickType_t ) 0xffffffffUL )
63 
64 /*-----------------------------------------------------------*/
65 
66 /* Hardware specifics. */
67 #define portSTACK_GROWTH            ( -1 )
68 #define portTICK_PERIOD_MS          ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
69 #define portBYTE_ALIGNMENT          32
70 
71 /*-----------------------------------------------------------*/
72 
73 /* Task utilities. */
74 
75 /* The interrupt priority (for vectors 16 to 255) is determined using vector/16.
76 The quotient is rounded to the nearest integer with 1 being the lowest priority
77 and 15 is the highest.  Therefore the following two interrupts are at the lowest
78 priority.  *NOTE 1* If the yield vector is changed then it must also be changed
79 in the portYIELD_INTERRUPT definition immediately below. */
80 #define portAPIC_TIMER_INT_VECTOR       ( 0x21 )
81 #define portAPIC_YIELD_INT_VECTOR       ( 0x20 )
82 
83 /* Build yield interrupt instruction. */
84 #define portYIELD_INTERRUPT "int $0x20"
85 
86 /* APIC register addresses. */
87 #define portAPIC_EOI                    ( *( ( volatile uint32_t * ) 0xFEE000B0UL ) )
88 
89 /* APIC bit definitions. */
90 #define portAPIC_ENABLE_BIT             ( 1UL << 8UL )
91 #define portAPIC_TIMER_PERIODIC         ( 1UL << 17UL )
92 #define portAPIC_DISABLE                ( 1UL << 16UL )
93 #define portAPIC_NMI                    ( 4 << 8)
94 #define portAPIC_DIV_16                 ( 0x03 )
95 
96 /* Define local API register addresses. */
97 #define portAPIC_ID_REGISTER            ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x20UL  ) ) )
98 #define portAPIC_SPURIOUS_INT           ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xF0UL  ) ) )
99 #define portAPIC_LVT_TIMER              ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x320UL ) ) )
100 #define portAPIC_TIMER_INITIAL_COUNT    ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x380UL ) ) )
101 #define portAPIC_TIMER_CURRENT_COUNT    ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x390UL ) ) )
102 #define portAPIC_TASK_PRIORITY          ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x80UL  ) ) )
103 #define portAPIC_LVT_ERROR              ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x370UL ) ) )
104 #define portAPIC_ERROR_STATUS           ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x280UL ) ) )
105 #define portAPIC_LDR                    ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xD0UL  ) ) )
106 #define portAPIC_TMRDIV                 ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x3E0UL ) ) )
107 #define portAPIC_LVT_PERF               ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x340UL ) ) )
108 #define portAPIC_LVT_LINT0              ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x350UL ) ) )
109 #define portAPIC_LVT_LINT1              ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x360UL ) ) )
110 
111 /* Don't yield if inside a critical section - instead hold the yield pending
112 so it is performed when the critical section is exited. */
113 #define portYIELD()                                 \
114 {                                                   \
115 extern volatile uint32_t ulCriticalNesting;         \
116 extern volatile uint32_t ulPortYieldPending;        \
117     if( ulCriticalNesting != 0 )                    \
118     {                                               \
119         ulPortYieldPending = pdTRUE;                \
120     }                                               \
121     else                                            \
122     {                                               \
123         __asm volatile( portYIELD_INTERRUPT );      \
124     }                                               \
125 }
126 
127 /* Called at the end of an ISR that can cause a context switch - pend a yield if
128 xSwithcRequired is not false. */
129 #define portEND_SWITCHING_ISR( xSwitchRequired )    \
130 {                                                   \
131 extern volatile uint32_t ulPortYieldPending;        \
132     if( xSwitchRequired != pdFALSE )                \
133     {                                               \
134         ulPortYieldPending = 1;                     \
135     }                                               \
136 }
137 
138 /* Same as portEND_SWITCHING_ISR() - take your pick which name to use. */
139 #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
140 
141 /*-----------------------------------------------------------
142  * Critical section control
143  *----------------------------------------------------------*/
144 
145 /* Critical sections for use in interrupts. */
146 #define portSET_INTERRUPT_MASK_FROM_ISR()       ulPortSetInterruptMask()
147 #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x)    vPortClearInterruptMask( x )
148 
149 extern void vPortEnterCritical( void );
150 extern void vPortExitCritical( void );
151 extern uint32_t ulPortSetInterruptMask( void );
152 extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
153 
154 /* These macros do not globally disable/enable interrupts.  They do mask off
155 interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
156 #define portENTER_CRITICAL()        vPortEnterCritical()
157 #define portEXIT_CRITICAL()         vPortExitCritical()
158 #define portDISABLE_INTERRUPTS()    __asm volatile( "cli" )
159 #define portENABLE_INTERRUPTS()     __asm volatile( "sti" )
160 
161 /*-----------------------------------------------------------*/
162 
163 /* Task function macros as described on the FreeRTOS.org WEB site.  These are
164 not required for this port but included in case common demo code that uses these
165 macros is used. */
166 #define portTASK_FUNCTION_PROTO( vFunction, pvParameters )  void vFunction( void *pvParameters )
167 #define portTASK_FUNCTION( vFunction, pvParameters )    void vFunction( void *pvParameters )
168 
169 /* Architecture specific optimisations. */
170 #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
171 
172     /* Store/clear the ready priorities in a bit map. */
173     #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities )    \
174         __asm volatile( "bsr %1, %0\n\t"                                    \
175                         :"=r"(uxTopPriority) : "rm"(uxReadyPriorities) : "cc" )
176 
177     #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
178     #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
179 
180 #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
181 
182 #define portNOP() __asm volatile( "NOP" )
183 
184 /*-----------------------------------------------------------
185  * Misc
186  *----------------------------------------------------------*/
187 
188 #define portNUM_VECTORS     256
189 #define portMAX_PRIORITY    15
190 typedef void ( *ISR_Handler_t ) ( void );
191 
192 /* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
193 before any floating point instructions are executed. */
194 #ifndef configSUPPORT_FPU
195     #define configSUPPORT_FPU 0
196 #endif
197 
198 #if configSUPPORT_FPU == 1
199     void vPortTaskUsesFPU( void );
200     #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
201 #endif
202 
203 /* See the comments under the configUSE_COMMON_INTERRUPT_ENTRY_POINT definition
204 below. */
205 BaseType_t xPortRegisterCInterruptHandler( ISR_Handler_t pxHandler, uint32_t ulVectorNumber );
206 BaseType_t xPortInstallInterruptHandler( ISR_Handler_t pxHandler, uint32_t ulVectorNumber );
207 
208 #ifndef configAPIC_BASE
209     /* configAPIC_BASE_ADDRESS sets the base address of the local APIC.  It can
210     be overridden in FreeRTOSConfig.h should it not be constant. */
211     #define configAPIC_BASE 0xFEE00000UL
212 #endif
213 
214 #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
215     /* The FreeRTOS scheduling algorithm selects the task that will enter the
216     Running state.  configUSE_PORT_OPTIMISED_TASK_SELECTION is used to set how
217     that is done.
218 
219     If configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 0 then the task to
220     enter the Running state is selected using a portable algorithm written in
221     C.  This is the slowest method, but the algorithm does not restrict the
222     maximum number of unique RTOS task priorities that are available.
223 
224     If configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 1 then the task to
225     enter the Running state is selected using a single assembly instruction.
226     This is the fastest method, but restricts the maximum number of unique RTOS
227     task priorities to 32 (the same task priority can be assigned to any number
228     of RTOS tasks). */
229     #warning configUSE_PORT_OPTIMISED_TASK_SELECTION was not defined in FreeRTOSConfig.h and has been defaulted to 1
230     #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
231 #endif
232 
233 #ifndef configUSE_COMMON_INTERRUPT_ENTRY_POINT
234     /* There are two ways of implementing interrupt handlers:
235 
236         1) As standard C functions -
237 
238         This method can only be used if configUSE_COMMON_INTERRUPT_ENTRY_POINT
239         is set to 1.  The C function is installed using
240         xPortRegisterCInterruptHandler().
241 
242         This is the simplest of the two methods but incurs a slightly longer
243         interrupt entry time.
244 
245         2) By using an assembly stub that wraps the handler in the FreeRTOS
246            portFREERTOS_INTERRUPT_ENTRY and portFREERTOS_INTERRUPT_EXIT macros.
247 
248         This method can always be used.  It is slightly more complex than
249         method 1 but benefits from a faster interrupt entry time. */
250     #warning configUSE_COMMON_INTERRUPT_ENTRY_POINT was not defined in FreeRTOSConfig.h and has been defaulted to 1.
251     #define configUSE_COMMON_INTERRUPT_ENTRY_POINT  1
252 #endif
253 
254 #ifndef configISR_STACK_SIZE
255     /* Interrupt entry code will switch the stack in use to a dedicated system
256     stack.
257 
258     configISR_STACK_SIZE defines the number of 32-bit values that can be stored
259     on the system stack, and must be large enough to hold a potentially nested
260     interrupt stack frame. */
261 
262     #error configISR_STACK_SIZE was not defined in FreeRTOSConfig.h.
263 #endif
264 
265 #ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
266     /* Interrupt safe FreeRTOS functions (those that end in "FromISR" must not
267     be called from an interrupt that has a priority above that set by
268     configMAX_API_CALL_INTERRUPT_PRIORITY.  */
269     #warning configMAX_API_CALL_INTERRUPT_PRIORITY was not defined in FreeRTOSConfig.h and has been defaulted to 10
270     #define configMAX_API_CALL_INTERRUPT_PRIORITY 10
271 #endif
272 
273 #ifndef configSUPPORT_FPU
274     #warning configSUPPORT_FPU was not defined in FreeRTOSConfig.h and has been defaulted to 0
275     #define configSUPPORT_FPU 0
276 #endif
277 
278 /* The value written to the task priority register to raise the interrupt mask
279 to the maximum from which FreeRTOS API calls can be made. */
280 #define portAPIC_PRIORITY_SHIFT     ( 4UL )
281 #define portAPIC_MAX_SUB_PRIORITY   ( 0x0fUL )
282 #define portMAX_API_CALL_PRIORITY       ( ( configMAX_API_CALL_INTERRUPT_PRIORITY << portAPIC_PRIORITY_SHIFT ) | portAPIC_MAX_SUB_PRIORITY )
283 
284 /* Asserts if interrupt safe FreeRTOS functions are called from a priority
285 above the max system call interrupt priority. */
286 #define portAPIC_PROCESSOR_PRIORITY ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xA0UL  ) ) )
287 #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( portAPIC_PROCESSOR_PRIORITY ) <= ( portMAX_API_CALL_PRIORITY ) )
288 
289 /* *INDENT-OFF* */
290 #ifdef __cplusplus
291     }
292 #endif
293 /* *INDENT-ON* */
294 
295 #endif /* PORTMACRO_H */
296