forked
Embed:
(wiki syntax)
Show/hide line numbers
core_ca.h
Go to the documentation of this file.
00001 /**************************************************************************//** 00002 * @file core_ca.h 00003 * @brief CMSIS Cortex-A Core Peripheral Access Layer Header File 00004 * @version V1.00 00005 * @date 22. Feb 2017 00006 ******************************************************************************/ 00007 /* 00008 * Copyright (c) 2009-2017 ARM Limited. All rights reserved. 00009 * 00010 * SPDX-License-Identifier: Apache-2.0 00011 * 00012 * Licensed under the Apache License, Version 2.0 (the License); you may 00013 * not use this file except in compliance with the License. 00014 * You may obtain a copy of the License at 00015 * 00016 * www.apache.org/licenses/LICENSE-2.0 00017 * 00018 * Unless required by applicable law or agreed to in writing, software 00019 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00020 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00021 * See the License for the specific language governing permissions and 00022 * limitations under the License. 00023 */ 00024 00025 #if defined ( __ICCARM__ ) 00026 #pragma system_include /* treat file as system include file for MISRA check */ 00027 #endif 00028 00029 #ifdef __cplusplus 00030 extern "C" { 00031 #endif 00032 00033 #ifndef __CORE_CA_H_GENERIC 00034 #define __CORE_CA_H_GENERIC 00035 00036 00037 /******************************************************************************* 00038 * CMSIS definitions 00039 ******************************************************************************/ 00040 00041 /* CMSIS CA definitions */ 00042 #define __CA_CMSIS_VERSION_MAIN (1U) /*!< \brief [31:16] CMSIS HAL main version */ 00043 #define __CA_CMSIS_VERSION_SUB (0U) /*!< \brief [15:0] CMSIS HAL sub version */ 00044 #define __CA_CMSIS_VERSION ((__CA_CMSIS_VERSION_MAIN << 16U) | \ 00045 __CA_CMSIS_VERSION_SUB ) /*!< \brief CMSIS HAL version number */ 00046 00047 #if defined ( __CC_ARM ) 00048 #if defined __TARGET_FPU_VFP 00049 #if (__FPU_PRESENT == 1) 00050 #define __FPU_USED 1U 00051 #else 00052 #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" 00053 #define __FPU_USED 0U 00054 #endif 00055 #else 00056 #define __FPU_USED 0U 00057 #endif 00058 00059 #elif defined ( __ICCARM__ ) 00060 #if defined __ARMVFP__ 00061 #if (__FPU_PRESENT == 1) 00062 #define __FPU_USED 1U 00063 #else 00064 #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" 00065 #define __FPU_USED 0U 00066 #endif 00067 #else 00068 #define __FPU_USED 0U 00069 #endif 00070 00071 #elif defined ( __TMS470__ ) 00072 #if defined __TI_VFP_SUPPORT__ 00073 #if (__FPU_PRESENT == 1) 00074 #define __FPU_USED 1U 00075 #else 00076 #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" 00077 #define __FPU_USED 0U 00078 #endif 00079 #else 00080 #define __FPU_USED 0U 00081 #endif 00082 00083 #elif defined ( __GNUC__ ) 00084 #if defined (__VFP_FP__) && !defined(__SOFTFP__) 00085 #if (__FPU_PRESENT == 1) 00086 #define __FPU_USED 1U 00087 #else 00088 #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" 00089 #define __FPU_USED 0U 00090 #endif 00091 #else 00092 #define __FPU_USED 0U 00093 #endif 00094 00095 #elif defined ( __TASKING__ ) 00096 #if defined __FPU_VFP__ 00097 #if (__FPU_PRESENT == 1) 00098 #define __FPU_USED 1U 00099 #else 00100 #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" 00101 #define __FPU_USED 0U 00102 #endif 00103 #else 00104 #define __FPU_USED 0U 00105 #endif 00106 #endif 00107 00108 #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ 00109 00110 #ifdef __cplusplus 00111 } 00112 #endif 00113 00114 #endif /* __CORE_CA_H_GENERIC */ 00115 00116 #ifndef __CMSIS_GENERIC 00117 00118 #ifndef __CORE_CA_H_DEPENDANT 00119 #define __CORE_CA_H_DEPENDANT 00120 00121 #ifdef __cplusplus 00122 extern "C" { 00123 #endif 00124 00125 /* check device defines and use defaults */ 00126 #if defined __CHECK_DEVICE_DEFINES 00127 #ifndef __CA_REV 00128 #define __CA_REV 0x0000U 00129 #warning "__CA_REV not defined in device header file; using default!" 00130 #endif 00131 00132 #ifndef __FPU_PRESENT 00133 #define __FPU_PRESENT 0U 00134 #warning "__FPU_PRESENT not defined in device header file; using default!" 00135 #endif 00136 00137 #ifndef __MPU_PRESENT 00138 #define __MPU_PRESENT 0U 00139 #warning "__MPU_PRESENT not defined in device header file; using default!" 00140 #endif 00141 00142 #ifndef __GIC_PRESENT 00143 #define __GIC_PRESENT 1U 00144 #warning "__GIC_PRESENT not defined in device header file; using default!" 00145 #endif 00146 00147 #ifndef __TIM_PRESENT 00148 #define __TIM_PRESENT 1U 00149 #warning "__TIM_PRESENT not defined in device header file; using default!" 00150 #endif 00151 00152 #ifndef __L2C_PRESENT 00153 #define __L2C_PRESENT 0U 00154 #warning "__L2C_PRESENT not defined in device header file; using default!" 00155 #endif 00156 #endif 00157 00158 /* IO definitions (access restrictions to peripheral registers) */ 00159 #ifdef __cplusplus 00160 #define __I volatile /*!< \brief Defines 'read only' permissions */ 00161 #else 00162 #define __I volatile const /*!< \brief Defines 'read only' permissions */ 00163 #endif 00164 #define __O volatile /*!< \brief Defines 'write only' permissions */ 00165 #define __IO volatile /*!< \brief Defines 'read / write' permissions */ 00166 00167 /* following defines should be used for structure members */ 00168 #define __IM volatile const /*!< \brief Defines 'read only' structure member permissions */ 00169 #define __OM volatile /*!< \brief Defines 'write only' structure member permissions */ 00170 #define __IOM volatile /*!< \brief Defines 'read / write' structure member permissions */ 00171 00172 00173 /******************************************************************************* 00174 * Register Abstraction 00175 Core Register contain: 00176 - CPSR 00177 - CP15 Registers 00178 - L2C-310 Cache Controller 00179 - Generic Interrupt Controller Distributor 00180 - Generic Interrupt Controller Interface 00181 ******************************************************************************/ 00182 00183 /* Core Register CPSR */ 00184 typedef union 00185 { 00186 struct 00187 { 00188 uint32_t M:5; /*!< \brief bit: 0.. 4 Mode field */ 00189 uint32_t T:1; /*!< \brief bit: 5 Thumb execution state bit */ 00190 uint32_t F:1; /*!< \brief bit: 6 FIQ mask bit */ 00191 uint32_t I:1; /*!< \brief bit: 7 IRQ mask bit */ 00192 uint32_t A:1; /*!< \brief bit: 8 Asynchronous abort mask bit */ 00193 uint32_t E:1; /*!< \brief bit: 9 Endianness execution state bit */ 00194 uint32_t IT1:6; /*!< \brief bit: 10..15 If-Then execution state bits 2-7 */ 00195 uint32_t GE:4; /*!< \brief bit: 16..19 Greater than or Equal flags */ 00196 uint32_t _reserved0:4; /*!< \brief bit: 20..23 Reserved */ 00197 uint32_t J:1; /*!< \brief bit: 24 Jazelle bit */ 00198 uint32_t IT0:2; /*!< \brief bit: 25..26 If-Then execution state bits 0-1 */ 00199 uint32_t Q:1; /*!< \brief bit: 27 Saturation condition flag */ 00200 uint32_t V:1; /*!< \brief bit: 28 Overflow condition code flag */ 00201 uint32_t C:1; /*!< \brief bit: 29 Carry condition code flag */ 00202 uint32_t Z:1; /*!< \brief bit: 30 Zero condition code flag */ 00203 uint32_t N:1; /*!< \brief bit: 31 Negative condition code flag */ 00204 } b; /*!< \brief Structure used for bit access */ 00205 uint32_t w; /*!< \brief Type used for word access */ 00206 } CPSR_Type; 00207 00208 /* CPSR Register Definitions */ 00209 #define CPSR_N_Pos 31U /*!< \brief CPSR: N Position */ 00210 #define CPSR_N_Msk (1UL << CPSR_N_Pos) /*!< \brief CPSR: N Mask */ 00211 00212 #define CPSR_Z_Pos 30U /*!< \brief CPSR: Z Position */ 00213 #define CPSR_Z_Msk (1UL << CPSR_Z_Pos) /*!< \brief CPSR: Z Mask */ 00214 00215 #define CPSR_C_Pos 29U /*!< \brief CPSR: C Position */ 00216 #define CPSR_C_Msk (1UL << CPSR_C_Pos) /*!< \brief CPSR: C Mask */ 00217 00218 #define CPSR_V_Pos 28U /*!< \brief CPSR: V Position */ 00219 #define CPSR_V_Msk (1UL << CPSR_V_Pos) /*!< \brief CPSR: V Mask */ 00220 00221 #define CPSR_Q_Pos 27U /*!< \brief CPSR: Q Position */ 00222 #define CPSR_Q_Msk (1UL << CPSR_Q_Pos) /*!< \brief CPSR: Q Mask */ 00223 00224 #define CPSR_IT0_Pos 25U /*!< \brief CPSR: IT0 Position */ 00225 #define CPSR_IT0_Msk (3UL << CPSR_IT0_Pos) /*!< \brief CPSR: IT0 Mask */ 00226 00227 #define CPSR_J_Pos 24U /*!< \brief CPSR: J Position */ 00228 #define CPSR_J_Msk (1UL << CPSR_J_Pos) /*!< \brief CPSR: J Mask */ 00229 00230 #define CPSR_GE_Pos 16U /*!< \brief CPSR: GE Position */ 00231 #define CPSR_GE_Msk (0xFUL << CPSR_GE_Pos) /*!< \brief CPSR: GE Mask */ 00232 00233 #define CPSR_IT1_Pos 10U /*!< \brief CPSR: IT1 Position */ 00234 #define CPSR_IT1_Msk (0x3FUL << CPSR_IT1_Pos) /*!< \brief CPSR: IT1 Mask */ 00235 00236 #define CPSR_E_Pos 9U /*!< \brief CPSR: E Position */ 00237 #define CPSR_E_Msk (1UL << CPSR_E_Pos) /*!< \brief CPSR: E Mask */ 00238 00239 #define CPSR_A_Pos 8U /*!< \brief CPSR: A Position */ 00240 #define CPSR_A_Msk (1UL << CPSR_A_Pos) /*!< \brief CPSR: A Mask */ 00241 00242 #define CPSR_I_Pos 7U /*!< \brief CPSR: I Position */ 00243 #define CPSR_I_Msk (1UL << CPSR_I_Pos) /*!< \brief CPSR: I Mask */ 00244 00245 #define CPSR_F_Pos 6U /*!< \brief CPSR: F Position */ 00246 #define CPSR_F_Msk (1UL << CPSR_F_Pos) /*!< \brief CPSR: F Mask */ 00247 00248 #define CPSR_T_Pos 5U /*!< \brief CPSR: T Position */ 00249 #define CPSR_T_Msk (1UL << CPSR_T_Pos) /*!< \brief CPSR: T Mask */ 00250 00251 #define CPSR_M_Pos 0U /*!< \brief CPSR: M Position */ 00252 #define CPSR_M_Msk (0x1FUL << CPSR_M_Pos) /*!< \brief CPSR: M Mask */ 00253 00254 /* CP15 Register SCTLR */ 00255 typedef union 00256 { 00257 struct 00258 { 00259 uint32_t M:1; /*!< \brief bit: 0 MMU enable */ 00260 uint32_t A:1; /*!< \brief bit: 1 Alignment check enable */ 00261 uint32_t C:1; /*!< \brief bit: 2 Cache enable */ 00262 uint32_t _reserved0:2; /*!< \brief bit: 3.. 4 Reserved */ 00263 uint32_t CP15BEN:1; /*!< \brief bit: 5 CP15 barrier enable */ 00264 uint32_t _reserved1:1; /*!< \brief bit: 6 Reserved */ 00265 uint32_t B:1; /*!< \brief bit: 7 Endianness model */ 00266 uint32_t _reserved2:2; /*!< \brief bit: 8.. 9 Reserved */ 00267 uint32_t SW:1; /*!< \brief bit: 10 SWP and SWPB enable */ 00268 uint32_t Z:1; /*!< \brief bit: 11 Branch prediction enable */ 00269 uint32_t I:1; /*!< \brief bit: 12 Instruction cache enable */ 00270 uint32_t V:1; /*!< \brief bit: 13 Vectors bit */ 00271 uint32_t RR:1; /*!< \brief bit: 14 Round Robin select */ 00272 uint32_t _reserved3:2; /*!< \brief bit:15..16 Reserved */ 00273 uint32_t HA:1; /*!< \brief bit: 17 Hardware Access flag enable */ 00274 uint32_t _reserved4:1; /*!< \brief bit: 18 Reserved */ 00275 uint32_t WXN:1; /*!< \brief bit: 19 Write permission implies XN */ 00276 uint32_t UWXN:1; /*!< \brief bit: 20 Unprivileged write permission implies PL1 XN */ 00277 uint32_t FI:1; /*!< \brief bit: 21 Fast interrupts configuration enable */ 00278 uint32_t U:1; /*!< \brief bit: 22 Alignment model */ 00279 uint32_t _reserved5:1; /*!< \brief bit: 23 Reserved */ 00280 uint32_t VE:1; /*!< \brief bit: 24 Interrupt Vectors Enable */ 00281 uint32_t EE:1; /*!< \brief bit: 25 Exception Endianness */ 00282 uint32_t _reserved6:1; /*!< \brief bit: 26 Reserved */ 00283 uint32_t NMFI:1; /*!< \brief bit: 27 Non-maskable FIQ (NMFI) support */ 00284 uint32_t TRE:1; /*!< \brief bit: 28 TEX remap enable. */ 00285 uint32_t AFE:1; /*!< \brief bit: 29 Access flag enable */ 00286 uint32_t TE:1; /*!< \brief bit: 30 Thumb Exception enable */ 00287 uint32_t _reserved7:1; /*!< \brief bit: 31 Reserved */ 00288 } b; /*!< \brief Structure used for bit access */ 00289 uint32_t w; /*!< \brief Type used for word access */ 00290 } SCTLR_Type; 00291 00292 #define SCTLR_TE_Pos 30U /*!< \brief SCTLR: TE Position */ 00293 #define SCTLR_TE_Msk (1UL << SCTLR_TE_Pos) /*!< \brief SCTLR: TE Mask */ 00294 00295 #define SCTLR_AFE_Pos 29U /*!< \brief SCTLR: AFE Position */ 00296 #define SCTLR_AFE_Msk (1UL << SCTLR_AFE_Pos) /*!< \brief SCTLR: AFE Mask */ 00297 00298 #define SCTLR_TRE_Pos 28U /*!< \brief SCTLR: TRE Position */ 00299 #define SCTLR_TRE_Msk (1UL << SCTLR_TRE_Pos) /*!< \brief SCTLR: TRE Mask */ 00300 00301 #define SCTLR_NMFI_Pos 27U /*!< \brief SCTLR: NMFI Position */ 00302 #define SCTLR_NMFI_Msk (1UL << SCTLR_NMFI_Pos) /*!< \brief SCTLR: NMFI Mask */ 00303 00304 #define SCTLR_EE_Pos 25U /*!< \brief SCTLR: EE Position */ 00305 #define SCTLR_EE_Msk (1UL << SCTLR_EE_Pos) /*!< \brief SCTLR: EE Mask */ 00306 00307 #define SCTLR_VE_Pos 24U /*!< \brief SCTLR: VE Position */ 00308 #define SCTLR_VE_Msk (1UL << SCTLR_VE_Pos) /*!< \brief SCTLR: VE Mask */ 00309 00310 #define SCTLR_U_Pos 22U /*!< \brief SCTLR: U Position */ 00311 #define SCTLR_U_Msk (1UL << SCTLR_U_Pos) /*!< \brief SCTLR: U Mask */ 00312 00313 #define SCTLR_FI_Pos 21U /*!< \brief SCTLR: FI Position */ 00314 #define SCTLR_FI_Msk (1UL << SCTLR_FI_Pos) /*!< \brief SCTLR: FI Mask */ 00315 00316 #define SCTLR_UWXN_Pos 20U /*!< \brief SCTLR: UWXN Position */ 00317 #define SCTLR_UWXN_Msk (1UL << SCTLR_UWXN_Pos) /*!< \brief SCTLR: UWXN Mask */ 00318 00319 #define SCTLR_WXN_Pos 19U /*!< \brief SCTLR: WXN Position */ 00320 #define SCTLR_WXN_Msk (1UL << SCTLR_WXN_Pos) /*!< \brief SCTLR: WXN Mask */ 00321 00322 #define SCTLR_HA_Pos 17U /*!< \brief SCTLR: HA Position */ 00323 #define SCTLR_HA_Msk (1UL << SCTLR_HA_Pos) /*!< \brief SCTLR: HA Mask */ 00324 00325 #define SCTLR_RR_Pos 14U /*!< \brief SCTLR: RR Position */ 00326 #define SCTLR_RR_Msk (1UL << SCTLR_RR_Pos) /*!< \brief SCTLR: RR Mask */ 00327 00328 #define SCTLR_V_Pos 13U /*!< \brief SCTLR: V Position */ 00329 #define SCTLR_V_Msk (1UL << SCTLR_V_Pos) /*!< \brief SCTLR: V Mask */ 00330 00331 #define SCTLR_I_Pos 12U /*!< \brief SCTLR: I Position */ 00332 #define SCTLR_I_Msk (1UL << SCTLR_I_Pos) /*!< \brief SCTLR: I Mask */ 00333 00334 #define SCTLR_Z_Pos 11U /*!< \brief SCTLR: Z Position */ 00335 #define SCTLR_Z_Msk (1UL << SCTLR_Z_Pos) /*!< \brief SCTLR: Z Mask */ 00336 00337 #define SCTLR_SW_Pos 10U /*!< \brief SCTLR: SW Position */ 00338 #define SCTLR_SW_Msk (1UL << SCTLR_SW_Pos) /*!< \brief SCTLR: SW Mask */ 00339 00340 #define SCTLR_B_Pos 7U /*!< \brief SCTLR: B Position */ 00341 #define SCTLR_B_Msk (1UL << SCTLR_B_Pos) /*!< \brief SCTLR: B Mask */ 00342 00343 #define SCTLR_CP15BEN_Pos 5U /*!< \brief SCTLR: CP15BEN Position */ 00344 #define SCTLR_CP15BEN_Msk (1UL << SCTLR_CP15BEN_Pos) /*!< \brief SCTLR: CP15BEN Mask */ 00345 00346 #define SCTLR_C_Pos 2U /*!< \brief SCTLR: C Position */ 00347 #define SCTLR_C_Msk (1UL << SCTLR_C_Pos) /*!< \brief SCTLR: C Mask */ 00348 00349 #define SCTLR_A_Pos 1U /*!< \brief SCTLR: A Position */ 00350 #define SCTLR_A_Msk (1UL << SCTLR_A_Pos) /*!< \brief SCTLR: A Mask */ 00351 00352 #define SCTLR_M_Pos 0U /*!< \brief SCTLR: M Position */ 00353 #define SCTLR_M_Msk (1UL << SCTLR_M_Pos) /*!< \brief SCTLR: M Mask */ 00354 00355 /* CP15 Register CPACR */ 00356 typedef union 00357 { 00358 struct 00359 { 00360 uint32_t _reserved0:20; /*!< \brief bit: 0..19 Reserved */ 00361 uint32_t cp10:2; /*!< \brief bit:20..21 Access rights for coprocessor 10 */ 00362 uint32_t cp11:2; /*!< \brief bit:22..23 Access rights for coprocessor 11 */ 00363 uint32_t _reserved1:6; /*!< \brief bit:24..29 Reserved */ 00364 uint32_t D32DIS:1; /*!< \brief bit: 30 Disable use of registers D16-D31 of the VFP register file */ 00365 uint32_t ASEDIS:1; /*!< \brief bit: 31 Disable Advanced SIMD Functionality */ 00366 } b; /*!< \brief Structure used for bit access */ 00367 uint32_t w; /*!< \brief Type used for word access */ 00368 } CPACR_Type; 00369 00370 #define CPACR_ASEDIS_Pos 31U /*!< \brief CPACR: ASEDIS Position */ 00371 #define CPACR_ASEDIS_Msk (1UL << CPACR_ASEDIS_Pos) /*!< \brief CPACR: ASEDIS Mask */ 00372 00373 #define CPACR_D32DIS_Pos 30U /*!< \brief CPACR: D32DIS Position */ 00374 #define CPACR_D32DIS_Msk (1UL << CPACR_D32DIS_Pos) /*!< \brief CPACR: D32DIS Mask */ 00375 00376 #define CPACR_cp11_Pos 22U /*!< \brief CPACR: cp11 Position */ 00377 #define CPACR_cp11_Msk (3UL << CPACR_cp11_Pos) /*!< \brief CPACR: cp11 Mask */ 00378 00379 #define CPACR_cp10_Pos 20U /*!< \brief CPACR: cp10 Position */ 00380 #define CPACR_cp10_Msk (3UL << CPACR_cp10_Pos) /*!< \brief CPACR: cp10 Mask */ 00381 00382 /* CP15 Register DFSR */ 00383 typedef union 00384 { 00385 struct 00386 { 00387 uint32_t FS0:4; /*!< \brief bit: 0.. 3 Fault Status bits bit 0-3 */ 00388 uint32_t Domain:4; /*!< \brief bit: 4.. 7 Fault on which domain */ 00389 uint32_t _reserved0:2; /*!< \brief bit: 8.. 9 Reserved */ 00390 uint32_t FS1:1; /*!< \brief bit: 10 Fault Status bits bit 4 */ 00391 uint32_t WnR:1; /*!< \brief bit: 11 Write not Read bit */ 00392 uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ 00393 uint32_t CM:1; /*!< \brief bit: 13 Cache maintenance fault */ 00394 uint32_t _reserved1:18; /*!< \brief bit:14..31 Reserved */ 00395 } b; /*!< \brief Structure used for bit access */ 00396 uint32_t w; /*!< \brief Type used for word access */ 00397 } DFSR_Type; 00398 00399 #define DFSR_CM_Pos 13U /*!< \brief DFSR: CM Position */ 00400 #define DFSR_CM_Msk (1UL << DFSR_CM_Pos) /*!< \brief DFSR: CM Mask */ 00401 00402 #define DFSR_Ext_Pos 12U /*!< \brief DFSR: Ext Position */ 00403 #define DFSR_Ext_Msk (1UL << DFSR_Ext_Pos) /*!< \brief DFSR: Ext Mask */ 00404 00405 #define DFSR_WnR_Pos 11U /*!< \brief DFSR: WnR Position */ 00406 #define DFSR_WnR_Msk (1UL << DFSR_WnR_Pos) /*!< \brief DFSR: WnR Mask */ 00407 00408 #define DFSR_FS1_Pos 10U /*!< \brief DFSR: FS1 Position */ 00409 #define DFSR_FS1_Msk (1UL << DFSR_FS1_Pos) /*!< \brief DFSR: FS1 Mask */ 00410 00411 #define DFSR_Domain_Pos 4U /*!< \brief DFSR: Domain Position */ 00412 #define DFSR_Domain_Msk (0xFUL << DFSR_Domain_Pos) /*!< \brief DFSR: Domain Mask */ 00413 00414 #define DFSR_FS0_Pos 0U /*!< \brief DFSR: FS0 Position */ 00415 #define DFSR_FS0_Msk (0xFUL << DFSR_FS0_Pos) /*!< \brief DFSR: FS0 Mask */ 00416 00417 /* CP15 Register IFSR */ 00418 typedef union 00419 { 00420 struct 00421 { 00422 uint32_t FS0:4; /*!< \brief bit: 0.. 3 Fault Status bits bit 0-3 */ 00423 uint32_t _reserved0:6; /*!< \brief bit: 4.. 9 Reserved */ 00424 uint32_t FS1:1; /*!< \brief bit: 10 Fault Status bits bit 4 */ 00425 uint32_t _reserved1:1; /*!< \brief bit: 11 Reserved */ 00426 uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ 00427 uint32_t _reserved2:19; /*!< \brief bit:13..31 Reserved */ 00428 } b; /*!< \brief Structure used for bit access */ 00429 uint32_t w; /*!< \brief Type used for word access */ 00430 } IFSR_Type; 00431 00432 #define IFSR_ExT_Pos 12U /*!< \brief IFSR: ExT Position */ 00433 #define IFSR_ExT_Msk (1UL << IFSR_ExT_Pos) /*!< \brief IFSR: ExT Mask */ 00434 00435 #define IFSR_FS1_Pos 10U /*!< \brief IFSR: FS1 Position */ 00436 #define IFSR_FS1_Msk (1UL << IFSR_FS1_Pos) /*!< \brief IFSR: FS1 Mask */ 00437 00438 #define IFSR_FS0_Pos 0U /*!< \brief IFSR: FS0 Position */ 00439 #define IFSR_FS0_Msk (0xFUL << IFSR_FS0_Pos) /*!< \brief IFSR: FS0 Mask */ 00440 00441 /* CP15 Register ISR */ 00442 typedef union 00443 { 00444 struct 00445 { 00446 uint32_t _reserved0:6; /*!< \brief bit: 0.. 5 Reserved */ 00447 uint32_t F:1; /*!< \brief bit: 6 FIQ pending bit */ 00448 uint32_t I:1; /*!< \brief bit: 7 IRQ pending bit */ 00449 uint32_t A:1; /*!< \brief bit: 8 External abort pending bit */ 00450 uint32_t _reserved1:23; /*!< \brief bit:14..31 Reserved */ 00451 } b; /*!< \brief Structure used for bit access */ 00452 uint32_t w; /*!< \brief Type used for word access */ 00453 } ISR_Type; 00454 00455 #define ISR_A_Pos 13U /*!< \brief ISR: A Position */ 00456 #define ISR_A_Msk (1UL << ISR_A_Pos) /*!< \brief ISR: A Mask */ 00457 00458 #define ISR_I_Pos 12U /*!< \brief ISR: I Position */ 00459 #define ISR_I_Msk (1UL << ISR_I_Pos) /*!< \brief ISR: I Mask */ 00460 00461 #define ISR_F_Pos 11U /*!< \brief ISR: F Position */ 00462 #define ISR_F_Msk (1UL << ISR_F_Pos) /*!< \brief ISR: F Mask */ 00463 00464 00465 /** 00466 \brief Union type to access the L2C_310 Cache Controller. 00467 */ 00468 #if (__L2C_PRESENT == 1U) 00469 typedef struct 00470 { 00471 __I uint32_t CACHE_ID; /*!< \brief Offset: 0x0000 Cache ID Register */ 00472 __I uint32_t CACHE_TYPE; /*!< \brief Offset: 0x0004 Cache Type Register */ 00473 uint32_t RESERVED0[0x3e]; 00474 __IO uint32_t CONTROL; /*!< \brief Offset: 0x0100 Control Register */ 00475 __IO uint32_t AUX_CNT; /*!< \brief Offset: 0x0104 Auxiliary Control */ 00476 uint32_t RESERVED1[0x3e]; 00477 __IO uint32_t EVENT_CONTROL; /*!< \brief Offset: 0x0200 Event Counter Control */ 00478 __IO uint32_t EVENT_COUNTER1_CONF; /*!< \brief Offset: 0x0204 Event Counter 1 Configuration */ 00479 __IO uint32_t EVENT_COUNTER0_CONF; /*!< \brief Offset: 0x0208 Event Counter 1 Configuration */ 00480 uint32_t RESERVED2[0x2]; 00481 __IO uint32_t INTERRUPT_MASK; /*!< \brief Offset: 0x0214 Interrupt Mask */ 00482 __I uint32_t MASKED_INT_STATUS; /*!< \brief Offset: 0x0218 Masked Interrupt Status */ 00483 __I uint32_t RAW_INT_STATUS; /*!< \brief Offset: 0x021c Raw Interrupt Status */ 00484 __O uint32_t INTERRUPT_CLEAR; /*!< \brief Offset: 0x0220 Interrupt Clear */ 00485 uint32_t RESERVED3[0x143]; 00486 __IO uint32_t CACHE_SYNC; /*!< \brief Offset: 0x0730 Cache Sync */ 00487 uint32_t RESERVED4[0xf]; 00488 __IO uint32_t INV_LINE_PA; /*!< \brief Offset: 0x0770 Invalidate Line By PA */ 00489 uint32_t RESERVED6[2]; 00490 __IO uint32_t INV_WAY; /*!< \brief Offset: 0x077c Invalidate by Way */ 00491 uint32_t RESERVED5[0xc]; 00492 __IO uint32_t CLEAN_LINE_PA; /*!< \brief Offset: 0x07b0 Clean Line by PA */ 00493 uint32_t RESERVED7[1]; 00494 __IO uint32_t CLEAN_LINE_INDEX_WAY; /*!< \brief Offset: 0x07b8 Clean Line by Index/Way */ 00495 __IO uint32_t CLEAN_WAY; /*!< \brief Offset: 0x07bc Clean by Way */ 00496 uint32_t RESERVED8[0xc]; 00497 __IO uint32_t CLEAN_INV_LINE_PA; /*!< \brief Offset: 0x07f0 Clean and Invalidate Line by PA */ 00498 uint32_t RESERVED9[1]; 00499 __IO uint32_t CLEAN_INV_LINE_INDEX_WAY; /*!< \brief Offset: 0x07f8 Clean and Invalidate Line by Index/Way */ 00500 __IO uint32_t CLEAN_INV_WAY; /*!< \brief Offset: 0x07fc Clean and Invalidate by Way */ 00501 uint32_t RESERVED10[0x40]; 00502 __IO uint32_t DATA_LOCK_0_WAY; /*!< \brief Offset: 0x0900 Data Lockdown 0 by Way */ 00503 __IO uint32_t INST_LOCK_0_WAY; /*!< \brief Offset: 0x0904 Instruction Lockdown 0 by Way */ 00504 __IO uint32_t DATA_LOCK_1_WAY; /*!< \brief Offset: 0x0908 Data Lockdown 1 by Way */ 00505 __IO uint32_t INST_LOCK_1_WAY; /*!< \brief Offset: 0x090c Instruction Lockdown 1 by Way */ 00506 __IO uint32_t DATA_LOCK_2_WAY; /*!< \brief Offset: 0x0910 Data Lockdown 2 by Way */ 00507 __IO uint32_t INST_LOCK_2_WAY; /*!< \brief Offset: 0x0914 Instruction Lockdown 2 by Way */ 00508 __IO uint32_t DATA_LOCK_3_WAY; /*!< \brief Offset: 0x0918 Data Lockdown 3 by Way */ 00509 __IO uint32_t INST_LOCK_3_WAY; /*!< \brief Offset: 0x091c Instruction Lockdown 3 by Way */ 00510 __IO uint32_t DATA_LOCK_4_WAY; /*!< \brief Offset: 0x0920 Data Lockdown 4 by Way */ 00511 __IO uint32_t INST_LOCK_4_WAY; /*!< \brief Offset: 0x0924 Instruction Lockdown 4 by Way */ 00512 __IO uint32_t DATA_LOCK_5_WAY; /*!< \brief Offset: 0x0928 Data Lockdown 5 by Way */ 00513 __IO uint32_t INST_LOCK_5_WAY; /*!< \brief Offset: 0x092c Instruction Lockdown 5 by Way */ 00514 __IO uint32_t DATA_LOCK_6_WAY; /*!< \brief Offset: 0x0930 Data Lockdown 5 by Way */ 00515 __IO uint32_t INST_LOCK_6_WAY; /*!< \brief Offset: 0x0934 Instruction Lockdown 5 by Way */ 00516 __IO uint32_t DATA_LOCK_7_WAY; /*!< \brief Offset: 0x0938 Data Lockdown 6 by Way */ 00517 __IO uint32_t INST_LOCK_7_WAY; /*!< \brief Offset: 0x093c Instruction Lockdown 6 by Way */ 00518 uint32_t RESERVED11[0x4]; 00519 __IO uint32_t LOCK_LINE_EN; /*!< \brief Offset: 0x0950 Lockdown by Line Enable */ 00520 __IO uint32_t UNLOCK_ALL_BY_WAY; /*!< \brief Offset: 0x0954 Unlock All Lines by Way */ 00521 uint32_t RESERVED12[0xaa]; 00522 __IO uint32_t ADDRESS_FILTER_START; /*!< \brief Offset: 0x0c00 Address Filtering Start */ 00523 __IO uint32_t ADDRESS_FILTER_END; /*!< \brief Offset: 0x0c04 Address Filtering End */ 00524 uint32_t RESERVED13[0xce]; 00525 __IO uint32_t DEBUG_CONTROL; /*!< \brief Offset: 0x0f40 Debug Control Register */ 00526 } L2C_310_TypeDef; 00527 00528 #define L2C_310 ((L2C_310_TypeDef *)L2C_310_BASE) /*!< \brief L2C_310 Declaration */ 00529 #endif 00530 00531 #if (__GIC_PRESENT == 1U) 00532 /** \brief Structure type to access the Generic Interrupt Controller Distributor (GICD) 00533 */ 00534 typedef struct 00535 { 00536 __IO uint32_t ICDDCR; 00537 __I uint32_t ICDICTR; 00538 __I uint32_t ICDIIDR; 00539 uint32_t RESERVED0[29]; 00540 __IO uint32_t ICDISR[32]; 00541 __IO uint32_t ICDISER[32]; 00542 __IO uint32_t ICDICER[32]; 00543 __IO uint32_t ICDISPR[32]; 00544 __IO uint32_t ICDICPR[32]; 00545 __I uint32_t ICDABR[32]; 00546 uint32_t RESERVED1[32]; 00547 __IO uint32_t ICDIPR[256]; 00548 __IO uint32_t ICDIPTR[256]; 00549 __IO uint32_t ICDICFR[64]; 00550 uint32_t RESERVED2[128]; 00551 __IO uint32_t ICDSGIR; 00552 } GICDistributor_Type; 00553 00554 #define GICDistributor ((GICDistributor_Type *) GIC_DISTRIBUTOR_BASE ) /*!< GIC Distributor configuration struct */ 00555 00556 /** \brief Structure type to access the Generic Interrupt Controller Interface (GICC) 00557 */ 00558 typedef struct 00559 { 00560 __IO uint32_t ICCICR; //!< \brief +0x000 - RW - CPU Interface Control Register 00561 __IO uint32_t ICCPMR; //!< \brief +0x004 - RW - Interrupt Priority Mask Register 00562 __IO uint32_t ICCBPR; //!< \brief +0x008 - RW - Binary Point Register 00563 __I uint32_t ICCIAR; //!< \brief +0x00C - RO - Interrupt Acknowledge Register 00564 __IO uint32_t ICCEOIR; //!< \brief +0x010 - WO - End of Interrupt Register 00565 __I uint32_t ICCRPR; //!< \brief +0x014 - RO - Running Priority Register 00566 __I uint32_t ICCHPIR; //!< \brief +0x018 - RO - Highest Pending Interrupt Register 00567 __IO uint32_t ICCABPR; //!< \brief +0x01C - RW - Aliased Binary Point Register 00568 uint32_t RESERVED[55]; 00569 __I uint32_t ICCIIDR; //!< \brief +0x0FC - RO - CPU Interface Identification Register 00570 } GICInterface_Type; 00571 00572 #define GICInterface ((GICInterface_Type *) GIC_INTERFACE_BASE ) /*!< GIC Interface configuration struct */ 00573 #endif 00574 00575 #if (__TIM_PRESENT == 1U) 00576 #if ((__CORTEX_A == 5U)||(__CORTEX_A == 9U)) 00577 /** \brief Structure type to access the Private Timer 00578 */ 00579 typedef struct 00580 { 00581 __IO uint32_t LOAD; //!< \brief +0x000 - RW - Private Timer Load Register 00582 __IO uint32_t COUNTER; //!< \brief +0x004 - RW - Private Timer Counter Register 00583 __IO uint32_t CONTROL; //!< \brief +0x008 - RW - Private Timer Control Register 00584 __IO uint32_t ISR; //!< \brief +0x00C - RO - Private Timer Interrupt Status Register 00585 uint32_t RESERVED[8]; 00586 __IO uint32_t WLOAD; //!< \brief +0x020 - RW - Watchdog Load Register 00587 __IO uint32_t WCOUNTER; //!< \brief +0x024 - RW - Watchdog Counter Register 00588 __IO uint32_t WCONTROL; //!< \brief +0x028 - RW - Watchdog Control Register 00589 __IO uint32_t WISR; //!< \brief +0x02C - RW - Watchdog Interrupt Status Register 00590 __IO uint32_t WRESET; //!< \brief +0x030 - RW - Watchdog Reset Status Register 00591 __I uint32_t WDISABLE; //!< \brief +0x0FC - RO - Watchdog Disable Register 00592 } Timer_Type; 00593 #define PTIM ((Timer_Type *) TIMER_BASE ) /*!< \brief Timer configuration struct */ 00594 #endif 00595 #endif 00596 00597 /******************************************************************************* 00598 * Hardware Abstraction Layer 00599 Core Function Interface contains: 00600 - L1 Cache Functions 00601 - L2C-310 Cache Controller Functions 00602 - PL1 Timer Functions 00603 - GIC Functions 00604 - MMU Functions 00605 ******************************************************************************/ 00606 00607 /* ########################## L1 Cache functions ################################# */ 00608 00609 /** \brief Enable Caches 00610 00611 Enable Caches 00612 */ 00613 __STATIC_INLINE void L1C_EnableCaches(void) { 00614 // Set I bit 12 to enable I Cache 00615 // Set C bit 2 to enable D Cache 00616 __set_SCTLR( __get_SCTLR() | (1 << 12) | (1 << 2)); 00617 } 00618 00619 /** \brief Disable Caches 00620 00621 Disable Caches 00622 */ 00623 __STATIC_INLINE void L1C_DisableCaches(void) { 00624 // Clear I bit 12 to disable I Cache 00625 // Clear C bit 2 to disable D Cache 00626 __set_SCTLR( __get_SCTLR() & ~(1 << 12) & ~(1 << 2)); 00627 __ISB(); 00628 } 00629 00630 /** \brief Enable BTAC 00631 00632 Enable BTAC 00633 */ 00634 __STATIC_INLINE void L1C_EnableBTAC(void) { 00635 // Set Z bit 11 to enable branch prediction 00636 __set_SCTLR( __get_SCTLR() | (1 << 11)); 00637 __ISB(); 00638 } 00639 00640 /** \brief Disable BTAC 00641 00642 Disable BTAC 00643 */ 00644 __STATIC_INLINE void L1C_DisableBTAC(void) { 00645 // Clear Z bit 11 to disable branch prediction 00646 __set_SCTLR( __get_SCTLR() & ~(1 << 11)); 00647 } 00648 00649 /** \brief Invalidate entire branch predictor array 00650 00651 BPIALL. Branch Predictor Invalidate All. 00652 */ 00653 00654 __STATIC_INLINE void L1C_InvalidateBTAC(void) { 00655 __set_BPIALL(0); 00656 __DSB(); //ensure completion of the invalidation 00657 __ISB(); //ensure instruction fetch path sees new state 00658 } 00659 00660 /** \brief Invalidate the whole I$ 00661 00662 ICIALLU. Instruction Cache Invalidate All to PoU 00663 */ 00664 __STATIC_INLINE void L1C_InvalidateICacheAll(void) { 00665 __set_ICIALLU(0); 00666 __DSB(); //ensure completion of the invalidation 00667 __ISB(); //ensure instruction fetch path sees new I cache state 00668 } 00669 00670 /** \brief Clean D$ by MVA 00671 00672 DCCMVAC. Data cache clean by MVA to PoC 00673 */ 00674 __STATIC_INLINE void L1C_CleanDCacheMVA(void *va) { 00675 __set_DCCMVAC((uint32_t)va); 00676 __DMB(); //ensure the ordering of data cache maintenance operations and their effects 00677 } 00678 00679 /** \brief Invalidate D$ by MVA 00680 00681 DCIMVAC. Data cache invalidate by MVA to PoC 00682 */ 00683 __STATIC_INLINE void L1C_InvalidateDCacheMVA(void *va) { 00684 __set_DCIMVAC((uint32_t)va); 00685 __DMB(); //ensure the ordering of data cache maintenance operations and their effects 00686 } 00687 00688 /** \brief Clean and Invalidate D$ by MVA 00689 00690 DCCIMVAC. Data cache clean and invalidate by MVA to PoC 00691 */ 00692 __STATIC_INLINE void L1C_CleanInvalidateDCacheMVA(void *va) { 00693 __set_DCCIMVAC((uint32_t)va); 00694 __DMB(); //ensure the ordering of data cache maintenance operations and their effects 00695 } 00696 00697 /** \brief Clean and Invalidate the entire data or unified cache 00698 00699 Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency. 00700 */ 00701 __STATIC_INLINE void L1C_CleanInvalidateCache(uint32_t op) { 00702 __L1C_CleanInvalidateCache(op); // compiler specific call 00703 } 00704 00705 00706 /** \brief Invalidate the whole D$ 00707 00708 DCISW. Invalidate by Set/Way 00709 */ 00710 00711 __STATIC_INLINE void L1C_InvalidateDCacheAll(void) { 00712 L1C_CleanInvalidateCache(0); 00713 } 00714 00715 /** \brief Clean the whole D$ 00716 00717 DCCSW. Clean by Set/Way 00718 */ 00719 00720 __STATIC_INLINE void L1C_CleanDCacheAll(void) { 00721 L1C_CleanInvalidateCache(1); 00722 } 00723 00724 /** \brief Clean and invalidate the whole D$ 00725 00726 DCCISW. Clean and Invalidate by Set/Way 00727 */ 00728 00729 __STATIC_INLINE void L1C_CleanInvalidateDCacheAll(void) { 00730 L1C_CleanInvalidateCache(2); 00731 } 00732 00733 00734 /* ########################## L2 Cache functions ################################# */ 00735 #if (__L2C_PRESENT == 1U) 00736 //Cache Sync operation 00737 __STATIC_INLINE void L2C_Sync(void) 00738 { 00739 L2C_310->CACHE_SYNC = 0x0; 00740 } 00741 00742 //return Cache controller cache ID 00743 __STATIC_INLINE int L2C_GetID (void) 00744 { 00745 return L2C_310->CACHE_ID; 00746 } 00747 00748 //return Cache controller cache Type 00749 __STATIC_INLINE int L2C_GetType (void) 00750 { 00751 return L2C_310->CACHE_TYPE; 00752 } 00753 00754 //Invalidate all cache by way 00755 __STATIC_INLINE void L2C_InvAllByWay (void) 00756 { 00757 unsigned int assoc; 00758 00759 if (L2C_310->AUX_CNT & (1<<16)) 00760 assoc = 16; 00761 else 00762 assoc = 8; 00763 00764 L2C_310->INV_WAY = (1 << assoc) - 1; 00765 while(L2C_310->INV_WAY & ((1 << assoc) - 1)); //poll invalidate 00766 00767 L2C_Sync(); 00768 } 00769 00770 //Clean and Invalidate all cache by way 00771 __STATIC_INLINE void L2C_CleanInvAllByWay (void) 00772 { 00773 unsigned int assoc; 00774 00775 if (L2C_310->AUX_CNT & (1<<16)) 00776 assoc = 16; 00777 else 00778 assoc = 8; 00779 00780 L2C_310->CLEAN_INV_WAY = (1 << assoc) - 1; 00781 while(L2C_310->CLEAN_INV_WAY & ((1 << assoc) - 1)); //poll invalidate 00782 00783 L2C_Sync(); 00784 } 00785 00786 //Enable Cache 00787 __STATIC_INLINE void L2C_Enable(void) 00788 { 00789 L2C_310->CONTROL = 0; 00790 L2C_310->INTERRUPT_CLEAR = 0x000001FFuL; 00791 L2C_310->DEBUG_CONTROL = 0; 00792 L2C_310->DATA_LOCK_0_WAY = 0; 00793 L2C_310->CACHE_SYNC = 0; 00794 L2C_310->CONTROL = 0x01; 00795 L2C_Sync(); 00796 } 00797 //Disable Cache 00798 __STATIC_INLINE void L2C_Disable(void) 00799 { 00800 L2C_310->CONTROL = 0x00; 00801 L2C_Sync(); 00802 } 00803 00804 //Invalidate cache by physical address 00805 __STATIC_INLINE void L2C_InvPa (void *pa) 00806 { 00807 L2C_310->INV_LINE_PA = (unsigned int)pa; 00808 L2C_Sync(); 00809 } 00810 00811 //Clean cache by physical address 00812 __STATIC_INLINE void L2C_CleanPa (void *pa) 00813 { 00814 L2C_310->CLEAN_LINE_PA = (unsigned int)pa; 00815 L2C_Sync(); 00816 } 00817 00818 //Clean and invalidate cache by physical address 00819 __STATIC_INLINE void L2C_CleanInvPa (void *pa) 00820 { 00821 L2C_310->CLEAN_INV_LINE_PA = (unsigned int)pa; 00822 L2C_Sync(); 00823 } 00824 #endif 00825 00826 /* ########################## GIC functions ###################################### */ 00827 #if (__GIC_PRESENT == 1U) 00828 00829 __STATIC_INLINE void GIC_EnableDistributor(void) 00830 { 00831 GICDistributor->ICDDCR |= 1; //enable distributor 00832 } 00833 00834 __STATIC_INLINE void GIC_DisableDistributor(void) 00835 { 00836 GICDistributor->ICDDCR &=~1; //disable distributor 00837 } 00838 00839 __STATIC_INLINE uint32_t GIC_DistributorInfo(void) 00840 { 00841 return (uint32_t)(GICDistributor->ICDICTR); 00842 } 00843 00844 __STATIC_INLINE uint32_t GIC_DistributorImplementer(void) 00845 { 00846 return (uint32_t)(GICDistributor->ICDIIDR); 00847 } 00848 00849 __STATIC_INLINE void GIC_SetTarget(IRQn_Type IRQn, uint32_t cpu_target) 00850 { 00851 char* field = (char*)&(GICDistributor->ICDIPTR[IRQn / 4]); 00852 field += IRQn % 4; 00853 *field = (char)cpu_target & 0xf; 00854 } 00855 00856 __STATIC_INLINE void GIC_SetICDICFR (const uint32_t *ICDICFRn) 00857 { 00858 uint32_t i, num_irq; 00859 00860 //Get the maximum number of interrupts that the GIC supports 00861 num_irq = 32 * ((GIC_DistributorInfo() & 0x1f) + 1); 00862 00863 for (i = 0; i < (num_irq/16); i++) 00864 { 00865 GICDistributor->ICDISPR[i] = *ICDICFRn++; 00866 } 00867 } 00868 00869 __STATIC_INLINE uint32_t GIC_GetTarget(IRQn_Type IRQn) 00870 { 00871 char* field = (char*)&(GICDistributor->ICDIPTR[IRQn / 4]); 00872 field += IRQn % 4; 00873 return ((uint32_t)*field & 0xf); 00874 } 00875 00876 __STATIC_INLINE void GIC_EnableInterface(void) 00877 { 00878 GICInterface->ICCICR |= 1; //enable interface 00879 } 00880 00881 __STATIC_INLINE void GIC_DisableInterface(void) 00882 { 00883 GICInterface->ICCICR &=~1; //disable distributor 00884 } 00885 00886 __STATIC_INLINE IRQn_Type GIC_AcknowledgePending(void) 00887 { 00888 return (IRQn_Type)(GICInterface->ICCIAR); 00889 } 00890 00891 __STATIC_INLINE void GIC_EndInterrupt(IRQn_Type IRQn) 00892 { 00893 GICInterface->ICCEOIR = IRQn; 00894 } 00895 00896 __STATIC_INLINE void GIC_EnableIRQ(IRQn_Type IRQn) 00897 { 00898 GICDistributor->ICDISER[IRQn / 32] = 1 << (IRQn % 32); 00899 } 00900 00901 __STATIC_INLINE void GIC_DisableIRQ(IRQn_Type IRQn) 00902 { 00903 GICDistributor->ICDICER[IRQn / 32] = 1 << (IRQn % 32); 00904 } 00905 00906 __STATIC_INLINE void GIC_SetPendingIRQ(IRQn_Type IRQn) 00907 { 00908 GICDistributor->ICDISPR[IRQn / 32] = 1 << (IRQn % 32); 00909 } 00910 00911 __STATIC_INLINE void GIC_ClearPendingIRQ(IRQn_Type IRQn) 00912 { 00913 GICDistributor->ICDICPR[IRQn / 32] = 1 << (IRQn % 32); 00914 } 00915 00916 __STATIC_INLINE void GIC_SetLevelModel(IRQn_Type IRQn, int8_t edge_level, int8_t model) 00917 { 00918 // Word-size read/writes must be used to access this register 00919 volatile uint32_t * field = &(GICDistributor->ICDICFR[IRQn / 16]); 00920 unsigned bit_shift = (IRQn % 16)<<1; 00921 unsigned int save_word; 00922 00923 save_word = *field; 00924 save_word &= (~(3 << bit_shift)); 00925 00926 *field = (save_word | (((edge_level<<1) | model) << bit_shift)); 00927 } 00928 00929 __STATIC_INLINE void GIC_SetPriority(IRQn_Type IRQn, uint32_t priority) 00930 { 00931 char* field = (char*)&(GICDistributor->ICDIPR[IRQn / 4]); 00932 field += IRQn % 4; 00933 *field = (char)priority; 00934 } 00935 00936 __STATIC_INLINE uint32_t GIC_GetPriority(IRQn_Type IRQn) 00937 { 00938 char* field = (char*)&(GICDistributor->ICDIPR[IRQn / 4]); 00939 field += IRQn % 4; 00940 return (uint32_t)*field; 00941 } 00942 00943 __STATIC_INLINE void GIC_InterfacePriorityMask(uint32_t priority) 00944 { 00945 GICInterface->ICCPMR = priority & 0xff; //set priority mask 00946 } 00947 00948 __STATIC_INLINE void GIC_SetBinaryPoint(uint32_t binary_point) 00949 { 00950 GICInterface->ICCBPR = binary_point & 0x07; //set binary point 00951 } 00952 00953 __STATIC_INLINE uint32_t GIC_GetBinaryPoint(uint32_t binary_point) 00954 { 00955 return (uint32_t)GICInterface->ICCBPR; 00956 } 00957 00958 __STATIC_INLINE uint32_t GIC_GetIRQStatus(IRQn_Type IRQn) 00959 { 00960 uint32_t pending, active; 00961 00962 active = ((GICDistributor->ICDABR[IRQn / 32]) >> (IRQn % 32)) & 0x1; 00963 pending =((GICDistributor->ICDISPR[IRQn / 32]) >> (IRQn % 32)) & 0x1; 00964 00965 return ((active<<1) | pending); 00966 } 00967 00968 __STATIC_INLINE void GIC_SendSGI(IRQn_Type IRQn, uint32_t target_list, uint32_t filter_list) 00969 { 00970 GICDistributor->ICDSGIR = ((filter_list & 0x3) << 24) | ((target_list & 0xff) << 16) | (IRQn & 0xf); 00971 } 00972 00973 __STATIC_INLINE void GIC_DistInit(void) 00974 { 00975 IRQn_Type i; 00976 uint32_t num_irq = 0; 00977 uint32_t priority_field; 00978 00979 //A reset sets all bits in the ICDISRs corresponding to the SPIs to 0, 00980 //configuring all of the interrupts as Secure. 00981 00982 //Disable interrupt forwarding 00983 GIC_DisableDistributor(); 00984 //Get the maximum number of interrupts that the GIC supports 00985 num_irq = 32 * ((GIC_DistributorInfo() & 0x1f) + 1); 00986 00987 /* Priority level is implementation defined. 00988 To determine the number of priority bits implemented write 0xFF to an ICDIPR 00989 priority field and read back the value stored.*/ 00990 GIC_SetPriority((IRQn_Type)0, 0xff); 00991 priority_field = GIC_GetPriority((IRQn_Type)0); 00992 00993 for (i = (IRQn_Type)32; i < num_irq; i++) 00994 { 00995 //Disable the SPI interrupt 00996 GIC_DisableIRQ(i); 00997 //Set level-sensitive and 1-N model 00998 GIC_SetLevelModel(i, 0, 1); 00999 //Set priority 01000 GIC_SetPriority(i, priority_field/2); 01001 //Set target list to CPU0 01002 GIC_SetTarget(i, 1); 01003 } 01004 //Enable distributor 01005 GIC_EnableDistributor(); 01006 } 01007 01008 __STATIC_INLINE void GIC_CPUInterfaceInit(void) 01009 { 01010 IRQn_Type i; 01011 uint32_t priority_field; 01012 01013 //A reset sets all bits in the ICDISRs corresponding to the SPIs to 0, 01014 //configuring all of the interrupts as Secure. 01015 01016 //Disable interrupt forwarding 01017 GIC_DisableInterface(); 01018 01019 /* Priority level is implementation defined. 01020 To determine the number of priority bits implemented write 0xFF to an ICDIPR 01021 priority field and read back the value stored.*/ 01022 GIC_SetPriority((IRQn_Type)0, 0xff); 01023 priority_field = GIC_GetPriority((IRQn_Type)0); 01024 01025 //SGI and PPI 01026 for (i = (IRQn_Type)0; i < 32; i++) 01027 { 01028 //Set level-sensitive and 1-N model for PPI 01029 if(i > 15) 01030 GIC_SetLevelModel(i, 0, 1); 01031 //Disable SGI and PPI interrupts 01032 GIC_DisableIRQ(i); 01033 //Set priority 01034 GIC_SetPriority(i, priority_field/2); 01035 } 01036 //Enable interface 01037 GIC_EnableInterface(); 01038 //Set binary point to 0 01039 GIC_SetBinaryPoint(0); 01040 //Set priority mask 01041 GIC_InterfacePriorityMask(0xff); 01042 } 01043 01044 __STATIC_INLINE void GIC_Enable(void) 01045 { 01046 GIC_DistInit(); 01047 GIC_CPUInterfaceInit(); //per CPU 01048 } 01049 #endif 01050 01051 /* ########################## Generic Timer functions ############################ */ 01052 #if (__TIM_PRESENT == 1U) 01053 01054 /* PL1 Physical Timer */ 01055 #if (__CORTEX_A == 7U) 01056 __STATIC_INLINE void PL1_SetLoadValue(uint32_t value) { 01057 __set_CNTP_TVAL(value); 01058 __ISB(); 01059 } 01060 01061 __STATIC_INLINE uint32_t PL1_GetCurrentValue() { 01062 return(__get_CNTP_TVAL()); 01063 } 01064 01065 __STATIC_INLINE void PL1_SetControl(uint32_t value) { 01066 __set_CNTP_CTL(value); 01067 __ISB(); 01068 } 01069 01070 /* Private Timer */ 01071 #elif ((__CORTEX_A == 5U)||(__CORTEX_A == 9U)) 01072 __STATIC_INLINE void PTIM_SetLoadValue(uint32_t value) { 01073 PTIM->LOAD = value; 01074 } 01075 01076 __STATIC_INLINE uint32_t PTIM_GetLoadValue() { 01077 return(PTIM->LOAD); 01078 } 01079 01080 __STATIC_INLINE uint32_t PTIM_GetCurrentValue() { 01081 return(PTIM->COUNTER); 01082 } 01083 01084 __STATIC_INLINE void PTIM_SetControl(uint32_t value) { 01085 PTIM->CONTROL = value; 01086 } 01087 01088 __STATIC_INLINE uint32_t PTIM_GetControl(void) { 01089 return(PTIM->CONTROL); 01090 } 01091 01092 __STATIC_INLINE void PTIM_ClearEventFlag(void) { 01093 PTIM->ISR = 1; 01094 } 01095 #endif 01096 #endif 01097 01098 /* ########################## MMU functions ###################################### */ 01099 01100 #define SECTION_DESCRIPTOR (0x2) 01101 #define SECTION_MASK (0xFFFFFFFC) 01102 01103 #define SECTION_TEXCB_MASK (0xFFFF8FF3) 01104 #define SECTION_B_SHIFT (2) 01105 #define SECTION_C_SHIFT (3) 01106 #define SECTION_TEX0_SHIFT (12) 01107 #define SECTION_TEX1_SHIFT (13) 01108 #define SECTION_TEX2_SHIFT (14) 01109 01110 #define SECTION_XN_MASK (0xFFFFFFEF) 01111 #define SECTION_XN_SHIFT (4) 01112 01113 #define SECTION_DOMAIN_MASK (0xFFFFFE1F) 01114 #define SECTION_DOMAIN_SHIFT (5) 01115 01116 #define SECTION_P_MASK (0xFFFFFDFF) 01117 #define SECTION_P_SHIFT (9) 01118 01119 #define SECTION_AP_MASK (0xFFFF73FF) 01120 #define SECTION_AP_SHIFT (10) 01121 #define SECTION_AP2_SHIFT (15) 01122 01123 #define SECTION_S_MASK (0xFFFEFFFF) 01124 #define SECTION_S_SHIFT (16) 01125 01126 #define SECTION_NG_MASK (0xFFFDFFFF) 01127 #define SECTION_NG_SHIFT (17) 01128 01129 #define SECTION_NS_MASK (0xFFF7FFFF) 01130 #define SECTION_NS_SHIFT (19) 01131 01132 #define PAGE_L1_DESCRIPTOR (0x1) 01133 #define PAGE_L1_MASK (0xFFFFFFFC) 01134 01135 #define PAGE_L2_4K_DESC (0x2) 01136 #define PAGE_L2_4K_MASK (0xFFFFFFFD) 01137 01138 #define PAGE_L2_64K_DESC (0x1) 01139 #define PAGE_L2_64K_MASK (0xFFFFFFFC) 01140 01141 #define PAGE_4K_TEXCB_MASK (0xFFFFFE33) 01142 #define PAGE_4K_B_SHIFT (2) 01143 #define PAGE_4K_C_SHIFT (3) 01144 #define PAGE_4K_TEX0_SHIFT (6) 01145 #define PAGE_4K_TEX1_SHIFT (7) 01146 #define PAGE_4K_TEX2_SHIFT (8) 01147 01148 #define PAGE_64K_TEXCB_MASK (0xFFFF8FF3) 01149 #define PAGE_64K_B_SHIFT (2) 01150 #define PAGE_64K_C_SHIFT (3) 01151 #define PAGE_64K_TEX0_SHIFT (12) 01152 #define PAGE_64K_TEX1_SHIFT (13) 01153 #define PAGE_64K_TEX2_SHIFT (14) 01154 01155 #define PAGE_TEXCB_MASK (0xFFFF8FF3) 01156 #define PAGE_B_SHIFT (2) 01157 #define PAGE_C_SHIFT (3) 01158 #define PAGE_TEX_SHIFT (12) 01159 01160 #define PAGE_XN_4K_MASK (0xFFFFFFFE) 01161 #define PAGE_XN_4K_SHIFT (0) 01162 #define PAGE_XN_64K_MASK (0xFFFF7FFF) 01163 #define PAGE_XN_64K_SHIFT (15) 01164 01165 #define PAGE_DOMAIN_MASK (0xFFFFFE1F) 01166 #define PAGE_DOMAIN_SHIFT (5) 01167 01168 #define PAGE_P_MASK (0xFFFFFDFF) 01169 #define PAGE_P_SHIFT (9) 01170 01171 #define PAGE_AP_MASK (0xFFFFFDCF) 01172 #define PAGE_AP_SHIFT (4) 01173 #define PAGE_AP2_SHIFT (9) 01174 01175 #define PAGE_S_MASK (0xFFFFFBFF) 01176 #define PAGE_S_SHIFT (10) 01177 01178 #define PAGE_NG_MASK (0xFFFFF7FF) 01179 #define PAGE_NG_SHIFT (11) 01180 01181 #define PAGE_NS_MASK (0xFFFFFFF7) 01182 #define PAGE_NS_SHIFT (3) 01183 01184 #define OFFSET_1M (0x00100000) 01185 #define OFFSET_64K (0x00010000) 01186 #define OFFSET_4K (0x00001000) 01187 01188 #define DESCRIPTOR_FAULT (0x00000000) 01189 01190 /* Attributes enumerations */ 01191 01192 /* Region size attributes */ 01193 typedef enum 01194 { 01195 SECTION, 01196 PAGE_4k, 01197 PAGE_64k, 01198 } mmu_region_size_Type; 01199 01200 /* Region type attributes */ 01201 typedef enum 01202 { 01203 NORMAL, 01204 DEVICE, 01205 SHARED_DEVICE, 01206 NON_SHARED_DEVICE, 01207 STRONGLY_ORDERED 01208 } mmu_memory_Type; 01209 01210 /* Region cacheability attributes */ 01211 typedef enum 01212 { 01213 NON_CACHEABLE, 01214 WB_WA, 01215 WT, 01216 WB_NO_WA, 01217 } mmu_cacheability_Type; 01218 01219 /* Region parity check attributes */ 01220 typedef enum 01221 { 01222 ECC_DISABLED, 01223 ECC_ENABLED, 01224 } mmu_ecc_check_Type; 01225 01226 /* Region execution attributes */ 01227 typedef enum 01228 { 01229 EXECUTE, 01230 NON_EXECUTE, 01231 } mmu_execute_Type; 01232 01233 /* Region global attributes */ 01234 typedef enum 01235 { 01236 GLOBAL, 01237 NON_GLOBAL, 01238 } mmu_global_Type; 01239 01240 /* Region shareability attributes */ 01241 typedef enum 01242 { 01243 NON_SHARED, 01244 SHARED, 01245 } mmu_shared_Type; 01246 01247 /* Region security attributes */ 01248 typedef enum 01249 { 01250 SECURE, 01251 NON_SECURE, 01252 } mmu_secure_Type; 01253 01254 /* Region access attributes */ 01255 typedef enum 01256 { 01257 NO_ACCESS, 01258 RW, 01259 READ, 01260 } mmu_access_Type; 01261 01262 /* Memory Region definition */ 01263 typedef struct RegionStruct { 01264 mmu_region_size_Type rg_t; 01265 mmu_memory_Type mem_t; 01266 uint8_t domain; 01267 mmu_cacheability_Type inner_norm_t; 01268 mmu_cacheability_Type outer_norm_t; 01269 mmu_ecc_check_Type e_t; 01270 mmu_execute_Type xn_t; 01271 mmu_global_Type g_t; 01272 mmu_secure_Type sec_t; 01273 mmu_access_Type priv_t; 01274 mmu_access_Type user_t; 01275 mmu_shared_Type sh_t; 01276 01277 } mmu_region_attributes_Type; 01278 01279 //Following macros define the descriptors and attributes 01280 //Sect_Normal. Outer & inner wb/wa, non-shareable, executable, rw, domain 0 01281 #define section_normal(descriptor_l1, region) region.rg_t = SECTION; \ 01282 region.domain = 0x0; \ 01283 region.e_t = ECC_DISABLED; \ 01284 region.g_t = GLOBAL; \ 01285 region.inner_norm_t = WB_WA; \ 01286 region.outer_norm_t = WB_WA; \ 01287 region.mem_t = NORMAL; \ 01288 region.sec_t = SECURE; \ 01289 region.xn_t = EXECUTE; \ 01290 region.priv_t = RW; \ 01291 region.user_t = RW; \ 01292 region.sh_t = NON_SHARED; \ 01293 MMU_GetSectionDescriptor(&descriptor_l1, region); 01294 01295 //Sect_Normal_Cod. Outer & inner wb/wa, non-shareable, executable, ro, domain 0 01296 #define section_normal_cod(descriptor_l1, region) region.rg_t = SECTION; \ 01297 region.domain = 0x0; \ 01298 region.e_t = ECC_DISABLED; \ 01299 region.g_t = GLOBAL; \ 01300 region.inner_norm_t = WB_WA; \ 01301 region.outer_norm_t = WB_WA; \ 01302 region.mem_t = NORMAL; \ 01303 region.sec_t = SECURE; \ 01304 region.xn_t = EXECUTE; \ 01305 region.priv_t = READ; \ 01306 region.user_t = READ; \ 01307 region.sh_t = NON_SHARED; \ 01308 MMU_GetSectionDescriptor(&descriptor_l1, region); 01309 01310 //Sect_Normal_RO. Sect_Normal_Cod, but not executable 01311 #define section_normal_ro(descriptor_l1, region) region.rg_t = SECTION; \ 01312 region.domain = 0x0; \ 01313 region.e_t = ECC_DISABLED; \ 01314 region.g_t = GLOBAL; \ 01315 region.inner_norm_t = WB_WA; \ 01316 region.outer_norm_t = WB_WA; \ 01317 region.mem_t = NORMAL; \ 01318 region.sec_t = SECURE; \ 01319 region.xn_t = NON_EXECUTE; \ 01320 region.priv_t = READ; \ 01321 region.user_t = READ; \ 01322 region.sh_t = NON_SHARED; \ 01323 MMU_GetSectionDescriptor(&descriptor_l1, region); 01324 01325 //Sect_Normal_RW. Sect_Normal_Cod, but writeable and not executable 01326 #define section_normal_rw(descriptor_l1, region) region.rg_t = SECTION; \ 01327 region.domain = 0x0; \ 01328 region.e_t = ECC_DISABLED; \ 01329 region.g_t = GLOBAL; \ 01330 region.inner_norm_t = WB_WA; \ 01331 region.outer_norm_t = WB_WA; \ 01332 region.mem_t = NORMAL; \ 01333 region.sec_t = SECURE; \ 01334 region.xn_t = NON_EXECUTE; \ 01335 region.priv_t = RW; \ 01336 region.user_t = RW; \ 01337 region.sh_t = NON_SHARED; \ 01338 MMU_GetSectionDescriptor(&descriptor_l1, region); 01339 //Sect_SO. Strongly-ordered (therefore shareable), not executable, rw, domain 0, base addr 0 01340 #define section_so(descriptor_l1, region) region.rg_t = SECTION; \ 01341 region.domain = 0x0; \ 01342 region.e_t = ECC_DISABLED; \ 01343 region.g_t = GLOBAL; \ 01344 region.inner_norm_t = NON_CACHEABLE; \ 01345 region.outer_norm_t = NON_CACHEABLE; \ 01346 region.mem_t = STRONGLY_ORDERED; \ 01347 region.sec_t = SECURE; \ 01348 region.xn_t = NON_EXECUTE; \ 01349 region.priv_t = RW; \ 01350 region.user_t = RW; \ 01351 region.sh_t = NON_SHARED; \ 01352 MMU_GetSectionDescriptor(&descriptor_l1, region); 01353 01354 //Sect_Device_RO. Device, non-shareable, non-executable, ro, domain 0, base addr 0 01355 #define section_device_ro(descriptor_l1, region) region.rg_t = SECTION; \ 01356 region.domain = 0x0; \ 01357 region.e_t = ECC_DISABLED; \ 01358 region.g_t = GLOBAL; \ 01359 region.inner_norm_t = NON_CACHEABLE; \ 01360 region.outer_norm_t = NON_CACHEABLE; \ 01361 region.mem_t = STRONGLY_ORDERED; \ 01362 region.sec_t = SECURE; \ 01363 region.xn_t = NON_EXECUTE; \ 01364 region.priv_t = READ; \ 01365 region.user_t = READ; \ 01366 region.sh_t = NON_SHARED; \ 01367 MMU_GetSectionDescriptor(&descriptor_l1, region); 01368 01369 //Sect_Device_RW. Sect_Device_RO, but writeable 01370 #define section_device_rw(descriptor_l1, region) region.rg_t = SECTION; \ 01371 region.domain = 0x0; \ 01372 region.e_t = ECC_DISABLED; \ 01373 region.g_t = GLOBAL; \ 01374 region.inner_norm_t = NON_CACHEABLE; \ 01375 region.outer_norm_t = NON_CACHEABLE; \ 01376 region.mem_t = STRONGLY_ORDERED; \ 01377 region.sec_t = SECURE; \ 01378 region.xn_t = NON_EXECUTE; \ 01379 region.priv_t = RW; \ 01380 region.user_t = RW; \ 01381 region.sh_t = NON_SHARED; \ 01382 MMU_GetSectionDescriptor(&descriptor_l1, region); 01383 //Page_4k_Device_RW. Shared device, not executable, rw, domain 0 01384 #define page4k_device_rw(descriptor_l1, descriptor_l2, region) region.rg_t = PAGE_4k; \ 01385 region.domain = 0x0; \ 01386 region.e_t = ECC_DISABLED; \ 01387 region.g_t = GLOBAL; \ 01388 region.inner_norm_t = NON_CACHEABLE; \ 01389 region.outer_norm_t = NON_CACHEABLE; \ 01390 region.mem_t = SHARED_DEVICE; \ 01391 region.sec_t = SECURE; \ 01392 region.xn_t = NON_EXECUTE; \ 01393 region.priv_t = RW; \ 01394 region.user_t = RW; \ 01395 region.sh_t = NON_SHARED; \ 01396 MMU_GetPageDescriptor(&descriptor_l1, &descriptor_l2, region); 01397 01398 //Page_64k_Device_RW. Shared device, not executable, rw, domain 0 01399 #define page64k_device_rw(descriptor_l1, descriptor_l2, region) region.rg_t = PAGE_64k; \ 01400 region.domain = 0x0; \ 01401 region.e_t = ECC_DISABLED; \ 01402 region.g_t = GLOBAL; \ 01403 region.inner_norm_t = NON_CACHEABLE; \ 01404 region.outer_norm_t = NON_CACHEABLE; \ 01405 region.mem_t = SHARED_DEVICE; \ 01406 region.sec_t = SECURE; \ 01407 region.xn_t = NON_EXECUTE; \ 01408 region.priv_t = RW; \ 01409 region.user_t = RW; \ 01410 region.sh_t = NON_SHARED; \ 01411 MMU_GetPageDescriptor(&descriptor_l1, &descriptor_l2, region); 01412 01413 /** \brief Set section execution-never attribute 01414 01415 \param [out] descriptor_l1 L1 descriptor. 01416 \param [in] xn Section execution-never attribute : EXECUTE , NON_EXECUTE. 01417 01418 \return 0 01419 */ 01420 __STATIC_INLINE int MMU_XNSection(uint32_t *descriptor_l1, mmu_execute_Type xn) 01421 { 01422 *descriptor_l1 &= SECTION_XN_MASK; 01423 *descriptor_l1 |= ((xn & 0x1) << SECTION_XN_SHIFT); 01424 return 0; 01425 } 01426 01427 /** \brief Set section domain 01428 01429 \param [out] descriptor_l1 L1 descriptor. 01430 \param [in] domain Section domain 01431 01432 \return 0 01433 */ 01434 __STATIC_INLINE int MMU_DomainSection(uint32_t *descriptor_l1, uint8_t domain) 01435 { 01436 *descriptor_l1 &= SECTION_DOMAIN_MASK; 01437 *descriptor_l1 |= ((domain & 0xF) << SECTION_DOMAIN_SHIFT); 01438 return 0; 01439 } 01440 01441 /** \brief Set section parity check 01442 01443 \param [out] descriptor_l1 L1 descriptor. 01444 \param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED 01445 01446 \return 0 01447 */ 01448 __STATIC_INLINE int MMU_PSection(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit) 01449 { 01450 *descriptor_l1 &= SECTION_P_MASK; 01451 *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT); 01452 return 0; 01453 } 01454 01455 /** \brief Set section access privileges 01456 01457 \param [out] descriptor_l1 L1 descriptor. 01458 \param [in] user User Level Access: NO_ACCESS, RW, READ 01459 \param [in] priv Privilege Level Access: NO_ACCESS, RW, READ 01460 \param [in] afe Access flag enable 01461 01462 \return 0 01463 */ 01464 __STATIC_INLINE int MMU_APSection(uint32_t *descriptor_l1, mmu_access_Type user, mmu_access_Type priv, uint32_t afe) 01465 { 01466 uint32_t ap = 0; 01467 01468 if (afe == 0) { //full access 01469 if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; } 01470 else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } 01471 else if ((priv == RW) && (user == READ)) { ap = 0x2; } 01472 else if ((priv == RW) && (user == RW)) { ap = 0x3; } 01473 else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } 01474 else if ((priv == READ) && (user == READ)) { ap = 0x7; } 01475 } 01476 01477 else { //Simplified access 01478 if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } 01479 else if ((priv == RW) && (user == RW)) { ap = 0x3; } 01480 else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } 01481 else if ((priv == READ) && (user == READ)) { ap = 0x7; } 01482 } 01483 01484 *descriptor_l1 &= SECTION_AP_MASK; 01485 *descriptor_l1 |= (ap & 0x3) << SECTION_AP_SHIFT; 01486 *descriptor_l1 |= ((ap & 0x4)>>2) << SECTION_AP2_SHIFT; 01487 01488 return 0; 01489 } 01490 01491 /** \brief Set section shareability 01492 01493 \param [out] descriptor_l1 L1 descriptor. 01494 \param [in] s_bit Section shareability: NON_SHARED, SHARED 01495 01496 \return 0 01497 */ 01498 __STATIC_INLINE int MMU_SharedSection(uint32_t *descriptor_l1, mmu_shared_Type s_bit) 01499 { 01500 *descriptor_l1 &= SECTION_S_MASK; 01501 *descriptor_l1 |= ((s_bit & 0x1) << SECTION_S_SHIFT); 01502 return 0; 01503 } 01504 01505 /** \brief Set section Global attribute 01506 01507 \param [out] descriptor_l1 L1 descriptor. 01508 \param [in] g_bit Section attribute: GLOBAL, NON_GLOBAL 01509 01510 \return 0 01511 */ 01512 __STATIC_INLINE int MMU_GlobalSection(uint32_t *descriptor_l1, mmu_global_Type g_bit) 01513 { 01514 *descriptor_l1 &= SECTION_NG_MASK; 01515 *descriptor_l1 |= ((g_bit & 0x1) << SECTION_NG_SHIFT); 01516 return 0; 01517 } 01518 01519 /** \brief Set section Security attribute 01520 01521 \param [out] descriptor_l1 L1 descriptor. 01522 \param [in] s_bit Section Security attribute: SECURE, NON_SECURE 01523 01524 \return 0 01525 */ 01526 __STATIC_INLINE int MMU_SecureSection(uint32_t *descriptor_l1, mmu_secure_Type s_bit) 01527 { 01528 *descriptor_l1 &= SECTION_NS_MASK; 01529 *descriptor_l1 |= ((s_bit & 0x1) << SECTION_NS_SHIFT); 01530 return 0; 01531 } 01532 01533 /* Page 4k or 64k */ 01534 /** \brief Set 4k/64k page execution-never attribute 01535 01536 \param [out] descriptor_l2 L2 descriptor. 01537 \param [in] xn Page execution-never attribute : EXECUTE , NON_EXECUTE. 01538 \param [in] page Page size: PAGE_4k, PAGE_64k, 01539 01540 \return 0 01541 */ 01542 __STATIC_INLINE int MMU_XNPage(uint32_t *descriptor_l2, mmu_execute_Type xn, mmu_region_size_Type page) 01543 { 01544 if (page == PAGE_4k) 01545 { 01546 *descriptor_l2 &= PAGE_XN_4K_MASK; 01547 *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_4K_SHIFT); 01548 } 01549 else 01550 { 01551 *descriptor_l2 &= PAGE_XN_64K_MASK; 01552 *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_64K_SHIFT); 01553 } 01554 return 0; 01555 } 01556 01557 /** \brief Set 4k/64k page domain 01558 01559 \param [out] descriptor_l1 L1 descriptor. 01560 \param [in] domain Page domain 01561 01562 \return 0 01563 */ 01564 __STATIC_INLINE int MMU_DomainPage(uint32_t *descriptor_l1, uint8_t domain) 01565 { 01566 *descriptor_l1 &= PAGE_DOMAIN_MASK; 01567 *descriptor_l1 |= ((domain & 0xf) << PAGE_DOMAIN_SHIFT); 01568 return 0; 01569 } 01570 01571 /** \brief Set 4k/64k page parity check 01572 01573 \param [out] descriptor_l1 L1 descriptor. 01574 \param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED 01575 01576 \return 0 01577 */ 01578 __STATIC_INLINE int MMU_PPage(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit) 01579 { 01580 *descriptor_l1 &= SECTION_P_MASK; 01581 *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT); 01582 return 0; 01583 } 01584 01585 /** \brief Set 4k/64k page access privileges 01586 01587 \param [out] descriptor_l2 L2 descriptor. 01588 \param [in] user User Level Access: NO_ACCESS, RW, READ 01589 \param [in] priv Privilege Level Access: NO_ACCESS, RW, READ 01590 \param [in] afe Access flag enable 01591 01592 \return 0 01593 */ 01594 __STATIC_INLINE int MMU_APPage(uint32_t *descriptor_l2, mmu_access_Type user, mmu_access_Type priv, uint32_t afe) 01595 { 01596 uint32_t ap = 0; 01597 01598 if (afe == 0) { //full access 01599 if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; } 01600 else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } 01601 else if ((priv == RW) && (user == READ)) { ap = 0x2; } 01602 else if ((priv == RW) && (user == RW)) { ap = 0x3; } 01603 else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } 01604 else if ((priv == READ) && (user == READ)) { ap = 0x6; } 01605 } 01606 01607 else { //Simplified access 01608 if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } 01609 else if ((priv == RW) && (user == RW)) { ap = 0x3; } 01610 else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } 01611 else if ((priv == READ) && (user == READ)) { ap = 0x7; } 01612 } 01613 01614 *descriptor_l2 &= PAGE_AP_MASK; 01615 *descriptor_l2 |= (ap & 0x3) << PAGE_AP_SHIFT; 01616 *descriptor_l2 |= ((ap & 0x4)>>2) << PAGE_AP2_SHIFT; 01617 01618 return 0; 01619 } 01620 01621 /** \brief Set 4k/64k page shareability 01622 01623 \param [out] descriptor_l2 L2 descriptor. 01624 \param [in] s_bit 4k/64k page shareability: NON_SHARED, SHARED 01625 01626 \return 0 01627 */ 01628 __STATIC_INLINE int MMU_SharedPage(uint32_t *descriptor_l2, mmu_shared_Type s_bit) 01629 { 01630 *descriptor_l2 &= PAGE_S_MASK; 01631 *descriptor_l2 |= ((s_bit & 0x1) << PAGE_S_SHIFT); 01632 return 0; 01633 } 01634 01635 /** \brief Set 4k/64k page Global attribute 01636 01637 \param [out] descriptor_l2 L2 descriptor. 01638 \param [in] g_bit 4k/64k page attribute: GLOBAL, NON_GLOBAL 01639 01640 \return 0 01641 */ 01642 __STATIC_INLINE int MMU_GlobalPage(uint32_t *descriptor_l2, mmu_global_Type g_bit) 01643 { 01644 *descriptor_l2 &= PAGE_NG_MASK; 01645 *descriptor_l2 |= ((g_bit & 0x1) << PAGE_NG_SHIFT); 01646 return 0; 01647 } 01648 01649 /** \brief Set 4k/64k page Security attribute 01650 01651 \param [out] descriptor_l1 L1 descriptor. 01652 \param [in] s_bit 4k/64k page Security attribute: SECURE, NON_SECURE 01653 01654 \return 0 01655 */ 01656 __STATIC_INLINE int MMU_SecurePage(uint32_t *descriptor_l1, mmu_secure_Type s_bit) 01657 { 01658 *descriptor_l1 &= PAGE_NS_MASK; 01659 *descriptor_l1 |= ((s_bit & 0x1) << PAGE_NS_SHIFT); 01660 return 0; 01661 } 01662 01663 /** \brief Set Section memory attributes 01664 01665 \param [out] descriptor_l1 L1 descriptor. 01666 \param [in] mem Section memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED 01667 \param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, 01668 \param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, 01669 01670 \return 0 01671 */ 01672 __STATIC_INLINE int MMU_MemorySection(uint32_t *descriptor_l1, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner) 01673 { 01674 *descriptor_l1 &= SECTION_TEXCB_MASK; 01675 01676 if (STRONGLY_ORDERED == mem) 01677 { 01678 return 0; 01679 } 01680 else if (SHARED_DEVICE == mem) 01681 { 01682 *descriptor_l1 |= (1 << SECTION_B_SHIFT); 01683 } 01684 else if (NON_SHARED_DEVICE == mem) 01685 { 01686 *descriptor_l1 |= (1 << SECTION_TEX1_SHIFT); 01687 } 01688 else if (NORMAL == mem) 01689 { 01690 *descriptor_l1 |= 1 << SECTION_TEX2_SHIFT; 01691 switch(inner) 01692 { 01693 case NON_CACHEABLE: 01694 break; 01695 case WB_WA: 01696 *descriptor_l1 |= (1 << SECTION_B_SHIFT); 01697 break; 01698 case WT: 01699 *descriptor_l1 |= 1 << SECTION_C_SHIFT; 01700 break; 01701 case WB_NO_WA: 01702 *descriptor_l1 |= (1 << SECTION_B_SHIFT) | (1 << SECTION_C_SHIFT); 01703 break; 01704 } 01705 switch(outer) 01706 { 01707 case NON_CACHEABLE: 01708 break; 01709 case WB_WA: 01710 *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT); 01711 break; 01712 case WT: 01713 *descriptor_l1 |= 1 << SECTION_TEX1_SHIFT; 01714 break; 01715 case WB_NO_WA: 01716 *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT) | (1 << SECTION_TEX0_SHIFT); 01717 break; 01718 } 01719 } 01720 return 0; 01721 } 01722 01723 /** \brief Set 4k/64k page memory attributes 01724 01725 \param [out] descriptor_l2 L2 descriptor. 01726 \param [in] mem 4k/64k page memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED 01727 \param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, 01728 \param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, 01729 \param [in] page Page size 01730 01731 \return 0 01732 */ 01733 __STATIC_INLINE int MMU_MemoryPage(uint32_t *descriptor_l2, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner, mmu_region_size_Type page) 01734 { 01735 *descriptor_l2 &= PAGE_4K_TEXCB_MASK; 01736 01737 if (page == PAGE_64k) 01738 { 01739 //same as section 01740 MMU_MemorySection(descriptor_l2, mem, outer, inner); 01741 } 01742 else 01743 { 01744 if (STRONGLY_ORDERED == mem) 01745 { 01746 return 0; 01747 } 01748 else if (SHARED_DEVICE == mem) 01749 { 01750 *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT); 01751 } 01752 else if (NON_SHARED_DEVICE == mem) 01753 { 01754 *descriptor_l2 |= (1 << PAGE_4K_TEX1_SHIFT); 01755 } 01756 else if (NORMAL == mem) 01757 { 01758 *descriptor_l2 |= 1 << PAGE_4K_TEX2_SHIFT; 01759 switch(inner) 01760 { 01761 case NON_CACHEABLE: 01762 break; 01763 case WB_WA: 01764 *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT); 01765 break; 01766 case WT: 01767 *descriptor_l2 |= 1 << PAGE_4K_C_SHIFT; 01768 break; 01769 case WB_NO_WA: 01770 *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT) | (1 << PAGE_4K_C_SHIFT); 01771 break; 01772 } 01773 switch(outer) 01774 { 01775 case NON_CACHEABLE: 01776 break; 01777 case WB_WA: 01778 *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT); 01779 break; 01780 case WT: 01781 *descriptor_l2 |= 1 << PAGE_4K_TEX1_SHIFT; 01782 break; 01783 case WB_NO_WA: 01784 *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT) | (1 << PAGE_4K_TEX0_SHIFT); 01785 break; 01786 } 01787 } 01788 } 01789 01790 return 0; 01791 } 01792 01793 /** \brief Create a L1 section descriptor 01794 01795 \param [out] descriptor L1 descriptor 01796 \param [in] reg Section attributes 01797 01798 \return 0 01799 */ 01800 __STATIC_INLINE int MMU_GetSectionDescriptor(uint32_t *descriptor, mmu_region_attributes_Type reg) 01801 { 01802 *descriptor = 0; 01803 01804 MMU_MemorySection(descriptor, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t); 01805 MMU_XNSection(descriptor,reg.xn_t); 01806 MMU_DomainSection(descriptor, reg.domain); 01807 MMU_PSection(descriptor, reg.e_t); 01808 MMU_APSection(descriptor, reg.priv_t, reg.user_t, 1); 01809 MMU_SharedSection(descriptor,reg.sh_t); 01810 MMU_GlobalSection(descriptor,reg.g_t); 01811 MMU_SecureSection(descriptor,reg.sec_t); 01812 *descriptor &= SECTION_MASK; 01813 *descriptor |= SECTION_DESCRIPTOR; 01814 01815 return 0; 01816 } 01817 01818 01819 /** \brief Create a L1 and L2 4k/64k page descriptor 01820 01821 \param [out] descriptor L1 descriptor 01822 \param [out] descriptor2 L2 descriptor 01823 \param [in] reg 4k/64k page attributes 01824 01825 \return 0 01826 */ 01827 __STATIC_INLINE int MMU_GetPageDescriptor(uint32_t *descriptor, uint32_t *descriptor2, mmu_region_attributes_Type reg) 01828 { 01829 *descriptor = 0; 01830 *descriptor2 = 0; 01831 01832 switch (reg.rg_t) 01833 { 01834 case PAGE_4k: 01835 MMU_MemoryPage(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_4k); 01836 MMU_XNPage(descriptor2, reg.xn_t, PAGE_4k); 01837 MMU_DomainPage(descriptor, reg.domain); 01838 MMU_PPage(descriptor, reg.e_t); 01839 MMU_APPage(descriptor2, reg.priv_t, reg.user_t, 1); 01840 MMU_SharedPage(descriptor2,reg.sh_t); 01841 MMU_GlobalPage(descriptor2,reg.g_t); 01842 MMU_SecurePage(descriptor,reg.sec_t); 01843 *descriptor &= PAGE_L1_MASK; 01844 *descriptor |= PAGE_L1_DESCRIPTOR; 01845 *descriptor2 &= PAGE_L2_4K_MASK; 01846 *descriptor2 |= PAGE_L2_4K_DESC; 01847 break; 01848 01849 case PAGE_64k: 01850 MMU_MemoryPage(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_64k); 01851 MMU_XNPage(descriptor2, reg.xn_t, PAGE_64k); 01852 MMU_DomainPage(descriptor, reg.domain); 01853 MMU_PPage(descriptor, reg.e_t); 01854 MMU_APPage(descriptor2, reg.priv_t, reg.user_t, 1); 01855 MMU_SharedPage(descriptor2,reg.sh_t); 01856 MMU_GlobalPage(descriptor2,reg.g_t); 01857 MMU_SecurePage(descriptor,reg.sec_t); 01858 *descriptor &= PAGE_L1_MASK; 01859 *descriptor |= PAGE_L1_DESCRIPTOR; 01860 *descriptor2 &= PAGE_L2_64K_MASK; 01861 *descriptor2 |= PAGE_L2_64K_DESC; 01862 break; 01863 01864 case SECTION: 01865 //error 01866 break; 01867 } 01868 01869 return 0; 01870 } 01871 01872 /** \brief Create a 1MB Section 01873 01874 \param [in] ttb Translation table base address 01875 \param [in] base_address Section base address 01876 \param [in] count Number of sections to create 01877 \param [in] descriptor_l1 L1 descriptor (region attributes) 01878 01879 */ 01880 __STATIC_INLINE void MMU_TTSection(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1) 01881 { 01882 uint32_t offset; 01883 uint32_t entry; 01884 uint32_t i; 01885 01886 offset = base_address >> 20; 01887 entry = (base_address & 0xFFF00000) | descriptor_l1; 01888 01889 //4 bytes aligned 01890 ttb = ttb + offset; 01891 01892 for (i = 0; i < count; i++ ) 01893 { 01894 //4 bytes aligned 01895 *ttb++ = entry; 01896 entry += OFFSET_1M; 01897 } 01898 } 01899 01900 /** \brief Create a 4k page entry 01901 01902 \param [in] ttb L1 table base address 01903 \param [in] base_address 4k base address 01904 \param [in] count Number of 4k pages to create 01905 \param [in] descriptor_l1 L1 descriptor (region attributes) 01906 \param [in] ttb_l2 L2 table base address 01907 \param [in] descriptor_l2 L2 descriptor (region attributes) 01908 01909 */ 01910 __STATIC_INLINE void MMU_TTPage4k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 ) 01911 { 01912 01913 uint32_t offset, offset2; 01914 uint32_t entry, entry2; 01915 uint32_t i; 01916 01917 offset = base_address >> 20; 01918 entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1; 01919 01920 //4 bytes aligned 01921 ttb += offset; 01922 //create l1_entry 01923 *ttb = entry; 01924 01925 offset2 = (base_address & 0xff000) >> 12; 01926 ttb_l2 += offset2; 01927 entry2 = (base_address & 0xFFFFF000) | descriptor_l2; 01928 for (i = 0; i < count; i++ ) 01929 { 01930 //4 bytes aligned 01931 *ttb_l2++ = entry2; 01932 entry2 += OFFSET_4K; 01933 } 01934 } 01935 01936 /** \brief Create a 64k page entry 01937 01938 \param [in] ttb L1 table base address 01939 \param [in] base_address 64k base address 01940 \param [in] count Number of 64k pages to create 01941 \param [in] descriptor_l1 L1 descriptor (region attributes) 01942 \param [in] ttb_l2 L2 table base address 01943 \param [in] descriptor_l2 L2 descriptor (region attributes) 01944 01945 */ 01946 __STATIC_INLINE void MMU_TTPage64k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 ) 01947 { 01948 uint32_t offset, offset2; 01949 uint32_t entry, entry2; 01950 uint32_t i,j; 01951 01952 01953 offset = base_address >> 20; 01954 entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1; 01955 01956 //4 bytes aligned 01957 ttb += offset; 01958 //create l1_entry 01959 *ttb = entry; 01960 01961 offset2 = (base_address & 0xff000) >> 12; 01962 ttb_l2 += offset2; 01963 entry2 = (base_address & 0xFFFF0000) | descriptor_l2; 01964 for (i = 0; i < count; i++ ) 01965 { 01966 //create 16 entries 01967 for (j = 0; j < 16; j++) 01968 { 01969 //4 bytes aligned 01970 *ttb_l2++ = entry2; 01971 } 01972 entry2 += OFFSET_64K; 01973 } 01974 } 01975 01976 /** \brief Enable MMU 01977 01978 Enable MMU 01979 */ 01980 __STATIC_INLINE void MMU_Enable(void) { 01981 // Set M bit 0 to enable the MMU 01982 // Set AFE bit to enable simplified access permissions model 01983 // Clear TRE bit to disable TEX remap and A bit to disable strict alignment fault checking 01984 __set_SCTLR( (__get_SCTLR() & ~(1 << 28) & ~(1 << 1)) | 1 | (1 << 29)); 01985 __ISB(); 01986 } 01987 01988 /** \brief Disable MMU 01989 01990 Disable MMU 01991 */ 01992 __STATIC_INLINE void MMU_Disable(void) { 01993 // Clear M bit 0 to disable the MMU 01994 __set_SCTLR( __get_SCTLR() & ~1); 01995 __ISB(); 01996 } 01997 01998 /** \brief Invalidate entire unified TLB 01999 02000 TLBIALL. Invalidate entire unified TLB 02001 */ 02002 02003 __STATIC_INLINE void MMU_InvalidateTLB(void) { 02004 __set_TLBIALL(0); 02005 __DSB(); //ensure completion of the invalidation 02006 __ISB(); //ensure instruction fetch path sees new state 02007 } 02008 02009 02010 #ifdef __cplusplus 02011 } 02012 #endif 02013 02014 #endif /* __CORE_CA_H_DEPENDANT */ 02015 02016 #endif /* __CMSIS_GENERIC */
Generated on Tue Jul 12 2022 16:02:32 by 1.7.2