Changeset 407 for trunk/hal/tsar_mips32/core/hal_exception.c
- Timestamp:
- Nov 7, 2017, 3:08:12 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/tsar_mips32/core/hal_exception.c
r406 r407 58 58 59 59 ////////////////////////////////////////////////////////////////////////////////////////// 60 // This enum defines the mask values ifor an MMU exception code reported by the mips32.60 // This enum defines the mask values for an MMU exception code reported by the mips32. 61 61 ////////////////////////////////////////////////////////////////////////////////////////// 62 62 63 63 typedef enum 64 64 { 65 MMU_EXCP_PAGE_UNMAPPED = 0x0003, 66 MMU_EXCP_USER_PRIVILEGE = 0x0004, 67 MMU_EXCP_USER_WRITE = 0x0008, 68 MMU_EXCP_USER_EXEC = 0x1010, 65 MMU_WRITE_PT1_UNMAPPED = 0x0001, 66 MMU_WRITE_PT2_UNMAPPED = 0x0002, 67 MMU_WRITE_PRIVILEGE_VIOLATION = 0x0004, 68 MMU_WRITE_ACCESS_VIOLATION = 0x0008, 69 MMU_WRITE_UNDEFINED_XTN = 0x0020, 70 MMU_WRITE_PT1_ILLEGAL_ACCESS = 0x0040, 71 MMU_WRITE_PT2_ILLEGAL_ACCESS = 0x0080, 72 MMU_WRITE_DATA_ILLEGAL_ACCESS = 0x0100, 73 74 MMU_READ_PT1_UNMAPPED = 0x1001, 75 MMU_READ_PT2_UNMAPPED = 0x1002, 76 MMU_READ_PRIVILEGE_VIOLATION = 0x1004, 77 MMU_READ_EXEC_VIOLATION = 0x1010, 78 MMU_READ_UNDEFINED_XTN = 0x1020, 79 MMU_READ_PT1_ILLEGAL_ACCESS = 0x1040, 80 MMU_READ_PT2_ILLEGAL_ACCESS = 0x1080, 81 MMU_READ_DATA_ILLEGAL_ACCESS = 0x1100, 69 82 } 70 83 mmu_exception_subtype_t; … … 148 161 process = this->process; 149 162 150 excp_dmsg("\n[DMSG] %s : enter for thread %x in process %x / is_ins = %d\n",151 __FUNCTION__ , this->trdid , process->pid , is_ins );152 153 163 // get relevant values from MMU 154 164 hal_get_mmu_excp( &mmu_ins_excp_code, … … 157 167 &mmu_dat_bad_vaddr ); 158 168 159 excp_dmsg("\n[DMSG] %s : icode = %x / ivaddr = %x / dcode = %x / dvaddr = %x\n",160 __FUNCTION__ , mmu_ins_excp_code , mmu_ins_bad_vaddr ,161 mmu_dat_excp_code , mmu_dat_bad_vaddr );162 163 169 // get exception code and faulty vaddr, depending on IBE/DBE 164 170 if( is_ins ) … … 173 179 } 174 180 175 excp_dmsg("\n[DMSG] %s : excp_code = %x / bad_vaddr = %x\n", 176 __FUNCTION__ , excp_code , bad_vaddr ); 177 178 // analyse exception code 179 if( excp_code & MMU_EXCP_PAGE_UNMAPPED ) 180 { 181 excp_dmsg("\n[DMSG] %s : type PAGE_UNMAPPED\n", __FUNCTION__ ); 182 183 // enable IRQs before handling page fault 184 // hal_enable_irq( NULL ); 185 186 // try to map the unmapped PTE 187 error = vmm_handle_page_fault( process, 188 bad_vaddr >> CONFIG_PPM_PAGE_SHIFT ); // vpn 189 // disable IRQs 190 // hal_disable_irq( NULL ); 191 192 if( error ) // not enough memory 193 { 194 printk("\n[ERROR] in %s for thread %x : cannot map vaddr = %x\n", 195 __FUNCTION__ , this->trdid , bad_vaddr ); 196 197 return EXCP_USER_ERROR; 198 } 199 else // page fault successfully handled 200 { 201 excp_dmsg("\n[DMSG] %s : page fault handled / bad_vaddr = %x / excp_code = %x\n", 202 __FUNCTION__ , bad_vaddr , excp_code ); 181 excp_dmsg("\n[DBG] %s : core[%x,%d] / is_ins %d / code %x / vaddr %x\n", 182 __FUNCTION__ , local_cxy , this->core->lid , is_ins, excp_code, bad_vaddr ); 183 184 // analyse exception code 185 switch( excp_code ) 186 { 187 case MMU_WRITE_PT1_UNMAPPED: // non fatal 188 case MMU_WRITE_PT2_UNMAPPED: 189 case MMU_READ_PT1_UNMAPPED: 190 case MMU_READ_PT2_UNMAPPED: 191 { 192 // try to map the unmapped PTE 193 error = vmm_handle_page_fault( process, 194 bad_vaddr >> CONFIG_PPM_PAGE_SHIFT ); // vpn 195 if( error ) 196 { 197 printk("\n[ERROR] in %s for thread %x : cannot map vaddr = %x\n", 198 __FUNCTION__ , this->trdid , bad_vaddr ); 199 200 return EXCP_USER_ERROR; 201 } 202 else // page fault successfull 203 { 204 205 excp_dmsg("\n[DBG] %s : core[%x,%d] / page-fault handled for vaddr = %x\n", 206 __FUNCTION__ , local_cxy , this->core->lid , bad_vaddr ); 203 207 204 return EXCP_NON_FATAL; 205 } 206 } 207 else if( excp_code & MMU_EXCP_USER_PRIVILEGE ) 208 { 209 printk("\n[ERROR] in %s for thread %x : user access to kernel vseg at vaddr = %x\n", 210 __FUNCTION__ , this->trdid , bad_vaddr ); 211 212 return EXCP_USER_ERROR; 213 } 214 else if( excp_code & MMU_EXCP_USER_EXEC ) 215 { 216 printk("\n[ERROR] in %s for thread %x : access to non-exec vseg at vaddr = %x\n", 217 __FUNCTION__ , this->trdid , bad_vaddr ); 218 219 return EXCP_USER_ERROR; 220 } 221 else if( excp_code & MMU_EXCP_USER_WRITE ) 222 { 223 printk("\n[ERROR] in %s for thread %x : write to non-writable vseg at vaddr = %x\n", 224 __FUNCTION__ , this->trdid , bad_vaddr ); 225 226 return EXCP_USER_ERROR; 227 } 228 else // this is a kernel error => panic 229 { 230 printk("\n[PANIC] in %s for thread %x : kernel exception = %x / vaddr = %x\n", 231 __FUNCTION__ , this->trdid , excp_code , bad_vaddr ); 232 233 return EXCP_KERNEL_PANIC; 234 } 235 208 return EXCP_NON_FATAL; 209 } 210 } 211 case MMU_WRITE_PRIVILEGE_VIOLATION: // illegal access user error 212 case MMU_READ_PRIVILEGE_VIOLATION: 213 { 214 printk("\n[ERROR] in %s for thread %x : illegal user access to vaddr = %x\n", 215 __FUNCTION__ , this->trdid , bad_vaddr ); 216 217 return EXCP_USER_ERROR; 218 } 219 case MMU_WRITE_ACCESS_VIOLATION: // user error or Copy-on-Write 220 { 221 // access page table to get GPT_COW flag 222 bool_t cow = hal_gpt_pte_is_cow( &(process->vmm.gpt), 223 bad_vaddr >> CONFIG_PPM_PAGE_SHIFT ); // vpn 224 225 if( cow ) // Copy-on-Write 226 { 227 // try to allocate and copy the page 228 error = vmm_copy_on_write( process, 229 bad_vaddr >> CONFIG_PPM_PAGE_SHIFT ); // vpn 230 if( error ) 231 { 232 printk("\n[ERROR] in %s for thread %x : cannot cow vaddr = %x\n", 233 __FUNCTION__ , this->trdid , bad_vaddr ); 234 235 return EXCP_USER_ERROR; 236 } 237 else // Copy on write successfull 238 { 239 240 excp_dmsg("\n[DBG] %s : core[%x,%d] / copy-on-write handled for vaddr = %x\n", 241 __FUNCTION__ , local_cxy , this->core->lid , bad_vaddr ); 242 243 return EXCP_NON_FATAL; 244 } 245 } 246 else // non writable user error 247 { 248 printk("\n[ERROR] in %s for thread %x : write to non-writable vaddr = %x\n", 249 __FUNCTION__ , this->trdid , bad_vaddr ); 250 251 return EXCP_USER_ERROR; 252 } 253 } 254 case MMU_READ_EXEC_VIOLATION: // user error 255 { 256 printk("\n[ERROR] in %s for thread %x : read to non-executable vaddr = %x\n", 257 __FUNCTION__ , this->trdid , bad_vaddr ); 258 259 return EXCP_USER_ERROR; 260 } 261 default: // this is a kernel error => panic 262 { 263 printk("\n[PANIC] in %s for thread %x : kernel exception = %x / vaddr = %x\n", 264 __FUNCTION__ , this->trdid , excp_code , bad_vaddr ); 265 266 return EXCP_KERNEL_PANIC; 267 } 268 } 236 269 } // end hal_mmu_exception() 237 270 … … 242 275 // @ this : pointer on faulty thread descriptor. 243 276 // @ regs_tbl : pointer on register array. 244 // @ return always EXCP_NON_FATAL277 // @ error : EXCP_USER_ERROR or EXCP_KERNEL_PANIC 245 278 ////////////////////////////////////////////////////////////////////////////////////////// 246 279 static void hal_exception_dump( thread_t * this, 247 reg_t * regs_tbl ) 280 reg_t * regs_tbl, 281 error_t error ) 248 282 { 249 283 uint32_t save_sr; 284 core_t * core = this->core; 250 285 251 286 // get pointers on TXT0 chdev 252 xptr_t txt0_xp = chdev_dir.txt [0];287 xptr_t txt0_xp = chdev_dir.txt_tx[0]; 253 288 cxy_t txt0_cxy = GET_CXY( txt0_xp ); 254 289 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); … … 260 295 remote_spinlock_lock_busy( lock_xp , &save_sr ); 261 296 262 if( this->type == THREAD_USER ) 263 nolock_printk("\n================= USER ERROR / cycle %d ====================\n", 264 hal_time_stamp() ); 297 if( error == EXCP_USER_ERROR ) 298 { 299 nolock_printk("\n========= USER ERROR / core[%x,%d] / cycle %d ==============\n", 300 local_cxy , core->lid , (uint32_t)hal_get_cycles() ); 301 } 265 302 else 266 nolock_printk("\n================= KERNEL PANIC / cycle %d ==================\n", 267 hal_time_stamp() ); 303 { 304 nolock_printk("\n======= KERNEL PANIC / core[%x,%d] / cycle %d ==============\n", 305 local_cxy , core->lid , (uint32_t)hal_get_cycles() ); 306 } 268 307 269 308 nolock_printk(" thread type = %s / trdid = %x / pid %x / core[%x,%d]\n" … … 272 311 this->core->lid, this->local_locks, this->remote_locks, this->blocked ); 273 312 274 nolock_printk(" CR %X EPC %X SR %X SP%X\n",275 regs_tbl[UZ_CR], regs_tbl[UZ_EPC], regs_tbl[UZ_SR], regs_tbl[UZ_ SP]);276 277 nolock_printk("at_ 1%X v0_2 %X v1_3 %X a0_4 %X a1_5 %X\n",278 regs_tbl[UZ_AT], regs_tbl[UZ_V0], regs_tbl[UZ_V1], regs_tbl[UZ_A0],regs_tbl[UZ_A1]);313 nolock_printk("cp0_cr %X cp0_epc %X cp0_sr %X cp2_mode %X\n", 314 regs_tbl[UZ_CR], regs_tbl[UZ_EPC], regs_tbl[UZ_SR], regs_tbl[UZ_MODE]); 315 316 nolock_printk("at_01 %X v0_2 %X v1_3 %X a0_4 %X a1_5 %X\n", 317 regs_tbl[UZ_AT],regs_tbl[UZ_V0],regs_tbl[UZ_V1],regs_tbl[UZ_A0],regs_tbl[UZ_A1]); 279 318 280 319 nolock_printk("a2_6 %X a3_7 %X t0_8 %X t1_9 %X t2_10 %X\n", … … 284 323 regs_tbl[UZ_T3],regs_tbl[UZ_T4],regs_tbl[UZ_T5],regs_tbl[UZ_T6],regs_tbl[UZ_T7]); 285 324 286 nolock_printk("t8_24 %X t9_25 %X gp_28 %X c0_hi %X c0_lo %X\n",287 regs_tbl[UZ_T8],regs_tbl[UZ_T9],regs_tbl[UZ_GP],regs_tbl[UZ_HI],regs_tbl[UZ_LO]);288 289 325 nolock_printk("s0_16 %X s1_17 %X s2_18 %X s3_19 %X s4_20 %X\n", 290 326 regs_tbl[UZ_S0],regs_tbl[UZ_S1],regs_tbl[UZ_S2],regs_tbl[UZ_S3],regs_tbl[UZ_S4]); 291 327 292 nolock_printk("s5_21 %X s6_22 %X s7_23 %X s8_30 %X ra_31 %X\n", 293 regs_tbl[UZ_S5],regs_tbl[UZ_S6],regs_tbl[UZ_S7],regs_tbl[UZ_S8],regs_tbl[UZ_RA]); 328 nolock_printk("s5_21 %X s6_22 %X s7_23 %X s8_24 %X ra_25 %X\n", 329 regs_tbl[UZ_S5],regs_tbl[UZ_S6],regs_tbl[UZ_S7],regs_tbl[UZ_T8],regs_tbl[UZ_T9]); 330 331 nolock_printk("gp_28 %X sp_29 %X S8_30 %X ra_31 %X\n", 332 regs_tbl[UZ_GP],regs_tbl[UZ_SP],regs_tbl[UZ_S8],regs_tbl[UZ_RA]); 294 333 295 334 // release the lock … … 311 350 excCode = (regs_tbl[UZ_CR] >> 2) & 0xF; 312 351 313 excp_dmsg("\n[DMSG] %s : enter for thread %x in process %x / xcode = %x / cycle %d\n", 314 __FUNCTION__ , this->trdid , this->process->pid , excCode , hal_time_stamp() ); 352 excp_dmsg("\n[DBG] %s : core[%x,%d] / thread %x in process %x / xcode %x / cycle %d\n", 353 __FUNCTION__, local_cxy, this->core->lid, this->trdid, 354 this->process->pid, excCode, (uint32_t)hal_get_cycle() ); 315 355 316 356 switch(excCode) … … 355 395 if( error == EXCP_USER_ERROR ) // user error => kill user process 356 396 { 357 hal_exception_dump( this , regs_tbl ); 358 sys_kill( this->process->pid , SIGKILL ); 397 hal_exception_dump( this , regs_tbl , error ); 398 399 // FIXME : replace this loop by sys_kill() 400 while( 1 ) asm volatile ("nop"); 401 // sys_kill( this->process->pid , SIGKILL ); 359 402 } 360 403 else if( error == EXCP_KERNEL_PANIC ) // kernel error => kernel panic 361 404 { 362 hal_exception_dump( this , regs_tbl );405 hal_exception_dump( this , regs_tbl , error ); 363 406 hal_core_sleep(); 364 407 } 365 408 366 excp_dmsg("\n[DMSG] %s : exit forthread %x in process %x / cycle %d\n",367 __FUNCTION__ , this->trdid , this->process->pid, hal_time_stamp() );409 excp_dmsg("\n[DBG] %s : core[%x,%d] exit / thread %x in process %x / cycle %d\n", 410 __FUNCTION__, local_cxy, this->core->lid, this->trdid, this->process->pid, hal_time_stamp() ); 368 411 369 412 } // end hal_do_exception()
Note: See TracChangeset
for help on using the changeset viewer.