Changeset 406 for trunk/hal/tsar_mips32/core/hal_exception.c
- Timestamp:
- Aug 29, 2017, 12:03:37 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/tsar_mips32/core/hal_exception.c
r401 r406 24 24 #include <hal_types.h> 25 25 #include <hal_irqmask.h> 26 #include <hal_special.h> 26 27 #include <hal_exception.h> 27 28 #include <thread.h> … … 35 36 #include <syscalls.h> 36 37 #include <remote_spinlock.h> 37 #include < mips32_uzone.h>38 #include <hal_kentry.h> 38 39 39 40 … … 57 58 58 59 ////////////////////////////////////////////////////////////////////////////////////////// 59 // This enum defines the relevant subtypes for a MMU exceptionreported by the mips32.60 // This enum defines the mask valuesi for an MMU exception code reported by the mips32. 60 61 ////////////////////////////////////////////////////////////////////////////////////////// 61 62 62 63 typedef enum 63 64 { 64 MMU_EXCP_PAGE_UNMAPPED ,65 MMU_EXCP_USER_PRIVILEGE ,66 MMU_EXCP_USER_ EXEC,67 MMU_EXCP_USER_ WRITE,65 MMU_EXCP_PAGE_UNMAPPED = 0x0003, 66 MMU_EXCP_USER_PRIVILEGE = 0x0004, 67 MMU_EXCP_USER_WRITE = 0x0008, 68 MMU_EXCP_USER_EXEC = 0x1010, 68 69 } 69 70 mmu_exception_subtype_t; … … 86 87 87 88 ////////////////////////////////////////////////////////////////////////////////////////// 88 // This staticfunction is called when a FPU Coprocessor Unavailable exception has been89 // This function is called when a FPU Coprocessor Unavailable exception has been 89 90 // detected for the calling thread. 90 91 // It enables the FPU, It saves the current FPU context in the current owner thread … … 94 95 // @ return always EXCP_NON_FATAL 95 96 ////////////////////////////////////////////////////////////////////////////////////////// 96 staticerror_t hal_fpu_exception( thread_t * this )97 error_t hal_fpu_exception( thread_t * this ) 97 98 { 98 99 core_t * core = this->core; … … 119 120 120 121 ////////////////////////////////////////////////////////////////////////////////////////// 121 // This staticfunction is called when an MMU exception has been detected.122 // This function is called when an MMU exception has been detected. 122 123 // It get the relevant exception arguments from the MMU. 123 124 // It signal a fatal error in case of illegal access. In case of page unmapped … … 128 129 ////////////////////////////////////////////////////////////////////////////////////////// 129 130 // @ this : pointer on faulty thread descriptor. 131 // @ is_ins : IBE if true / DBE if false. 130 132 // @ return EXCP_NON_FATAL / EXCP_USER_ERROR / EXCP_KERNEL_PANIC 131 133 ////////////////////////////////////////////////////////////////////////////////////////// 132 static error_t hal_mmu_exception( thread_t * this ) 133 { 134 process_t * process; // local process descriptor 135 error_t error; // return value 136 137 reg_t mmu_ins_excp_code; 138 reg_t mmu_ins_bad_vaddr; 139 reg_t mmu_dat_excp_code; 140 reg_t mmu_dat_bad_vaddr; 141 142 intptr_t bad_vaddr; 134 error_t hal_mmu_exception( thread_t * this, 135 bool_t is_ins ) 136 { 137 process_t * process; 138 error_t error; 139 140 uint32_t mmu_ins_excp_code; 141 uint32_t mmu_ins_bad_vaddr; 142 uint32_t mmu_dat_excp_code; 143 uint32_t mmu_dat_bad_vaddr; 144 145 uint32_t bad_vaddr; 143 146 uint32_t excp_code; 144 147 145 process = this->process; 148 process = this->process; 149 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 ); 146 152 147 153 // get relevant values from MMU … … 151 157 &mmu_dat_bad_vaddr ); 152 158 153 // get exception code and faulty vaddr 154 if( mmu_ins_excp_code ) 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 // get exception code and faulty vaddr, depending on IBE/DBE 164 if( is_ins ) 155 165 { 156 166 excp_code = mmu_ins_excp_code; 157 167 bad_vaddr = mmu_ins_bad_vaddr; 158 168 } 159 else if( mmu_dat_excp_code )169 else 160 170 { 161 171 excp_code = mmu_dat_excp_code; 162 172 bad_vaddr = mmu_dat_bad_vaddr; 163 173 } 164 else 165 { 166 return EXCP_NON_FATAL; 167 } 168 169 vmm_dmsg("\n[INFO] %s : enters for thread %x / process %x" 170 " / bad_vaddr = %x / excep_code = %x\n", 171 __FUNCTION__, this->trdid , process->pid , bad_vaddr , excp_code ); 172 173 // on TSAR, a kernel thread should not rise an MMU exception 174 assert( (this->type != THREAD_USER) , __FUNCTION__ , 175 "thread %x is a kernel thread / vaddr = %x\n", this->trdid , bad_vaddr ); 176 174 175 excp_dmsg("\n[DMSG] %s : excp_code = %x / bad_vaddr = %x\n", 176 __FUNCTION__ , excp_code , bad_vaddr ); 177 177 178 // analyse exception code 178 179 if( excp_code & MMU_EXCP_PAGE_UNMAPPED ) 179 180 { 181 excp_dmsg("\n[DMSG] %s : type PAGE_UNMAPPED\n", __FUNCTION__ ); 182 180 183 // enable IRQs before handling page fault 181 hal_enable_irq( NULL );184 // hal_enable_irq( NULL ); 182 185 183 186 // try to map the unmapped PTE … … 185 188 bad_vaddr >> CONFIG_PPM_PAGE_SHIFT ); // vpn 186 189 // disable IRQs 187 hal_disable_irq( NULL );190 // hal_disable_irq( NULL ); 188 191 189 192 if( error ) // not enough memory 190 193 { 191 printk("\n[ERROR] in %s for thread %x : cannot map legalvaddr = %x\n",194 printk("\n[ERROR] in %s for thread %x : cannot map vaddr = %x\n", 192 195 __FUNCTION__ , this->trdid , bad_vaddr ); 193 196 … … 196 199 else // page fault successfully handled 197 200 { 198 vmm_dmsg("\n[INFO] %s : page fault handled for vaddr = %x in thread%x\n",199 __FUNCTION__ , bad_vaddr , this->trdid);201 excp_dmsg("\n[DMSG] %s : page fault handled / bad_vaddr = %x / excp_code = %x\n", 202 __FUNCTION__ , bad_vaddr , excp_code ); 200 203 201 204 return EXCP_NON_FATAL; … … 223 226 return EXCP_USER_ERROR; 224 227 } 225 226 228 else // this is a kernel error => panic 227 229 { … … 309 311 excCode = (regs_tbl[UZ_CR] >> 2) & 0xF; 310 312 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() ); 315 311 316 switch(excCode) 312 317 { 313 318 case XCODE_DBE: // can be non fatal 319 { 320 error = hal_mmu_exception( this , false ); // data MMU exception 321 break; 322 } 314 323 case XCODE_IBE: // can be non fatal 315 324 { 316 error = hal_mmu_exception( this ); 317 } 318 break; 319 325 error = hal_mmu_exception( this , true ); // ins MMU exception 326 break; 327 } 320 328 case XCODE_CPU: // can be non fatal 321 329 { … … 328 336 error = EXCP_USER_ERROR; 329 337 } 330 } 331 break; 332 338 break; 339 } 333 340 case XCODE_OVR: // user fatal error 334 341 case XCODE_RI: // user fatal error … … 337 344 { 338 345 error = EXCP_USER_ERROR; 339 } 340 break; 341 346 break; 347 } 342 348 default: 343 349 { … … 357 363 hal_core_sleep(); 358 364 } 365 366 excp_dmsg("\n[DMSG] %s : exit for thread %x in process %x / cycle %d\n", 367 __FUNCTION__ , this->trdid , this->process->pid , hal_time_stamp() ); 368 359 369 } // end hal_do_exception() 360 370
Note: See TracChangeset
for help on using the changeset viewer.