Changeset 0237380 in mainline
- Timestamp:
- 2012-11-25T16:37:57Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 37bb3e1
- Parents:
- e5c8bc6
- Location:
- kernel/arch/arm32
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/arm32/include/fpu_context.h
re5c8bc6 r0237380 44 44 45 45 /* ARM Architecture reference manual, p B-1529. 46 * We don't enable EX bit so max 32 64bit regs are stored (+2 control regs)47 46 */ 48 47 typedef struct { 48 uint32_t fpexc; 49 49 uint32_t fpuscr; 50 uint32_t fpuexc;51 50 uint32_t s[64]; 52 51 } fpu_context_t; … … 54 53 void fpu_setup(void); 55 54 55 bool handle_if_fpu_exception(void); 56 56 57 #endif 57 58 -
kernel/arch/arm32/src/exception.c
re5c8bc6 r0237380 167 167 static void undef_insn_exception(unsigned int exc_no, istate_t *istate) 168 168 { 169 #ifdef CONFIG_FPU_LAZY 170 scheduler_fpu_lazy_request(); 171 #else 172 fault_if_from_uspace(istate, "Undefined instruction."); 173 panic_badtrap(istate, exc_no, "Undefined instruction."); 174 #endif 169 if (!handle_if_fpu_exception()) { 170 fault_if_from_uspace(istate, "Undefined instruction."); 171 panic_badtrap(istate, exc_no, "Undefined instruction."); 172 } 175 173 } 176 174 -
kernel/arch/arm32/src/fpu_context.c
re5c8bc6 r0237380 47 47 FPU_VFPv1 = 0x00, 48 48 FPU_VFPv2_COMMONv1 = 0x01, 49 FPU_VFPv3_COMMONv2 = 0x02, /* Check MVFR0 and MVFR 1*/50 FPU_VFPv3_NO TRAP= 0x3, /* Does not support trap */51 FPU_VFPv3 = 0x4,49 FPU_VFPv3_COMMONv2 = 0x02, 50 FPU_VFPv3_NO_COMMON = 0x3, /* Does not support trap */ 51 FPU_VFPv3_COMMONv3 = 0x4, 52 52 }; 53 54 enum { 55 FPEXC_ENABLED_FLAG = 0x40000000, 56 FPEXC_EX_FLAG = 0x80000000, 57 }; 58 59 static inline uint32_t fpexc_read() 60 { 61 uint32_t reg; 62 asm volatile ( 63 "vmrs %0, fpexc\n" 64 :"=r" (reg):: 65 ); 66 return reg; 67 } 68 69 static inline void fpexc_write(uint32_t val) 70 { 71 asm volatile ( 72 "vmsr fpexc, %0\n" 73 ::"r" (val): 74 ); 75 } 53 76 54 77 static void (*save_context)(fpu_context_t *ctx); … … 62 85 { 63 86 asm volatile ( 87 "vmrs r1, fpexc\n" 88 "stmia %0!, {r1}\n" 64 89 "vmrs r1, fpscr\n" 65 90 "stmia %0!, {r1}\n" … … 76 101 { 77 102 asm volatile ( 103 "ldmia %0!, {r1}\n" 104 "vmsr fpexc, r1\n" 78 105 "ldmia %0!, {r1}\n" 79 106 "vmsr fpscr, r1\n" … … 90 117 { 91 118 asm volatile ( 119 "vmrs r1, fpexc\n" 120 "stmia %0!, {r1}\n" 92 121 "vmrs r1, fpscr\n" 93 122 "stmia %0!, {r1}\n" … … 104 133 { 105 134 asm volatile ( 135 "ldmia %0!, {r1}\n" 136 "vmsr fpexc, r1\n" 106 137 "ldmia %0!, {r1}\n" 107 138 "vmsr fpscr, r1\n" … … 118 149 { 119 150 asm volatile ( 151 "vmrs r1, fpexc\n" 152 "stmia %0!, {r1}\n" 120 153 "vmrs r1, fpscr\n" 121 154 "stmia %0!, {r1}\n" … … 133 166 { 134 167 asm volatile ( 168 "ldmia %0!, {r1}\n" 169 "vmsr fpexc, r1\n" 135 170 "ldmia %0!, {r1}\n" 136 171 "vmsr fpscr, r1\n" … … 143 178 void fpu_init(void) 144 179 { 180 /* Clear all fpu flags */ 181 fpexc_write(0); 145 182 fpu_enable(); 146 183 } … … 150 187 uint32_t fpsid = 0; 151 188 asm volatile ( 152 "vmrs %0, fpsid\n"189 "vmrs %0, fpsid\n" 153 190 :"=r"(fpsid):: 154 191 ); … … 170 207 break; 171 208 case FPU_VFPv3_COMMONv2: 172 case FPU_VFPv3_NO TRAP:173 case FPU_VFPv3 : {209 case FPU_VFPv3_NO_COMMON: 210 case FPU_VFPv3_COMMONv3: { 174 211 uint32_t mvfr0 = 0; 175 212 asm volatile ( … … 179 216 /* See page B4-1637 */ 180 217 if ((mvfr0 & 0xf) == 0x1) { 218 printf("Detected VFPv3+ with 16 regs\n"); 219 save_context = fpu_context_save_d16; 220 restore_context = fpu_context_restore_d16; 221 } else { 181 222 printf("Detected VFPv3+ with 32 regs\n"); 182 223 save_context = fpu_context_save_d32; 183 224 restore_context = fpu_context_restore_d32; 184 } else {185 printf("Detected VFPv3+ with 16 regs\n");186 save_context = fpu_context_save_d16;187 restore_context = fpu_context_restore_d16;188 225 } 189 226 break; … … 193 230 } 194 231 232 bool handle_if_fpu_exception(void) 233 { 234 const uint32_t fpexc = fpexc_read(); 235 if (fpexc & FPEXC_ENABLED_FLAG) { 236 printf("FPU exception with FPU on\n"); 237 return false; 238 } 239 #ifdef CONFIG_FPU_LAZY 240 scheduler_fpu_lazy_request(); 241 return true; 242 #else 243 return false; 244 #endif 245 } 246 195 247 void fpu_enable(void) 196 248 { 197 249 /* Enable FPU instructions */ 198 asm volatile ( 199 "ldr r1, =0x40000000\n" 200 "vmsr fpexc, r1\n" 201 ::: "r1" 202 ); 250 fpexc_write(fpexc_read() | FPEXC_ENABLED_FLAG); 203 251 } 204 252 … … 206 254 { 207 255 /* Disable FPU instructions */ 208 asm volatile ( 209 "ldr r1, =0x00000000\n" 210 "vmsr fpexc, r1\n" 211 ::: "r1" 212 ); 256 fpexc_write(fpexc_read() & ~FPEXC_ENABLED_FLAG); 213 257 } 214 258
Note:
See TracChangeset
for help on using the changeset viewer.