Changeset 369 for trunk/kernel
- Timestamp:
- Aug 14, 2017, 12:36:52 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/do_exception.c
r325 r369 1 1 /* 2 2 * do_exception.c - architecture independant exception handler implementation. 3 * 3 * 4 4 * Author Alain Greiner (2016) 5 5 * … … 45 45 46 46 ///////////////////////////////////////////////////////////////////////////////////////// 47 // This remote_spinlock is a kernel global variable defined in all clusters. 47 // This remote_spinlock is a kernel global variable defined in all clusters. 48 48 // It must be used by the architecture-specific exception handlers to display 49 49 // error messages on the kernel terminal. Only the spinlock in the I/O cluster is used. … … 55 55 ////////////////////////////////////////////////////////////////////////////////////////// 56 56 // This static function is called by the generic do_exception() handler when an MMU 57 // exception has been detected. 57 // exception has been detected. 58 58 // It get the relevant exception arguments from the MMU. 59 59 // It signal a fatal error in case of illegal access. In case of page fault, … … 66 66 // @ return EXCP_NON_FATAL / EXCP_USER_ERROR / EXCP_KERNEL_PANIC 67 67 ////////////////////////////////////////////////////////////////////////////////////////// 68 static error_t mmu_exception( thread_t * this ) 68 static error_t mmu_exception( thread_t * this ) 69 69 { 70 71 70 vseg_t * vseg; // vseg containing the bad_vaddr 71 process_t * process; // local process descriptor 72 72 error_t error; // return value 73 73 … … 79 79 intptr_t bad_vaddr; 80 80 uint32_t excp_code; 81 81 82 82 process = this->process; 83 83 84 84 // get relevant values from MMU 85 86 87 &mmu_dat_excp_code, 88 85 hal_get_mmu_excp( &mmu_ins_excp_code, 86 &mmu_ins_bad_vaddr, 87 &mmu_dat_excp_code, 88 &mmu_dat_bad_vaddr ); 89 89 90 90 // get exception code and faulty vaddr … … 104 104 } 105 105 106 107 " / bad_vaddr = %x / excep_code = %x\n", 108 106 vmm_dmsg("\n[INFO] %s : enters for thread %x / process %x" 107 " / bad_vaddr = %x / excep_code = %x\n", 108 __FUNCTION__, this->trdid , process->pid , bad_vaddr , excp_code ); 109 109 110 110 // a kernel thread should not rise an MMU exception 111 112 113 114 115 116 117 118 // enable IRQs 119 111 if( this->type != THREAD_USER ) 112 { 113 printk("\n[PANIC] in %s : thread %x is a kernel thread / vaddr = %x\n", 114 __FUNCTION__ , this->trdid , bad_vaddr ); 115 return EXCP_KERNEL_PANIC; 116 } 117 118 // enable IRQs 119 hal_enable_irq( NULL ); 120 120 121 121 // vaddr must be contained in a registered vseg … … 123 123 124 124 if( vseg == NULL ) // vseg not found in local cluster 125 125 { 126 126 // get extended pointer on reference process 127 127 xptr_t ref_xp = process->ref_xp; 128 128 129 // get cluster and local pointer on reference process 129 // get cluster and local pointer on reference process 130 130 cxy_t ref_cxy = GET_CXY( ref_xp ); 131 131 process_t * ref_ptr = (process_t *)GET_PTR( ref_xp ); … … 136 136 xptr_t vseg_xp; 137 137 rpc_vmm_get_ref_vseg_client( ref_cxy , ref_ptr , bad_vaddr , &vseg_xp ); 138 139 140 if( vseg == NULL ) // vseg not found => illegal user vaddr 138 139 if( vseg == NULL ) // vseg not found => illegal user vaddr 141 140 { 142 141 printk("\n[ERROR] in %s for thread %x : illegal vaddr = %x\n", … … 144 143 145 144 hal_disable_irq( NULL ); 146 145 return EXCP_USER_ERROR; 147 146 } 148 147 else // vseg found => make a local copy … … 153 152 if( vseg == NULL ) 154 153 { 155 156 154 printk("\n[PANIC] in %s : no memory for vseg / thread = %x\n", 155 __FUNCTION__ , this->trdid ); 157 156 hal_disable_irq( NULL ); 158 157 return EXCP_KERNEL_PANIC; 159 158 } 160 159 … … 172 171 173 172 hal_disable_irq( NULL ); 174 175 } 176 } 177 178 vmm_dmsg("\n[INFO] %s : found vseg for thread %x / vseg_min = %x / vseg_max = %x\n", 179 173 return EXCP_USER_ERROR; 174 } 175 } 176 177 vmm_dmsg("\n[INFO] %s : found vseg for thread %x / vseg_min = %x / vseg_max = %x\n", 178 __FUNCTION__ , this->trdid , vseg->min , vseg->max ); 180 179 181 180 // analyse exception code … … 183 182 { 184 183 // try to map the unmapped PTE 185 error = vmm_handle_page_fault( process, 184 error = vmm_handle_page_fault( process, 186 185 vseg, 187 186 bad_vaddr >> CONFIG_PPM_PAGE_SHIFT ); // vpn … … 193 192 194 193 hal_disable_irq( NULL ); 195 194 return EXCP_KERNEL_PANIC; 196 195 } 197 196 else 198 197 { 199 198 vmm_dmsg("\n[INFO] %s : page fault handled for vaddr = %x in thread %x\n", 200 201 199 __FUNCTION__ , bad_vaddr , this->trdid ); 200 202 201 // page fault successfully handled 203 202 hal_disable_irq( NULL ); 204 203 205 204 // TODO Pourquoi ce yield ? [AG] 206 // sched_yield(); 205 // sched_yield(); 207 206 208 207 return EXCP_NON_FATAL; … … 234 233 } 235 234 236 else // this is a kernel error => panic 235 else // this is a kernel error => panic 237 236 { 238 237 printk("\n[PANIC] in %s for thread %x : kernel exception = %x / vaddr = %x\n", … … 242 241 return EXCP_KERNEL_PANIC; 243 242 } 244 243 245 244 } // end mmu_exception_handler() 246 245 247 246 ////////////////////////////////////////////////////////////////////////////////////////// 248 // This static function is called by the generic do_exception() handler when a 249 // FPU Coprocessor Unavailable exception has been detected by the calling thread. 250 // It enables the FPU, It saves the current FPU context in the current owner thread 247 // This static function is called by the generic do_exception() handler when a 248 // FPU Coprocessor Unavailable exception has been detected by the calling thread. 249 // It enables the FPU, It saves the current FPU context in the current owner thread 251 250 // descriptor if required, and restore the FPU context from the calling thread descriptor. 252 251 ////////////////////////////////////////////////////////////////////////////////////////// … … 256 255 static error_t fpu_exception( thread_t * this ) 257 256 { 258 core_t * core = this->core; 259 260 // enable FPU 261 262 263 // save FPU context in current owner thread if required 264 257 core_t * core = this->core; 258 259 // enable FPU 260 hal_fpu_enable(); 261 262 // save FPU context in current owner thread if required 263 if( core->fpu_owner != NULL ) 265 264 { 266 265 if( core->fpu_owner != this ) 267 268 269 } 270 266 { 267 hal_fpu_context_save ( core->fpu_owner->fpu_context ); 268 } 269 } 271 270 272 271 // attach the FPU to the requesting thread 273 274 275 276 272 hal_fpu_context_restore( this->fpu_context ); 273 core->fpu_owner = this; 274 275 return EXCP_NON_FATAL; 277 276 } 278 277 … … 284 283 error_t error; 285 284 286 // update user time 287 285 // update user time 286 thread_user_time_update( this ); 288 287 289 288 // try to handle non fatal exception 290 289 if( is_mmu ) error = mmu_exception( this ); 291 290 else error = fpu_exception( this ); 292 291 293 292 // handle pending signals for interrupted thread 294 293 thread_signals_handle( this ); 295 294 296 297 295 // update kernel time 296 thread_kernel_time_update( this ); 298 297 299 298 return error;
Note: See TracChangeset
for help on using the changeset viewer.