source: trunk/hal/tsar_mips32/core/hal_exception.c @ 605

Last change on this file since 605 was 587, checked in by alain, 6 years ago

Modify the GPT (Generic Page Table) API to support remote accesses,
in order to improve page faults and COW handling.

File size: 19.7 KB
RevLine 
[16]1/*
2 * hal_exception.c - implementation of exception handler for TSAR-MIPS32.
3 *
4 * Author   Alain Greiner (2016, 2017)
5 *
6 * Copyright (c) UPMC Sorbonne Universites
7 *
8 * This file is part of ALMOS-MKH.
9 *
10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
14 * ALMOS-MKH is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
[457]24#include <hal_kernel_types.h>
[16]25#include <hal_irqmask.h>
[406]26#include <hal_special.h>
[16]27#include <hal_exception.h>
28#include <thread.h>
29#include <printk.h>
[380]30#include <chdev.h>
[16]31#include <vmm.h>
32#include <errno.h>
33#include <scheduler.h>
34#include <core.h>
35#include <syscalls.h>
[440]36#include <shared_syscalls.h>
[570]37#include <remote_busylock.h>
[406]38#include <hal_kentry.h>
[505]39#include <hal_exception.h>
[380]40
[16]41//////////////////////////////////////////////////////////////////////////////////////////
42//  Extern global variables
43//////////////////////////////////////////////////////////////////////////////////////////
44
[380]45extern   chdev_directory_t    chdev_dir;  // allocated in the kernel_init.c file.
[16]46
47//////////////////////////////////////////////////////////////////////////////////////////
[407]48// This enum defines the mask values for an MMU exception code reported by the mips32.
[381]49//////////////////////////////////////////////////////////////////////////////////////////
50
51typedef enum
52{
[407]53    MMU_WRITE_PT1_UNMAPPED        = 0x0001,
54    MMU_WRITE_PT2_UNMAPPED        = 0x0002,
55    MMU_WRITE_PRIVILEGE_VIOLATION = 0x0004,
56    MMU_WRITE_ACCESS_VIOLATION    = 0x0008,
57    MMU_WRITE_UNDEFINED_XTN       = 0x0020,
58    MMU_WRITE_PT1_ILLEGAL_ACCESS  = 0x0040,
59    MMU_WRITE_PT2_ILLEGAL_ACCESS  = 0x0080,
60    MMU_WRITE_DATA_ILLEGAL_ACCESS = 0x0100,
61
62    MMU_READ_PT1_UNMAPPED         = 0x1001,
63    MMU_READ_PT2_UNMAPPED         = 0x1002,
64    MMU_READ_PRIVILEGE_VIOLATION  = 0x1004,
65    MMU_READ_EXEC_VIOLATION       = 0x1010,
66    MMU_READ_UNDEFINED_XTN        = 0x1020,
67    MMU_READ_PT1_ILLEGAL_ACCESS   = 0x1040,
68    MMU_READ_PT2_ILLEGAL_ACCESS   = 0x1080,
69    MMU_READ_DATA_ILLEGAL_ACCESS  = 0x1100,
[381]70}
71mmu_exception_subtype_t;
72
73//////////////////////////////////////////////////////////////////////////////////////////
[16]74// This enum defines the relevant values for XCODE field in mips32 CP0_CR register.
75//////////////////////////////////////////////////////////////////////////////////////////
76
77typedef enum
78{
[296]79    XCODE_ADEL = 0x4,        // Illegal address for data load
80    XCODE_ADES = 0x5,        // Illegal address for data store
81    XCODE_IBE  = 0x6,        // Instruction MMU exception       (can be NON-FATAL)
82    XCODE_DBE  = 0x7,        // Data MMU exception              (can be NON-FATAL)
83    XCODE_RI   = 0xA,        // Reserved instruction exception
84    XCODE_CPU  = 0xB,        // Coprocessor unusable exception  (can be NON-FATAl)
85    XCODE_OVR  = 0xC,        // Arithmetic Overflow exception
[16]86}
87xcode_values_t;
88
[409]89/////////////////////////////////////////////
90char * hal_mmu_exception_str( uint32_t code )
[408]91{
[527]92  switch (code) {
93    case (MMU_WRITE_PT1_UNMAPPED):        return "WRITE_PT1_UNMAPPED";
94    case (MMU_WRITE_PT2_UNMAPPED):        return "WRITE_PT2_UNMAPPED";
95    case (MMU_WRITE_PRIVILEGE_VIOLATION): return "WRITE_PRIVILEGE_VIOLATION";
96    case (MMU_WRITE_ACCESS_VIOLATION):    return "WRITE_ACCESS_VIOLATION";
97    case (MMU_WRITE_UNDEFINED_XTN):       return "WRITE_UNDEFINED_XTN";
98    case (MMU_WRITE_PT1_ILLEGAL_ACCESS):  return "WRITE_PT1_ILLEGAL_ACCESS";
99    case (MMU_WRITE_PT2_ILLEGAL_ACCESS):  return "WRITE_PT2_ILLEGAL_ACCESS";
100    case (MMU_WRITE_DATA_ILLEGAL_ACCESS): return "WRITE_DATA_ILLEGAL_ACCESS";
101    case (MMU_READ_PT1_UNMAPPED):         return "READ_PT1_UNMAPPED";
102    case (MMU_READ_PT2_UNMAPPED):         return "READ_PT2_UNMAPPED";
103    case (MMU_READ_PRIVILEGE_VIOLATION):  return "READ_PRIVILEGE_VIOLATION";
104    case (MMU_READ_EXEC_VIOLATION):       return "READ_EXEC_VIOLATION";
105    case (MMU_READ_UNDEFINED_XTN):        return "READ_UNDEFINED_XTN";
106    case (MMU_READ_PT1_ILLEGAL_ACCESS):   return "READ_PT1_ILLEGAL_ACCESS";
107    case (MMU_READ_PT2_ILLEGAL_ACCESS):   return "READ_PT2_ILLEGAL_ACCESS";
108    case (MMU_READ_DATA_ILLEGAL_ACCESS):  return "READ_DATA_ILLEGAL_ACCESS";
109    default:                              return "undefined";
110  }
[408]111}
112
[380]113//////////////////////////////////////////////////////////////////////////////////////////
[406]114// This function is called when a FPU Coprocessor Unavailable exception has been
[380]115// detected for the calling thread.
116// It enables the FPU, It saves the current FPU context in the current owner thread
117// descriptor if required, and restore the FPU context from the calling thread descriptor.
118//////////////////////////////////////////////////////////////////////////////////////////
119// @ this     : pointer on faulty thread descriptor.
120// @ return always EXCP_NON_FATAL
121//////////////////////////////////////////////////////////////////////////////////////////
[406]122error_t hal_fpu_exception( thread_t * this )
[380]123{
124        core_t   * core = this->core; 
125
[457]126    // enable FPU (in core SR) 
[380]127        hal_fpu_enable();
128
[457]129    // save FPU register values in current owner thread if required
[380]130        if( core->fpu_owner != NULL )
131    {
132        if( core->fpu_owner != this )
133            {
[457]134            // save the FPU registers to current owner thread context
[408]135                    hal_fpu_context_save( XPTR( local_cxy , core->fpu_owner ) );
[457]136
137            // restore FPU registers from requesting thread context
[469]138                hal_fpu_context_restore( this );
[457]139
140            // attach the FPU to the requesting thread
141                core->fpu_owner = this;
[380]142        }
143        }
[457]144    else
145    {
146        // restore FPU registers from requesting thread context
[469]147            hal_fpu_context_restore( this );
[380]148
[457]149        // attach the FPU to the requesting thread
150            core->fpu_owner = this;
151    }
[380]152
153        return EXCP_NON_FATAL;
154
155}  // end hal_fpu_exception()
156
157//////////////////////////////////////////////////////////////////////////////////////////
[437]158// This function is called when an MMU exception has been detected (IBE / DBE).
[380]159// It get the relevant exception arguments from the MMU.
160// It signal a fatal error in case of illegal access. In case of page unmapped
161// it checks that the faulty address belongs to a registered vseg. It update the local
162// vseg list from the reference cluster if required, and signal a fatal user error
163// in case of illegal virtual address. Finally, it updates the local page table from the
164// reference cluster.
165//////////////////////////////////////////////////////////////////////////////////////////
166// @ this     : pointer on faulty thread descriptor.
[440]167// @ excPC    :
[406]168// @ is_ins   : IBE if true / DBE if false.
[380]169// @ return EXCP_NON_FATAL / EXCP_USER_ERROR / EXCP_KERNEL_PANIC
170//////////////////////////////////////////////////////////////////////////////////////////
[406]171error_t hal_mmu_exception( thread_t * this,
[437]172                           uint32_t   excPC,
[406]173                           bool_t     is_ins ) 
[380]174{
[406]175        process_t      * process;
176    error_t          error;
[380]177
[406]178    uint32_t         mmu_ins_excp_code;
179    uint32_t         mmu_ins_bad_vaddr;
180    uint32_t         mmu_dat_excp_code;
181    uint32_t         mmu_dat_bad_vaddr;
[380]182
[406]183    uint32_t         bad_vaddr;
[380]184    uint32_t         excp_code;
185       
[406]186    process = this->process;
[380]187
188    // get relevant values from MMU
189        hal_get_mmu_excp( &mmu_ins_excp_code,
190                          &mmu_ins_bad_vaddr,
191                          &mmu_dat_excp_code, 
192                          &mmu_dat_bad_vaddr );
193
[406]194    // get exception code and faulty vaddr, depending on IBE/DBE
195    if( is_ins )
[380]196    {
197        excp_code = mmu_ins_excp_code;
198        bad_vaddr = mmu_ins_bad_vaddr;
199    }
[406]200    else 
[380]201    {
202        excp_code = mmu_dat_excp_code;
203        bad_vaddr = mmu_dat_bad_vaddr;
204    }
205
[438]206#if DEBUG_HAL_EXCEPTIONS
[432]207uint32_t cycle = (uint32_t)hal_get_cycles();
[438]208if( DEBUG_HAL_EXCEPTIONS < cycle )
[587]209printk("\n[DBG] %s : thread[%x,%x] enter / is_ins %d / %s / vaddr %x / cycle %d\n",
210__FUNCTION__, process->pid, this->trdid,
[469]211is_ins, hal_mmu_exception_str(excp_code), bad_vaddr, cycle);
[432]212#endif
[408]213
[407]214   // analyse exception code
215    switch( excp_code )
[380]216    {
[407]217        case MMU_WRITE_PT1_UNMAPPED:      // non fatal
218        case MMU_WRITE_PT2_UNMAPPED:
219        case MMU_READ_PT1_UNMAPPED:
220        case MMU_READ_PT2_UNMAPPED:
221        {
222            // try to map the unmapped PTE
223            error = vmm_handle_page_fault( process, 
[587]224                                           bad_vaddr >> CONFIG_PPM_PAGE_SHIFT );
[406]225
[587]226            if( error == EXCP_NON_FATAL )            // page-fault successfully handled
[407]227            {
[391]228
[438]229#if DEBUG_HAL_EXCEPTIONS
[432]230cycle = (uint32_t)hal_get_cycles();
[438]231if( DEBUG_HAL_EXCEPTIONS < cycle )
[587]232printk("\n[DBG] %s : thread[%x,%x] exit / page-fault handled for vaddr = %x\n",
233__FUNCTION__, process->pid, this->trdid, bad_vaddr );
[432]234#endif
[407]235 
236                return EXCP_NON_FATAL;
237            }
[587]238            else if( error == EXCP_USER_ERROR )      // illegal vaddr
239            {
240                printk("\n[USER ERROR] in %s for thread %x in process %x\n"
241                "   illegal vaddr = %x / is_ins %d / epc %x\n",
242                __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
243
244                        return EXCP_USER_ERROR;
245            } 
246            else  // error == EXCP_KERNEL_PANIC 
247            {
248                printk("\n[KERNEL ERROR] in %s for thread %x in process %x\n"
249                "   no memory to map vaddr = %x / is_ins %d / epc %x\n",
250                __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
251
252                        return EXCP_KERNEL_PANIC;
253            } 
[407]254        }
255        case MMU_WRITE_PRIVILEGE_VIOLATION:  // illegal access user error
256        case MMU_READ_PRIVILEGE_VIOLATION:
[380]257        {
[587]258            printk("\n[USER ERROR] in %s : thread %x in process %x\n"
[469]259            "   illegal user access to vaddr = %x / is_ins %d / epc %x\n",
260            __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
[380]261
[407]262            return EXCP_USER_ERROR;
263        }
[408]264        case MMU_WRITE_ACCESS_VIOLATION:     // user error, or Copy-on-Write
[380]265        {
[407]266            // access page table to get GPT_COW flag
267            bool_t cow = hal_gpt_pte_is_cow( &(process->vmm.gpt),
[408]268                                             bad_vaddr >> CONFIG_PPM_PAGE_SHIFT ); 
[380]269
[407]270            if( cow )                        // Copy-on-Write
271            {
272                // try to allocate and copy the page
[587]273                error = vmm_handle_cow( process,
274                                        bad_vaddr >> CONFIG_PPM_PAGE_SHIFT );
[380]275
[587]276                if( error == EXCP_NON_FATAL )        // Copy on write successfull
[407]277                {
[380]278
[438]279#if DEBUG_HAL_EXCEPTIONS
[432]280cycle = (uint32_t)hal_get_cycles();
[438]281if( DEBUG_HAL_EXCEPTIONS < cycle )
[587]282printk("\n[DBG] %s : thread[%x,%x] exit / copy-on-write handled for vaddr = %x\n",
283__FUNCTION__, process->pid, this->trdid, bad_vaddr );
[432]284#endif
[380]285
[407]286                    return EXCP_NON_FATAL;
287                } 
[587]288                else if( error == EXCP_USER_ERROR )  // illegal user access
289                {
290                    printk("\n[USER ERROR] in %s : thread %x in process %x\n"
291                    "   cannot cow vaddr = %x / is_ins %d / epc %x\n",
292                    __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
293
294                            return EXCP_USER_ERROR;
295                }
296                else   // error == EXCP_KERNEL_PANIC
297                {
298                    printk("\n[KERNEL ERROR] in %s : thread %x in process %x\n"
299                    "   no memoty to cow vaddr = %x / is_ins %d / epc %x\n",
300                    __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
301
302                            return EXCP_USER_ERROR;
303                }
[407]304            }
305            else                             // non writable user error
306            {
[587]307                printk("\n[USER ERROR] in %s : thread %x in process %x\n"
[469]308                "   non-writable vaddr = %x / is_ins %d / epc %x\n",
309                __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
[407]310
311                return EXCP_USER_ERROR;
312            }
313        }
314        case MMU_READ_EXEC_VIOLATION:        // user error
315        {
[587]316            printk("\n[USER_ERROR] in %s : thread %x in process %x\n"
[469]317            "   non-executable vaddr = %x / is_ins %d / epc %x\n",
318            __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
[407]319
320            return EXCP_USER_ERROR;
321        }
[469]322        default:                             // this is a kernel error   
[407]323        {
[587]324            printk("\n[KERNEL ERROR] in %s : thread %x in process %x\n"
[469]325            "  epc %x / badvaddr %x / is_ins %d\n",
326            __FUNCTION__, this->trdid, this->process->pid, excPC, bad_vaddr, is_ins );
[407]327
328            return EXCP_KERNEL_PANIC;
329        }
330    } 
[380]331} // end hal_mmu_exception()
332
333//////////////////////////////////////////////////////////////////////////////////////////
334// This static function prints on the kernel terminal the saved context (core registers)
335// and the thread state of a faulty thread.
336//////////////////////////////////////////////////////////////////////////////////////////
337// @ this     : pointer on faulty thread descriptor.
[425]338// @ uzone    : pointer on register array.
[407]339// @ error    : EXCP_USER_ERROR or EXCP_KERNEL_PANIC
[380]340//////////////////////////////////////////////////////////////////////////////////////////
341static void hal_exception_dump( thread_t * this,
[408]342                                reg_t    * uzone,
[407]343                                error_t    error )
[380]344{
[408]345    core_t    * core    = this->core;
346    process_t * process = this->process;
[380]347
348    // get pointers on TXT0 chdev
[407]349    xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
[380]350    cxy_t     txt0_cxy = GET_CXY( txt0_xp );
351    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
352
353    // get extended pointer on remote TXT0 chdev lock
354    xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
355
356    // get TXT0 lock in busy waiting mode
[570]357    remote_busylock_acquire( lock_xp );
[380]358
[407]359    if( error == EXCP_USER_ERROR )
360    {
[408]361        nolock_printk("\n=== USER ERROR / trdid %x / pid %x / core[%x,%d] / cycle %d ===\n",
362        this->trdid, process->pid, local_cxy, core->lid , (uint32_t)hal_get_cycles() );
[407]363    }
[380]364    else
[407]365    {
[469]366        nolock_printk("\n=== KERNEL ERROR / trdid %x / pid %x / core[%x,%d] / cycle %d ===\n",
[408]367        this->trdid, process->pid, local_cxy, core->lid , (uint32_t)hal_get_cycles() );
[407]368    }
[380]369
[570]370        nolock_printk("busylocks = %d / blocked_vector = %X / flags = %X\n\n",
371    this->busylocks, this->blocked, this->flags );
[380]372
[408]373    nolock_printk("c0_cr   %X  c0_epc  %X  c0_sr  %X  c0_th  %X\n",
374    uzone[UZ_CR], uzone[UZ_EPC], uzone[UZ_SR], uzone[UZ_TH] );
[380]375
[408]376    nolock_printk("c2_mode %X  c2_ptpr %X\n",
377    uzone[UZ_MODE], uzone[UZ_PTPR] );
[380]378
[408]379    nolock_printk("at_01   %X  v0_2    %X  v1_3   %X  a0_4   %X  a1_5   %X\n",
380        uzone[UZ_AT], uzone[UZ_V0], uzone[UZ_V1], uzone[UZ_A0], uzone[UZ_A1] );
381
382    nolock_printk("a2_6    %X  a3_7    %X  t0_8   %X  t1_9   %X  t2_10  %X\n",
383        uzone[UZ_A2], uzone[UZ_A3], uzone[UZ_T0], uzone[UZ_T1], uzone[UZ_T2] );
[380]384 
[408]385    nolock_printk("t3_11   %X  t4_12   %X  t5_13  %X  t6_14  %X  t7_15  %X\n",
386        uzone[UZ_T3], uzone[UZ_T4], uzone[UZ_T5], uzone[UZ_T6], uzone[UZ_T7] );
[380]387
[408]388    nolock_printk("s0_16   %X  s1_17   %X  s2_18  %X  s3_19  %X  s4_20  %X\n",
389        uzone[UZ_S0], uzone[UZ_S1], uzone[UZ_S2], uzone[UZ_S3], uzone[UZ_S4] );
[380]390 
[408]391    nolock_printk("s5_21   %X  s6_22   %X  s7_23  %X  s8_24  %X  ra_25  %X\n",
392        uzone[UZ_S5], uzone[UZ_S6], uzone[UZ_S7], uzone[UZ_T8], uzone[UZ_T9] );
[380]393
[408]394    nolock_printk("gp_28   %X  sp_29   %X  S8_30  %X  ra_31  %X\n",
395        uzone[UZ_GP], uzone[UZ_SP], uzone[UZ_S8], uzone[UZ_RA] );
[407]396
[380]397    // release the lock
[570]398    remote_busylock_release( lock_xp );
[380]399
400}  // end hal_exception_dump()
401
[408]402///////////////////////
[481]403void hal_do_exception( void )
[16]404{
[408]405    uint32_t   * uzone;
406    thread_t   * this;
407        error_t      error;
408        uint32_t     excCode;                  // 4 bits XCODE from CP0_CR
[437]409        uint32_t     excPC;                    // fauty instruction address
[16]410
[408]411    // get pointer on faulty thread uzone
412    this  = CURRENT_THREAD;
[425]413    uzone = (uint32_t *)CURRENT_THREAD->uzone_current;
[408]414
[437]415    // get XCODE and EPC from UZONE
[408]416        excCode        = (uzone[UZ_CR] >> 2) & 0xF;
[437]417    excPC          = uzone[UZ_EPC];
[16]418
[438]419#if DEBUG_HAL_EXCEPTIONS
[432]420uint32_t cycle = (uint32_t)hal_get_cycles();
[438]421if( DEBUG_HAL_EXCEPTIONS < cycle )
[457]422printk("\n[DBG] %s : thread %x in process %x enter / core[%x,%d] / epc %x / xcode %x / cycle %d\n",
423__FUNCTION__, this->trdid, this->process->pid, local_cxy, this->core->lid, excPC, excCode, cycle );
[432]424#endif
[406]425
[16]426        switch(excCode)
427        {
[469]428        case XCODE_DBE:     // Data Bus Error : can be non fatal if page fault
[406]429        {
[437]430                    error = hal_mmu_exception( this , excPC , false );  // data MMU exception
[406]431            break;
432        }
[469]433            case XCODE_IBE:     // Instruction Bus Error : can be non fatal if page fault
[16]434        {
[437]435                    error = hal_mmu_exception( this , excPC , true );   // ins MMU exception
[406]436                    break;
[16]437        }
[469]438            case XCODE_CPU:    // Coprocessor unavailable : can be non fatal if FPU
[16]439        {
[469]440            if( ((uzone[UZ_CR] >> 28) & 0x3) == 1 )             // FPU
[16]441            {
[469]442                error = hal_fpu_exception( this );
[16]443            }
[469]444            else                                                // undefined coprocessor
[16]445            {
[469]446                printk("\n[USER_ERROR] in %s for thread %x in process %x\n"
447                "   undefined coprocessor / epc %x\n",
448                __FUNCTION__, this->trdid, this->process->pid, excPC );
449
[16]450                        error = EXCP_USER_ERROR;
451            }
[406]452                    break;
[16]453        }
[469]454        case XCODE_OVR:    // Arithmetic Overflow : user fatal error
455        {
456            printk("\n[USER_ERROR] in %s for thread %x in process %x\n"
457            "   arithmetic overflow / epc %x\n",
458            __FUNCTION__, this->trdid, this->process->pid, excPC );
459
460                    error = EXCP_USER_ERROR;
461                break;
462        }
463        case XCODE_RI:     // Reserved Instruction : user fatal error
464        {
465            printk("\n[USER_ERROR] in %s for thread %x in process %x\n"
466            "   reserved instruction / epc %x\n",
467            __FUNCTION__, this->trdid, this->process->pid, excPC );
468
469                    error = EXCP_USER_ERROR;
470                break;
471        }
[380]472        case XCODE_ADEL:   // user fatal error
[16]473        {
[469]474            printk("\n[USER_ERROR] in %s for thread %x in process %x\n"
475            "   illegal data load address / epc %x\n",
476            __FUNCTION__, this->trdid, this->process->pid, excPC );
477
[16]478                    error = EXCP_USER_ERROR;
[406]479                break;
[16]480        }
[469]481        case XCODE_ADES:   //   user fatal error
482        {
483            printk("\n[USER_ERROR] in %s for thread %x in process %x\n"
484            "   illegal data store address / epc %x\n",
485            __FUNCTION__, this->trdid, this->process->pid, excPC );
486
487                    error = EXCP_USER_ERROR;
488                break;
489        }
[16]490        default:
491        {
[317]492                    error = EXCP_KERNEL_PANIC;
[16]493        }
494        }
495   
496    // analyse error code
[317]497        if( error == EXCP_USER_ERROR )          //  user error => kill user process
[16]498        {
[408]499        hal_exception_dump( this , uzone , error );
[407]500
[440]501        sys_exit( EXIT_FAILURE );
[16]502        }
503    else if( error == EXCP_KERNEL_PANIC )   // kernel error => kernel panic
504    {
[408]505        hal_exception_dump( this , uzone , error );
[425]506
[492]507        assert( false , "Exception raised kernel panic see information below.\n" );
[16]508    }
[406]509
[438]510#if DEBUG_HAL_EXCEPTIONS
[432]511cycle = (uint32_t)hal_get_cycles();
[438]512if( DEBUG_HAL_EXCEPTIONS < cycle )
[457]513printk("\n[DBG] %s : thread %x in process %x exit / core[%x,%d] / epc %x / xcode %x / cycle %d\n",
514__FUNCTION__, this->trdid, this->process->pid, local_cxy, this->core->lid, excPC, excCode, cycle );
[432]515#endif
[406]516
[16]517}  // end hal_do_exception()
518
519
Note: See TracBrowser for help on using the repository browser.