Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-dev by
core_ca.h
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 Wed Jul 27 2022 09:32:04 by
