Changeset 5fcd537 in mainline
- Timestamp:
- 2013-01-19T02:25:08Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- bad1f53
- Parents:
- ae86f89 (diff), 660e8fa (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- kernel/arch/arm32
- Files:
-
- 3 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/arm32/Makefile.inc
rae86f89 r5fcd537 35 35 GCC_CFLAGS += -fno-omit-frame-pointer -mapcs-frame -march=$(subst _,-,$(PROCESSOR_ARCH)) -mno-unaligned-access 36 36 37 ifeq ($(MACHINE),beagleboardxm) 38 GCC_CFLAGS += -mcpu=cortex-a8 39 endif 40 37 41 ifeq ($(CONFIG_FPU),y) 38 42 # This is necessary to allow vmsr insn and fpexc manipulation 39 43 # Use vfp32 to allow context save/restore of d16-d31 regs. 40 GCC_CFLAGS += -mfloat-abi=hard -mfpu=vfp344 AFLAGS += -mfloat-abi=hard -mfpu=vfp3 41 45 endif 42 46 … … 70 74 ifeq ($(CONFIG_FPU),y) 71 75 ARCH_SOURCES += arch/$(KARCH)/src/fpu_context.c 76 ARCH_SOURCES += arch/$(KARCH)/src/fpu.s 72 77 endif 73 78 -
kernel/arch/arm32/include/barrier.h
rae86f89 r5fcd537 39 39 /* 40 40 * TODO: implement true ARM memory barriers for macros below. 41 * ARMv6 introduced user access of the following commands: 42 * • Prefetch flush 43 * • Data synchronization barrier 44 * • Data memory barrier 45 * • Clean and prefetch range operations. 46 * ARM Architecture Reference Manual version I ch. B.3.2.1 p. B3-4 41 47 */ 42 48 #define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") … … 88 94 */ 89 95 90 /* Available on both all supported arms, 96 #ifdef PROCESSOR_ARCH_armv7_a 97 #define smc_coherence(a) asm volatile ( "isb" ::: "memory") 98 #define smc_coherence_block(a, l) smc_coherence(a) 99 #else 100 /* Available on all supported arms, 91 101 * invalidates entire ICache so the written value does not matter. */ 102 //TODO might be PL1 only on armv5 - 92 103 #define smc_coherence(a) asm volatile ( "mcr p15, 0, r0, c7, c5, 0") 93 104 #define smc_coherence_block(a, l) smc_coherence(a) 105 #endif 94 106 95 107 -
kernel/arch/arm32/include/regutils.h
rae86f89 r5fcd537 66 66 67 67 /* ARM Processor Operation Modes */ 68 #define USER_MODE 0x10 69 #define FIQ_MODE 0x11 70 #define IRQ_MODE 0x12 71 #define SUPERVISOR_MODE 0x13 72 #define ABORT_MODE 0x17 73 #define UNDEFINED_MODE 0x1b 74 #define SYSTEM_MODE 0x1f 75 68 enum { 69 USER_MODE = 0x10, 70 FIQ_MODE = 0x11, 71 IRQ_MODE = 0x12, 72 SUPERVISOR_MODE = 0x13, 73 MONITOR_MODE = 0x16, 74 ABORT_MODE = 0x17, 75 HYPERVISOR_MODE = 0x1a, 76 UNDEFINED_MODE = 0x1b, 77 SYSTEM_MODE = 0x1f, 78 MODE_MASK = 0x1f, 79 }; 76 80 /* [CS]PRS manipulation macros */ 77 81 #define GEN_STATUS_READ(nm, reg) \ -
kernel/arch/arm32/src/fpu_context.c
rae86f89 r5fcd537 37 37 #include <arch.h> 38 38 #include <arch/types.h> 39 #include <arch/security_ext.h> 40 #include <arch/cp15.h> 39 41 #include <cpu.h> 40 42 … … 55 57 }; 56 58 59 extern uint32_t fpsid_read(void); 60 extern uint32_t mvfr0_read(void); 61 57 62 enum { 58 63 FPEXC_EX_FLAG = (1 << 31), 59 64 FPEXC_ENABLED_FLAG = (1 << 30), 60 65 }; 66 extern uint32_t fpexc_read(void); 67 extern void fpexc_write(uint32_t); 61 68 62 69 /** ARM Architecture Reference Manual ch. B4.1.58, p. B$-1551 */ … … 94 101 FPSCR_EN_ALL = FPSCR_DENORMAL_EN_FLAG | FPSCR_INEXACT_EN_FLAG | FPSCR_UNDERFLOW_EN_FLAG | FPSCR_OVERFLOW_EN_FLAG | FPSCR_ZERO_DIV_EN_FLAG | FPSCR_INVALID_OP_EN_FLAG, 95 102 }; 96 97 static inline uint32_t fpscr_read() 98 { 99 uint32_t reg; 100 asm volatile ( 101 "vmrs %0, fpscr\n" 102 :"=r" (reg):: 103 ); 104 return reg; 105 } 106 107 static inline void fpscr_write(uint32_t val) 108 { 109 asm volatile ( 110 "vmsr fpscr, %0\n" 111 ::"r" (val): 112 ); 113 } 114 115 static inline uint32_t fpexc_read() 116 { 117 uint32_t reg; 118 asm volatile ( 119 "vmrs %0, fpexc\n" 120 :"=r" (reg):: 121 ); 122 return reg; 123 } 124 125 static inline void fpexc_write(uint32_t val) 126 { 127 asm volatile ( 128 "vmsr fpexc, %0\n" 129 ::"r" (val): 130 ); 131 } 103 extern uint32_t fpscr_read(void); 104 extern void fpscr_write(uint32_t); 105 106 extern void fpu_context_save_s32(fpu_context_t *); 107 extern void fpu_context_restore_s32(fpu_context_t *); 108 extern void fpu_context_save_d16(fpu_context_t *); 109 extern void fpu_context_restore_d16(fpu_context_t *); 110 extern void fpu_context_save_d32(fpu_context_t *); 111 extern void fpu_context_restore_d32(fpu_context_t *); 132 112 133 113 static void (*save_context)(fpu_context_t *ctx); 134 114 static void (*restore_context)(fpu_context_t *ctx); 135 115 136 /** Saves 32 single precision fpu registers. 137 * @param ctx FPU context area. 138 * Used by VFPv1 139 */ 140 static void fpu_context_save_s32(fpu_context_t *ctx) 141 { 142 asm volatile ( 143 "vmrs r1, fpexc\n" 144 "vmrs r2, fpscr\n" 145 "stmia %0!, {r1, r2}\n" 146 "vstmia %0!, {s0-s31}\n" 147 ::"r" (ctx): "r1","r2","memory" 148 ); 149 } 150 151 /** Restores 32 single precision fpu registers. 152 * @param ctx FPU context area. 153 * Used by VFPv1 154 */ 155 static void fpu_context_restore_s32(fpu_context_t *ctx) 156 { 157 asm volatile ( 158 "ldmia %0!, {r1, r2}\n" 159 "vmsr fpexc, r1\n" 160 "vmsr fpscr, r2\n" 161 "vldmia %0!, {s0-s31}\n" 162 ::"r" (ctx): "r1","r2" 163 ); 164 } 165 166 /** Saves 16 double precision fpu registers. 167 * @param ctx FPU context area. 168 * Used by VFPv2, VFPv3-d16, and VFPv4-d16. 169 */ 170 static void fpu_context_save_d16(fpu_context_t *ctx) 171 { 172 asm volatile ( 173 "vmrs r1, fpexc\n" 174 "vmrs r2, fpscr\n" 175 "stmia %0!, {r1, r2}\n" 176 "vstmia %0!, {d0-d15}\n" 177 ::"r" (ctx): "r1","r2","memory" 178 ); 179 } 180 181 /** Restores 16 double precision fpu registers. 182 * @param ctx FPU context area. 183 * Used by VFPv2, VFPv3-d16, and VFPv4-d16. 184 */ 185 static void fpu_context_restore_d16(fpu_context_t *ctx) 186 { 187 asm volatile ( 188 "ldmia %0!, {r1, r2}\n" 189 "vmsr fpexc, r1\n" 190 "vmsr fpscr, r2\n" 191 "vldmia %0!, {d0-d15}\n" 192 ::"r" (ctx): "r1","r2" 193 ); 194 } 195 196 /** Saves 32 double precision fpu registers. 197 * @param ctx FPU context area. 198 * Used by VFPv3-d32, VFPv4-d32, and advanced SIMD. 199 */ 200 static void fpu_context_save_d32(fpu_context_t *ctx) 201 { 202 asm volatile ( 203 "vmrs r1, fpexc\n" 204 "stmia %0!, {r1}\n" 205 "vmrs r1, fpscr\n" 206 "stmia %0!, {r1}\n" 207 "vstmia %0!, {d0-d15}\n" 208 "vstmia %0!, {d16-d31}\n" 209 ::"r" (ctx): "r1","memory" 210 ); 211 } 212 213 /** Restores 32 double precision fpu registers. 214 * @param ctx FPU context area. 215 * Used by VFPv3-d32, VFPv4-d32, and advanced SIMD. 216 */ 217 static void fpu_context_restore_d32(fpu_context_t *ctx) 218 { 219 asm volatile ( 220 "ldmia %0!, {r1}\n" 221 "vmsr fpexc, r1\n" 222 "ldmia %0!, {r1}\n" 223 "vmsr fpscr, r1\n" 224 "vldmia %0!, {d0-d15}\n" 225 "vldmia %0!, {d16-d31}\n" 226 ::"r" (ctx): "r1" 227 ); 228 } 116 static int fpu_have_coprocessor_access() 117 { 118 /* The register containing the information (CPACR) is not available on armv6- 119 * rely on user decision to use CONFIG_FPU. 120 */ 121 #ifdef PROCESSOR_ARC_armv7_a 122 const uint32_t cpacr = CPACR_read(); 123 /* FPU needs access to coprocessor 10 and 11. 124 * Moreover they need to have same access enabledd */ 125 if (((cpacr & CPACR_CP_MASK(10)) != CPACR_CP_FULL_ACCESS(10)) && 126 ((cpacr & CPACR_CP_MASK(11)) != CPACR_CP_FULL_ACCESS(11))) { 127 printf("No access to CP10 and CP11: %" PRIx32 "\n", cpacr); 128 return 0; 129 } 130 #endif 131 return 1; 132 } 133 134 /** Enable coprocessor access. Turn both non-secure mode bit and generic access. 135 * Cortex A8 Manual says: 136 * "You must execute an Instruction Memory Barrier (IMB) sequence immediately 137 * after an update of the Coprocessor Access Control Register, see Memory 138 * Barriers in the ARM Architecture Reference Manual. You must not attempt to 139 * execute any instructions that are affected by the change of access rights 140 * between the IMB sequence and the register update." 141 * Cortex a8 TRM ch. 3.2.27. c1, Coprocessor Access Control Register 142 * 143 * @note do we need to call secure monitor here? 144 */ 145 static void fpu_enable_coprocessor_access() 146 { 147 /* The register containing the information (CPACR) is not available on armv6- 148 * rely on user decision to use CONFIG_FPU. 149 */ 150 #ifndef PROCESSOR_ARCH_armv7_a 151 return; 152 #endif 153 154 /* Allow coprocessor access */ 155 uint32_t cpacr = CPACR_read(); 156 /* FPU needs access to coprocessor 10 and 11. 157 * Moreover, they need to have same access enabled */ 158 cpacr &= ~(CPACR_CP_MASK(10) | CPACR_CP_MASK(11)); 159 cpacr |= (CPACR_CP_FULL_ACCESS(10) | CPACR_CP_FULL_ACCESS(11)); 160 CPACR_write(cpacr); 161 162 smc_coherence(0); 163 } 164 229 165 230 166 void fpu_init(void) 231 167 { 168 /* Check if we have access */ 169 if (!fpu_have_coprocessor_access()) 170 return; 171 232 172 /* Clear all fpu flags */ 233 173 fpexc_write(0); … … 241 181 void fpu_setup(void) 242 182 { 243 uint32_t fpsid = 0; 244 asm volatile ( 245 "vmrs %0, fpsid\n" 246 :"=r"(fpsid):: 247 ); 183 /* Enable coprocessor access*/ 184 fpu_enable_coprocessor_access(); 185 186 /* Check if we succeeded */ 187 if (!fpu_have_coprocessor_access()) 188 return; 189 190 const uint32_t fpsid = fpsid_read(); 248 191 if (fpsid & FPSID_SW_ONLY_FLAG) { 249 192 printf("No FPU avaiable\n"); … … 265 208 case FPU_VFPv3_NO_COMMON: 266 209 case FPU_VFPv3_COMMONv3: { 267 uint32_t mvfr0 = 0; 268 asm volatile ( 269 "vmrs %0,mvfr0\n" 270 :"=r"(mvfr0):: 271 ); 210 const uint32_t mvfr0 = mvfr0_read(); 272 211 /* See page B4-1637 */ 273 212 if ((mvfr0 & 0xf) == 0x1) { … … 288 227 bool handle_if_fpu_exception(void) 289 228 { 229 /* Check if we have access */ 230 if (!fpu_have_coprocessor_access()) 231 return false; 232 290 233 const uint32_t fpexc = fpexc_read(); 291 234 if (fpexc & FPEXC_ENABLED_FLAG) { … … 305 248 void fpu_enable(void) 306 249 { 250 /* Check if we have access */ 251 if (!fpu_have_coprocessor_access()) 252 return; 307 253 /* Enable FPU instructions */ 308 254 fpexc_write(fpexc_read() | FPEXC_ENABLED_FLAG); … … 311 257 void fpu_disable(void) 312 258 { 259 /* Check if we have access */ 260 if (!fpu_have_coprocessor_access()) 261 return; 313 262 /* Disable FPU instructions */ 314 263 fpexc_write(fpexc_read() & ~FPEXC_ENABLED_FLAG); … … 317 266 void fpu_context_save(fpu_context_t *ctx) 318 267 { 268 /* This is only necessary if we enable fpu exceptions. */ 269 #if 0 319 270 const uint32_t fpexc = fpexc_read(); 320 271 … … 323 274 //TODO implement common subarch context saving 324 275 } 276 #endif 325 277 if (save_context) 326 278 save_context(ctx);
Note:
See TracChangeset
for help on using the changeset viewer.