1 /* 2 * FreeRTOS Kernel V11.1.0 3 * Copyright (C) 2024 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_ASM_H 30 #define PORTMACRO_ASM_H 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 #include "FreeRTOSConfig.h" 37 38 #ifndef configTOTAL_MPU_REGIONS 39 #error "Set configTOTAL_MPU_REGIONS to the humber of MPU regions in FreeRTOSConfig.h" 40 #elif( configTOTAL_MPU_REGIONS == 12 ) 41 #define portMPU_TOTAL_REGIONS ( 12UL ) 42 #elif( configTOTAL_MPU_REGIONS == 16 ) 43 #define portMPU_TOTAL_REGIONS ( 16UL ) 44 #else 45 #error "Set configTOTAL_MPU_REGIONS to the number of MPU regions in FreeRTOSConfig.h" 46 #endif /* configTOTAL_MPU_REGIONS */ 47 48 /* 49 * The application write can disable Floating Point Unit (FPU) support by 50 * setting configENABLE_FPU to 0. Floating point context stored in TCB 51 * comprises of 32 floating point registers (D0-D31) and FPSCR register. 52 * Disabling FPU, therefore, reduces the per-task RAM usage by 53 * ( 32 + 1 ) * 4 = 132 bytes per task. 54 * 55 * BE CAREFUL DISABLING THIS: Certain standard library APIs try to optimize 56 * themselves by using the floating point registers. If the FPU support is 57 * disabled, the use of such APIs may result in memory corruption. 58 */ 59 #ifndef configENABLE_FPU 60 #define configENABLE_FPU 1 61 #endif /* configENABLE_FPU */ 62 63 #define portENABLE_FPU configENABLE_FPU 64 65 /* On the ArmV7-R Architecture the Operating mode of the Processor is set 66 * using the Current Program Status Register (CPSR) Mode bits, [4:0]. The only 67 * unprivileged mode is User Mode. 68 * 69 * Additional information about the Processor Modes can be found here: 70 * https://developer.arm.com/documentation/ddi0406/cb/System-Level-Architecture/The-System-Level-Programmers--Model/ARM-processor-modes-and-ARM-core-registers/ARM-processor-modes?lang=en 71 * 72 */ 73 74 /** 75 * @brief CPSR bits for various processor modes. 76 * 77 * @ingroup Port Privilege 78 */ 79 #define USER_MODE 0x10U 80 #define FIQ_MODE 0x11U 81 #define IRQ_MODE 0x12U 82 #define SVC_MODE 0x13U 83 #define MON_MODE 0x16U 84 #define ABT_MODE 0x17U 85 #define HYP_MODE 0x1AU 86 #define UND_MODE 0x1BU 87 #define SYS_MODE 0x1FU 88 89 /** 90 * @brief Flag used to mark that a FreeRTOS Task is privileged. 91 * 92 * @ingroup Port Privilege 93 */ 94 #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) 95 96 /** 97 * @brief SVC numbers for various scheduler operations. 98 * 99 * @ingroup Scheduler 100 * 101 * @note These value must not be used in mpu_syscall_numbers.h. 102 */ 103 #define portSVC_YIELD 0x0100U 104 #define portSVC_SYSTEM_CALL_EXIT 0x0104U 105 106 /** 107 * @brief Macros required to manipulate MPU. 108 * 109 * Further information about MPU can be found in Arm's documentation 110 * https://developer.arm.com/documentation/ddi0363/g/System-Control/Register-descriptions/c6--MPU-memory-region-programming-registers 111 * 112 */ 113 114 /* MPU sub-region disable settings. This information is encoded in the MPU 115 * Region Size and Enable Register. */ 116 #define portMPU_SUBREGION_0_DISABLE ( 0x1UL << 8UL ) 117 #define portMPU_SUBREGION_1_DISABLE ( 0x1UL << 9UL ) 118 #define portMPU_SUBREGION_2_DISABLE ( 0x1UL << 10UL ) 119 #define portMPU_SUBREGION_3_DISABLE ( 0x1UL << 11UL ) 120 #define portMPU_SUBREGION_4_DISABLE ( 0x1UL << 12UL ) 121 #define portMPU_SUBREGION_5_DISABLE ( 0x1UL << 13UL ) 122 #define portMPU_SUBREGION_6_DISABLE ( 0x1UL << 14UL ) 123 #define portMPU_SUBREGION_7_DISABLE ( 0x1UL << 15UL ) 124 125 /* Default MPU regions. */ 126 #define portFIRST_CONFIGURABLE_REGION ( 0 ) 127 #define portLAST_CONFIGURABLE_REGION ( portMPU_TOTAL_REGIONS - 5UL ) 128 #define portSTACK_REGION ( portMPU_TOTAL_REGIONS - 4UL ) 129 #define portUNPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 3UL ) 130 #define portPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 2UL ) 131 #define portPRIVILEGED_RAM_REGION ( portMPU_TOTAL_REGIONS - 1UL ) 132 #define portNUM_CONFIGURABLE_REGIONS \ 133 ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1UL ) 134 /* Plus one to make space for the stack region. */ 135 #define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1UL ) 136 137 /* MPU region sizes. This information is encoded in the MPU Region Size and 138 * Enable Register. */ 139 #define portMPU_REGION_SIZE_32B ( 0x04UL << 1UL ) 140 #define portMPU_REGION_SIZE_64B ( 0x05UL << 1UL ) 141 #define portMPU_REGION_SIZE_128B ( 0x06UL << 1UL ) 142 #define portMPU_REGION_SIZE_256B ( 0x07UL << 1UL ) 143 #define portMPU_REGION_SIZE_512B ( 0x08UL << 1UL ) 144 #define portMPU_REGION_SIZE_1KB ( 0x09UL << 1UL ) 145 #define portMPU_REGION_SIZE_2KB ( 0x0AUL << 1UL ) 146 #define portMPU_REGION_SIZE_4KB ( 0x0BUL << 1UL ) 147 #define portMPU_REGION_SIZE_8KB ( 0x0CUL << 1UL ) 148 #define portMPU_REGION_SIZE_16KB ( 0x0DUL << 1UL ) 149 #define portMPU_REGION_SIZE_32KB ( 0x0EUL << 1UL ) 150 #define portMPU_REGION_SIZE_64KB ( 0x0FUL << 1UL ) 151 #define portMPU_REGION_SIZE_128KB ( 0x10UL << 1UL ) 152 #define portMPU_REGION_SIZE_256KB ( 0x11UL << 1UL ) 153 #define portMPU_REGION_SIZE_512KB ( 0x12UL << 1UL ) 154 #define portMPU_REGION_SIZE_1MB ( 0x13UL << 1UL ) 155 #define portMPU_REGION_SIZE_2MB ( 0x14UL << 1UL ) 156 #define portMPU_REGION_SIZE_4MB ( 0x15UL << 1UL ) 157 #define portMPU_REGION_SIZE_8MB ( 0x16UL << 1UL ) 158 #define portMPU_REGION_SIZE_16MB ( 0x17UL << 1UL ) 159 #define portMPU_REGION_SIZE_32MB ( 0x18UL << 1UL ) 160 #define portMPU_REGION_SIZE_64MB ( 0x19UL << 1UL ) 161 #define portMPU_REGION_SIZE_128MB ( 0x1AUL << 1UL ) 162 #define portMPU_REGION_SIZE_256MB ( 0x1BUL << 1UL ) 163 #define portMPU_REGION_SIZE_512MB ( 0x1CUL << 1UL ) 164 #define portMPU_REGION_SIZE_1GB ( 0x1DUL << 1UL ) 165 #define portMPU_REGION_SIZE_2GB ( 0x1EUL << 1UL ) 166 #define portMPU_REGION_SIZE_4GB ( 0x1FUL << 1UL ) 167 168 /* MPU memory types. This information is encoded in the TEX, S, C and B bits 169 * of the MPU Region Access Control Register. */ 170 #define portMPU_REGION_STRONGLY_ORDERED_SHAREABLE ( 0x00UL ) /* TEX=000, S=NA, C=0, B=0. */ 171 #define portMPU_REGION_DEVICE_SHAREABLE ( 0x01UL ) /* TEX=000, S=NA, C=0, B=1. */ 172 #define portMPU_REGION_NORMAL_OIWTNOWA_NONSHARED ( 0x02UL ) /* TEX=000, S=0, C=1, B=0. */ 173 #define portMPU_REGION_NORMAL_OIWTNOWA_SHARED ( 0x06UL ) /* TEX=000, S=1, C=1, B=0. */ 174 #define portMPU_REGION_NORMAL_OIWBNOWA_NONSHARED ( 0x03UL ) /* TEX=000, S=0, C=1, B=1. */ 175 #define portMPU_REGION_NORMAL_OIWBNOWA_SHARED ( 0x07UL ) /* TEX=000, S=1, C=1, B=1. */ 176 #define portMPU_REGION_NORMAL_OINC_NONSHARED ( 0x08UL ) /* TEX=001, S=0, C=0, B=0. */ 177 #define portMPU_REGION_NORMAL_OINC_SHARED ( 0x0CUL ) /* TEX=001, S=1, C=0, B=0. */ 178 #define portMPU_REGION_NORMAL_OIWBWA_NONSHARED ( 0x0BUL ) /* TEX=001, S=0, C=1, B=1. */ 179 #define portMPU_REGION_NORMAL_OIWBWA_SHARED ( 0x0FUL ) /* TEX=001, S=1, C=1, B=1. */ 180 #define portMPU_REGION_DEVICE_NONSHAREABLE ( 0x10UL ) /* TEX=010, S=NA, C=0, B=0. */ 181 182 /* MPU access permissions. This information is encoded in the XN and AP bits of 183 * the MPU Region Access Control Register. */ 184 #define portMPU_REGION_AP_BITMASK ( 0x07UL << 8UL ) 185 #define portMPU_REGION_XN_BITMASK ( 0x01UL << 12UL ) 186 187 #define portMPU_REGION_PRIV_NA_USER_NA ( 0x00UL << 8UL ) 188 #define portMPU_REGION_PRIV_NA_USER_NA_EXEC ( portMPU_REGION_PRIV_NA_USER_NA ) /* Priv: X, Unpriv: X. */ 189 #define portMPU_REGION_PRIV_NA_USER_NA_NOEXEC ( portMPU_REGION_PRIV_NA_USER_NA | \ 190 portMPU_REGION_XN_BITMASK ) /* Priv: No Access, Unpriv: No Access. */ 191 192 #define portMPU_REGION_PRIV_RW_USER_NA ( 0x01UL << 8UL ) 193 #define portMPU_REGION_PRIV_RW_USER_NA_EXEC ( portMPU_REGION_PRIV_RW_USER_NA ) /* Priv: RWX, Unpriv: X. */ 194 #define portMPU_REGION_PRIV_RW_USER_NA_NOEXEC ( portMPU_REGION_PRIV_RW_USER_NA | \ 195 portMPU_REGION_XN_BITMASK ) /* Priv: RW, Unpriv: No access. */ 196 197 #define portMPU_REGION_PRIV_RW_USER_RO ( 0x02UL << 8UL ) 198 #define portMPU_REGION_PRIV_RW_USER_RO_EXEC ( portMPU_REGION_PRIV_RW_USER_RO ) /* Priv: RWX, Unpriv: RX. */ 199 #define portMPU_REGION_PRIV_RW_USER_RO_NOEXEC ( portMPU_REGION_PRIV_RW_USER_RO | \ 200 portMPU_REGION_XN_BITMASK ) /* Priv: RW, Unpriv: R. */ 201 202 #define portMPU_REGION_PRIV_RW_USER_RW ( 0x03UL << 8UL ) 203 #define portMPU_REGION_PRIV_RW_USER_RW_EXEC ( portMPU_REGION_PRIV_RW_USER_RW ) /* Priv: RWX, Unpriv: RWX. */ 204 #define portMPU_REGION_PRIV_RW_USER_RW_NOEXEC ( portMPU_REGION_PRIV_RW_USER_RW | \ 205 portMPU_REGION_XN_BITMASK ) /* Priv: RW, Unpriv: RW. */ 206 207 #define portMPU_REGION_PRIV_RO_USER_NA ( 0x05UL << 8UL ) 208 #define portMPU_REGION_PRIV_RO_USER_NA_EXEC ( portMPU_REGION_PRIV_RO_USER_NA ) /* Priv: RX, Unpriv: X. */ 209 #define portMPU_REGION_PRIV_RO_USER_NA_NOEXEC ( portMPU_REGION_PRIV_RO_USER_NA | \ 210 portMPU_REGION_XN_BITMASK ) /* Priv: R, Unpriv: No access. */ 211 212 #define portMPU_REGION_PRIV_RO_USER_RO ( 0x06UL << 8UL ) 213 #define portMPU_REGION_PRIV_RO_USER_RO_EXEC ( portMPU_REGION_PRIV_RO_USER_RO ) /* Priv: RX, Unpriv: RX. */ 214 #define portMPU_REGION_PRIV_RO_USER_RO_NOEXEC ( portMPU_REGION_PRIV_RO_USER_RO | \ 215 portMPU_REGION_XN_BITMASK ) /* Priv: R, Unpriv: R. */ 216 217 /* MPU region management. */ 218 #define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 12UL ) 219 #define portMPU_REGION_ENABLE ( 0x01UL ) 220 221 /** 222 * @brief The size (in words) of a task context. 223 * 224 * An array of this size is allocated in TCB where a task's context is saved 225 * when it is switched out. 226 * 227 * Information about Floating Point Unit (FPU): 228 * https://developer.arm.com/documentation/den0042/a/Floating-Point 229 * 230 * Additional information related to the Cortex R4-F's FPU Implementation: 231 * https://developer.arm.com/documentation/ddi0363/e/fpu-programmer-s-model 232 * 233 * Additional information related to the Cortex R5-F's FPU Implementation: 234 * https://developer.arm.com/documentation/ddi0460/d/FPU-Programmers-Model 235 * 236 * Additional information related to the ArmV7-R CPSR: 237 * https://developer.arm.com/documentation/ddi0406/cb/Application-Level-Architecture/Application-Level-Programmers--Model/The-Application-Program-Status-Register--APSR-?lang=en 238 * 239 * Additional information related to the GPRs: 240 * https://developer.arm.com/documentation/ddi0406/cb/System-Level-Architecture/The-System-Level-Programmers--Model/ARM-processor-modes-and-ARM-core-registers/ARM-core-registers?lang=en 241 * 242 */ 243 244 #if( portENABLE_FPU == 1 ) 245 /* 246 * +-------------------+-------+----------+--------+----------+----------+----------+------+ 247 * | ulCriticalNesting | FPSCR | S0-S31 | R0-R12 | SP (R13) | LR (R14) | PC (R15) | CPSR | 248 * +-------------------+-------+----------+--------+----------+----------+----------+------+ 249 * 250 * <------------------><------><---------><--------><---------><--------><----------><-----> 251 * 1 1 32 13 1 1 1 1 252 */ 253 #define CONTEXT_SIZE 51U 254 #else 255 /* 256 * +-------------------+--------+----------+----------+----------+------+ 257 * | ulCriticalNesting | R0-R12 | SP (R13) | LR (R14) | PC (R15) | CPSR | 258 * +-------------------+--------+----------+----------+----------+------+ 259 * 260 * <------------------><--------><---------><--------><----------><-----> 261 * 1 13 1 1 1 1 262 */ 263 #define CONTEXT_SIZE 18U 264 #endif /* CONTEXT_SIZE */ 265 266 /** 267 * @brief Offset of xSystemCallStackInfo from the start of a TCB. 268 */ 269 #define portSYSTEM_CALL_INFO_OFFSET \ 270 ( ( 1U /* pxTopOfStack. */ + \ 271 ( portTOTAL_NUM_REGIONS_IN_TCB * 3U ) + \ 272 1U /* ulTaskFlags. */ \ 273 ) * 4U ) 274 275 #ifdef __cplusplus 276 } /* extern C */ 277 #endif 278 279 #endif /* PORTMACRO_ASM_H */ 280