Changes in / [5203efb1:2fa10f6] in mainline
- Location:
- kernel/arch/mips32
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/mips32/include/context_offset.h
r5203efb1 r2fa10f6 61 61 #endif /* KERNEL */ 62 62 63 /* istate_t */ 64 #define EOFFSET_AT 0x0 65 #define EOFFSET_V0 0x4 66 #define EOFFSET_V1 0x8 67 #define EOFFSET_A0 0xc 68 #define EOFFSET_A1 0x10 69 #define EOFFSET_A2 0x14 70 #define EOFFSET_A3 0x18 71 #define EOFFSET_T0 0x1c 72 #define EOFFSET_T1 0x20 73 #define EOFFSET_T2 0x24 74 #define EOFFSET_T3 0x28 75 #define EOFFSET_T4 0x2c 76 #define EOFFSET_T5 0x30 77 #define EOFFSET_T6 0x34 78 #define EOFFSET_T7 0x38 79 #define EOFFSET_T8 0x3c 80 #define EOFFSET_T9 0x40 81 #define EOFFSET_GP 0x44 82 #define EOFFSET_SP 0x48 83 #define EOFFSET_RA 0x4c 84 #define EOFFSET_LO 0x50 85 #define EOFFSET_HI 0x54 86 #define EOFFSET_STATUS 0x58 87 #define EOFFSET_EPC 0x5c 88 #define EOFFSET_K1 0x60 89 #define REGISTER_SPACE 104 /* respect stack alignment */ 90 63 91 #ifdef __ASM__ 64 92 -
kernel/arch/mips32/include/exception.h
r5203efb1 r2fa10f6 60 60 61 61 typedef struct istate { 62 /* 63 * The first seven registers are arranged so that the istate structure 64 * can be used both for exception handlers and for the syscall handler. 65 */ 66 uint32_t a0; /* arg1 */ 67 uint32_t a1; /* arg2 */ 68 uint32_t a2; /* arg3 */ 69 uint32_t a3; /* arg4 */ 70 uint32_t t0; /* arg5 */ 71 uint32_t t1; /* arg6 */ 72 uint32_t v0; /* arg7 */ 62 uint32_t at; 63 uint32_t v0; 73 64 uint32_t v1; 74 uint32_t at; 65 uint32_t a0; 66 uint32_t a1; 67 uint32_t a2; 68 uint32_t a3; 69 uint32_t t0; 70 uint32_t t1; 75 71 uint32_t t2; 76 72 uint32_t t3; … … 79 75 uint32_t t6; 80 76 uint32_t t7; 81 uint32_t s0;82 uint32_t s1;83 uint32_t s2;84 uint32_t s3;85 uint32_t s4;86 uint32_t s5;87 uint32_t s6;88 uint32_t s7;89 77 uint32_t t8; 90 78 uint32_t t9; 91 uint32_t kt0;92 uint32_t kt1; /* We use it as thread-local pointer */93 79 uint32_t gp; 94 80 uint32_t sp; 95 uint32_t s8;96 81 uint32_t ra; 97 82 … … 99 84 uint32_t hi; 100 85 101 uint32_t status; /* cp0_status */ 102 uint32_t epc; /* cp0_epc */ 103 104 uint32_t alignment; /* to make sizeof(istate_t) a multiple of 8 */ 86 uint32_t status; /* cp0_status */ 87 uint32_t epc; /* cp0_epc */ 88 uint32_t k1; /* We use it as thread-local pointer */ 105 89 } istate_t; 106 90 … … 124 108 NO_TRACE static inline unative_t istate_get_fp(istate_t *istate) 125 109 { 126 return istate->sp; 110 /* FIXME */ 111 112 return 0; 127 113 } 128 114 -
kernel/arch/mips32/src/debug/stacktrace.c
r5203efb1 r2fa10f6 33 33 */ 34 34 35 /*36 * This stack tracing code is based on the suggested algorithm described on page37 * 3-27 and 3-28 of:38 *39 * SYSTEM V40 * APPLICATION BINARY INTERFACE41 *42 * MIPS RISC Processor43 * Supplement44 * 3rd Edition45 *46 * Unfortunately, GCC generates code which is not entirely compliant with this47 * method. For example, it places the "jr ra" instruction quite arbitrarily in48 * the middle of the function which makes the original algorithm unapplicable.49 *50 * We deal with this problem by simply not using those parts of the algorithm51 * that rely on the "jr ra" instruction occurring in the last basic block of a52 * function, which gives us still usable, but less reliable stack tracer. The53 * unreliability stems from the fact that under some circumstances it can become54 * confused and produce incorrect or incomplete stack trace. We apply extra55 * sanity checks so that the algorithm is still safe and should not crash the56 * system.57 *58 * Even though not perfect, our solution is pretty lightweight, especially when59 * compared with a prospective alternative solution based on additional60 * debugging information stored directly in the kernel image.61 */62 63 35 #include <stacktrace.h> 64 36 #include <syscall/copy.h> … … 124 96 extern char ktext_end; 125 97 126 static bool bounds_check(uintptr_t pc)127 {128 return (pc >= (uintptr_t) &ktext_start) &&129 (pc < (uintptr_t) &ktext_end);130 }131 132 98 static bool 133 99 scan(stack_trace_context_t *ctx, uintptr_t *prev_fp, uintptr_t *prev_ra) … … 140 106 do { 141 107 inst--; 142 if (!bounds_check((uintptr_t) inst))143 return false;144 108 #if 0 145 109 /* … … 216 180 return false; 217 181 /* too big offsets are suspicious */ 218 if ( (size_t) offset > sizeof(istate_t))182 if (offset > 32 * 4) 219 183 return false; 220 184 … … 243 207 { 244 208 return !((ctx->fp == 0) || ((ctx->fp % 8) != 0) || 245 (ctx->pc % 4 != 0) || !bounds_check(ctx->pc)); 209 (ctx->pc % 4 != 0) || (ctx->pc < (uintptr_t) &ktext_start) || 210 (ctx->pc >= (uintptr_t) &ktext_end)); 246 211 } 247 212 -
kernel/arch/mips32/src/exception.c
r5203efb1 r2fa10f6 74 74 void istate_decode(istate_t *istate) 75 75 { 76 printf("epc=%p\tsta=%p\tlo =%p\thi =%p\n", 77 istate->epc, istate->status, istate->lo, istate->hi); 78 printf("a0 =%p\ta1 =%p\ta2 =%p\ta3 =%p\n", 79 istate->a0, istate->a1, istate->a2, istate->a3); 80 printf("t0 =%p\tt1 =%p\tt2 =%p\tt3 =%p\n", 81 istate->t0, istate->t1, istate->t2, istate->t3); 82 printf("t4 =%p\tt5 =%p\tt6 =%p\tt7 =%p\n", 83 istate->t4, istate->t5, istate->t6, istate->t7); 84 printf("t8 =%p\tt9 =%p\tv0 =%p\tv1 =%p\n", 85 istate->t8, istate->t9, istate->v0, istate->v1); 86 printf("s0 =%p\ts1 =%p\ts2 =%p\ts3 =%p\n", 87 istate->s0, istate->s1, istate->s2, istate->s3); 88 printf("s4 =%p\ts5 =%p\ts6 =%p\ts7 =%p\n", 89 istate->s4, istate->s5, istate->s6, istate->s7); 90 printf("s8 =%p\tat =%p\tkt0=%p\tkt1=%p\n", 91 istate->s8, istate->at, istate->kt0, istate->kt1); 92 printf("sp =%p\tra =%p\tgp =%p\n", 93 istate->sp, istate->ra, istate->gp); 76 printf("at=%p\tv0=%p\tv1=%p\n", istate->at, istate->v0, istate->v1); 77 printf("a0=%p\ta1=%p\ta2=%p\n", istate->a0, istate->a1, istate->a2); 78 printf("a3=%p\tt0=%p\tt1=%p\n", istate->a3, istate->t0, istate->t1); 79 printf("t2=%p\tt3=%p\tt4=%p\n", istate->t2, istate->t3, istate->t4); 80 printf("t5=%p\tt6=%p\tt7=%p\n", istate->t5, istate->t6, istate->t7); 81 printf("t8=%p\tt9=%p\tgp=%p\n", istate->t8, istate->t9, istate->gp); 82 printf("sp=%p\tra=%p\t\n", istate->sp, istate->ra); 83 printf("lo=%p\thi=%p\t\n", istate->lo, istate->hi); 84 printf("cp0_status=%p\tcp0_epc=%p\tk1=%p\n", 85 istate->status, istate->epc, istate->k1); 94 86 } 95 87 … … 105 97 ASSERT(THREAD); 106 98 istate->epc += 4; 107 istate->v1 = istate->k t1;99 istate->v1 = istate->k1; 108 100 } else 109 101 unhandled_exception(n, istate); -
kernel/arch/mips32/src/start.S
r5203efb1 r2fa10f6 46 46 47 47 /* 48 * Which status bits are thread-local:48 * Which status bits should are thread-local: 49 49 * KSU(UM), EXL, ERL, IE 50 50 */ 51 51 #define REG_SAVE_MASK 0x1f 52 53 #define ISTATE_OFFSET_A0 054 #define ISTATE_OFFSET_A1 455 #define ISTATE_OFFSET_A2 856 #define ISTATE_OFFSET_A3 1257 #define ISTATE_OFFSET_T0 1658 #define ISTATE_OFFSET_T1 2059 #define ISTATE_OFFSET_V0 2460 #define ISTATE_OFFSET_V1 2861 #define ISTATE_OFFSET_AT 3262 #define ISTATE_OFFSET_T2 3663 #define ISTATE_OFFSET_T3 4064 #define ISTATE_OFFSET_T4 4465 #define ISTATE_OFFSET_T5 4866 #define ISTATE_OFFSET_T6 5267 #define ISTATE_OFFSET_T7 5668 #define ISTATE_OFFSET_S0 6069 #define ISTATE_OFFSET_S1 6470 #define ISTATE_OFFSET_S2 6871 #define ISTATE_OFFSET_S3 7272 #define ISTATE_OFFSET_S4 7673 #define ISTATE_OFFSET_S5 8074 #define ISTATE_OFFSET_S6 8475 #define ISTATE_OFFSET_S7 8876 #define ISTATE_OFFSET_T8 9277 #define ISTATE_OFFSET_T9 9678 #define ISTATE_OFFSET_KT0 10079 #define ISTATE_OFFSET_KT1 10480 #define ISTATE_OFFSET_GP 10881 #define ISTATE_OFFSET_SP 11282 #define ISTATE_OFFSET_S8 11683 #define ISTATE_OFFSET_RA 12084 #define ISTATE_OFFSET_LO 12485 #define ISTATE_OFFSET_HI 12886 #define ISTATE_OFFSET_STATUS 13287 #define ISTATE_OFFSET_EPC 13688 #define ISTATE_OFFSET_ALIGNMENT 14089 90 #define ISTATE_SOFT_SIZE 14491 92 /*93 * The fake ABI prologue is never executed and may not be part of the94 * procedure's body. Instead, it should be immediately preceding the procedure's95 * body. Its only purpose is to trick the stack trace walker into thinking that96 * the exception is more or less just a normal function call.97 */98 .macro FAKE_ABI_PROLOGUE99 sub $sp, ISTATE_SOFT_SIZE100 sw $ra, ISTATE_OFFSET_EPC($sp)101 .endm102 52 103 53 /* … … 108 58 */ 109 59 .macro REGISTERS_STORE_AND_EXC_RESET r 110 sw $at, ISTATE_OFFSET_AT(\r) 111 sw $v0, ISTATE_OFFSET_V0(\r) 112 sw $v1, ISTATE_OFFSET_V1(\r) 113 sw $a0, ISTATE_OFFSET_A0(\r) 114 sw $a1, ISTATE_OFFSET_A1(\r) 115 sw $a2, ISTATE_OFFSET_A2(\r) 116 sw $a3, ISTATE_OFFSET_A3(\r) 117 sw $t0, ISTATE_OFFSET_T0(\r) 118 sw $t1, ISTATE_OFFSET_T1(\r) 119 sw $t2, ISTATE_OFFSET_T2(\r) 120 sw $t3, ISTATE_OFFSET_T3(\r) 121 sw $t4, ISTATE_OFFSET_T4(\r) 122 sw $t5, ISTATE_OFFSET_T5(\r) 123 sw $t6, ISTATE_OFFSET_T6(\r) 124 sw $t7, ISTATE_OFFSET_T7(\r) 125 sw $t8, ISTATE_OFFSET_T8(\r) 126 sw $t9, ISTATE_OFFSET_T9(\r) 127 sw $s0, ISTATE_OFFSET_S0(\r) 128 sw $s1, ISTATE_OFFSET_S1(\r) 129 sw $s2, ISTATE_OFFSET_S2(\r) 130 sw $s3, ISTATE_OFFSET_S3(\r) 131 sw $s4, ISTATE_OFFSET_S4(\r) 132 sw $s5, ISTATE_OFFSET_S5(\r) 133 sw $s6, ISTATE_OFFSET_S6(\r) 134 sw $s7, ISTATE_OFFSET_S7(\r) 135 sw $s8, ISTATE_OFFSET_S8(\r) 60 sw $at, EOFFSET_AT(\r) 61 sw $v0, EOFFSET_V0(\r) 62 sw $v1, EOFFSET_V1(\r) 63 sw $a0, EOFFSET_A0(\r) 64 sw $a1, EOFFSET_A1(\r) 65 sw $a2, EOFFSET_A2(\r) 66 sw $a3, EOFFSET_A3(\r) 67 sw $t0, EOFFSET_T0(\r) 68 sw $t1, EOFFSET_T1(\r) 69 sw $t2, EOFFSET_T2(\r) 70 sw $t3, EOFFSET_T3(\r) 71 sw $t4, EOFFSET_T4(\r) 72 sw $t5, EOFFSET_T5(\r) 73 sw $t6, EOFFSET_T6(\r) 74 sw $t7, EOFFSET_T7(\r) 75 sw $t8, EOFFSET_T8(\r) 76 sw $t9, EOFFSET_T9(\r) 136 77 137 78 mflo $at 138 sw $at, ISTATE_OFFSET_LO(\r)79 sw $at, EOFFSET_LO(\r) 139 80 mfhi $at 140 sw $at, ISTATE_OFFSET_HI(\r) 141 142 sw $gp, ISTATE_OFFSET_GP(\r) 143 sw $ra, ISTATE_OFFSET_RA(\r) 144 sw $k0, ISTATE_OFFSET_KT0(\r) 145 sw $k1, ISTATE_OFFSET_KT1(\r) 81 sw $at, EOFFSET_HI(\r) 82 83 sw $gp, EOFFSET_GP(\r) 84 sw $ra, EOFFSET_RA(\r) 85 sw $k1, EOFFSET_K1(\r) 146 86 147 87 mfc0 $t0, $status … … 155 95 and $t0, $t0, $t3 156 96 157 sw $t2, ISTATE_OFFSET_STATUS(\r)158 sw $t1, ISTATE_OFFSET_EPC(\r)97 sw $t2, EOFFSET_STATUS(\r) 98 sw $t1, EOFFSET_EPC(\r) 159 99 mtc0 $t0, $status 160 100 .endm … … 166 106 */ 167 107 mfc0 $t0, $status 168 lw $t1, ISTATE_OFFSET_STATUS(\r)108 lw $t1,EOFFSET_STATUS(\r) 169 109 170 110 /* mask UM, EXL, ERL, IE */ … … 176 116 mtc0 $t0, $status 177 117 178 lw $v0, ISTATE_OFFSET_V0(\r)179 lw $v1, ISTATE_OFFSET_V1(\r)180 lw $a0, ISTATE_OFFSET_A0(\r)181 lw $a1, ISTATE_OFFSET_A1(\r)182 lw $a2, ISTATE_OFFSET_A2(\r)183 lw $a3, ISTATE_OFFSET_A3(\r)184 lw $t0, ISTATE_OFFSET_T0(\r)185 lw $t1, ISTATE_OFFSET_T1(\r)186 lw $t2, ISTATE_OFFSET_T2(\r)187 lw $t3, ISTATE_OFFSET_T3(\r)188 lw $t4, ISTATE_OFFSET_T4(\r)189 lw $t5, ISTATE_OFFSET_T5(\r)190 lw $t6, ISTATE_OFFSET_T6(\r)191 lw $t7, ISTATE_OFFSET_T7(\r)192 lw $t8, ISTATE_OFFSET_T8(\r)193 lw $t9, ISTATE_OFFSET_T9(\r)194 195 lw $gp, ISTATE_OFFSET_GP(\r)196 lw $ra, ISTATE_OFFSET_RA(\r)197 lw $k1, ISTATE_OFFSET_KT1(\r)198 199 lw $at, ISTATE_OFFSET_LO(\r)118 lw $v0, EOFFSET_V0(\r) 119 lw $v1, EOFFSET_V1(\r) 120 lw $a0, EOFFSET_A0(\r) 121 lw $a1, EOFFSET_A1(\r) 122 lw $a2, EOFFSET_A2(\r) 123 lw $a3, EOFFSET_A3(\r) 124 lw $t0, EOFFSET_T0(\r) 125 lw $t1, EOFFSET_T1(\r) 126 lw $t2, EOFFSET_T2(\r) 127 lw $t3, EOFFSET_T3(\r) 128 lw $t4, EOFFSET_T4(\r) 129 lw $t5, EOFFSET_T5(\r) 130 lw $t6, EOFFSET_T6(\r) 131 lw $t7, EOFFSET_T7(\r) 132 lw $t8, EOFFSET_T8(\r) 133 lw $t9, EOFFSET_T9(\r) 134 135 lw $gp, EOFFSET_GP(\r) 136 lw $ra, EOFFSET_RA(\r) 137 lw $k1, EOFFSET_K1(\r) 138 139 lw $at, EOFFSET_LO(\r) 200 140 mtlo $at 201 lw $at, ISTATE_OFFSET_HI(\r)141 lw $at, EOFFSET_HI(\r) 202 142 mthi $at 203 143 204 lw $at, ISTATE_OFFSET_EPC(\r)144 lw $at, EOFFSET_EPC(\r) 205 145 mtc0 $at, $epc 206 146 207 lw $at, ISTATE_OFFSET_AT(\r)208 lw $sp, ISTATE_OFFSET_SP(\r)147 lw $at, EOFFSET_AT(\r) 148 lw $sp, EOFFSET_SP(\r) 209 149 .endm 210 150 … … 219 159 220 160 beq $k0, $0, 1f 221 move $k0, $sp161 add $k0, $sp, 0 222 162 223 163 /* move $k0 pointer to kernel stack */ … … 226 166 227 167 /* move $k0 (supervisor_sp) */ 228 lw $k0, ($k0)168 lw $k0, 0($k0) 229 169 230 170 1: … … 262 202 nop 263 203 264 FAKE_ABI_PROLOGUE265 204 exception_handler: 266 205 KERNEL_STACK_TO_K0 267 206 268 sub $k0, ISTATE_SOFT_SIZE269 sw $sp, ISTATE_OFFSET_SP($k0)207 sub $k0, REGISTER_SPACE 208 sw $sp, EOFFSET_SP($k0) 270 209 move $sp, $k0 271 210 … … 288 227 /* the $sp is automatically restored to former value */ 289 228 eret 229 230 #define SS_SP EOFFSET_SP 231 #define SS_STATUS EOFFSET_STATUS 232 #define SS_EPC EOFFSET_EPC 233 #define SS_K1 EOFFSET_K1 290 234 291 235 /** Syscall entry … … 305 249 */ 306 250 syscall_shortcut: 251 /* we have a lot of space on the stack, with free use */ 307 252 mfc0 $t3, $epc 308 253 mfc0 $t2, $status 309 sw $t3, ISTATE_OFFSET_EPC($sp) /* save EPC */310 sw $k1, ISTATE_OFFSET_KT1($sp)/* save $k1 not saved on context switch */254 sw $t3, SS_EPC($sp) /* save EPC */ 255 sw $k1, SS_K1($sp) /* save $k1 not saved on context switch */ 311 256 312 257 and $t4, $t2, REG_SAVE_MASK /* save only KSU, EXL, ERL, IE */ … … 315 260 ori $t2, $t2, 0x1 /* set IE */ 316 261 317 sw $t4, ISTATE_OFFSET_STATUS($sp)262 sw $t4, SS_STATUS($sp) 318 263 mtc0 $t2, $status 319 264 320 265 /* 321 266 * Call the higher level system call handler. 267 * We are going to reuse part of the unused exception stack frame. 322 268 * 323 269 */ 324 sw $t0, ISTATE_OFFSET_T0($sp) /* save the 5th argument on the stack */325 sw $t1, ISTATE_OFFSET_T1($sp) /* save the 6th argument on the stack */270 sw $t0, STACK_ARG4($sp) /* save the 5th argument on the stack */ 271 sw $t1, STACK_ARG5($sp) /* save the 6th argument on the stack */ 326 272 jal syscall_handler 327 sw $v0, ISTATE_OFFSET_V0($sp) /* save the syscall number on the stack */273 sw $v0, STACK_ARG6($sp) /* save the syscall number on the stack */ 328 274 329 275 /* restore status */ 330 276 mfc0 $t2, $status 331 lw $t3, ISTATE_OFFSET_STATUS($sp)277 lw $t3, SS_STATUS($sp) 332 278 333 279 /* … … 342 288 343 289 /* restore epc + 4 */ 344 lw $t2, ISTATE_OFFSET_EPC($sp)345 lw $k1, ISTATE_OFFSET_KT1($sp)290 lw $t2, SS_EPC($sp) 291 lw $k1, SS_K1($sp) 346 292 addi $t2, $t2, 4 347 293 mtc0 $t2, $epc 348 294 349 lw $sp, ISTATE_OFFSET_SP($sp) /* restore $sp */ 350 eret 351 352 FAKE_ABI_PROLOGUE 295 lw $sp, SS_SP($sp) /* restore $sp */ 296 eret 297 353 298 tlb_refill_handler: 354 299 KERNEL_STACK_TO_K0 355 sub $k0, ISTATE_SOFT_SIZE300 sub $k0, REGISTER_SPACE 356 301 REGISTERS_STORE_AND_EXC_RESET $k0 357 sw $sp, ISTATE_OFFSET_SP($k0)358 move $sp, $k0302 sw $sp,EOFFSET_SP($k0) 303 add $sp, $k0, 0 359 304 360 305 jal tlb_refill 361 move $a0, $sp306 add $a0, $sp, 0 362 307 363 308 REGISTERS_LOAD $sp 364 309 eret 365 310 366 FAKE_ABI_PROLOGUE367 311 cache_error_handler: 368 312 KERNEL_STACK_TO_K0 369 sub $k0, ISTATE_SOFT_SIZE313 sub $k0, REGISTER_SPACE 370 314 REGISTERS_STORE_AND_EXC_RESET $k0 371 sw $sp, ISTATE_OFFSET_SP($k0)372 move $sp, $k0315 sw $sp,EOFFSET_SP($k0) 316 add $sp, $k0, 0 373 317 374 318 jal cache_error 375 move $a0, $sp319 add $a0, $sp, 0 376 320 377 321 REGISTERS_LOAD $sp … … 379 323 380 324 userspace_asm: 381 move $sp, $a0382 move $v0, $a1383 move $t9, $a2/* set up correct entry into PIC code */325 add $sp, $a0, 0 326 add $v0, $a1, 0 327 add $t9, $a2, 0 /* set up correct entry into PIC code */ 384 328 xor $a0, $a0, $a0 /* $a0 is defined to hold pcb_ptr */ 385 329 /* set it to 0 */
Note:
See TracChangeset
for help on using the changeset viewer.