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

Last change on this file since 625 was 625, checked in by alain, 5 years ago

Fix a bug in the vmm_remove_vseg() function: the physical pages
associated to an user DATA vseg were released to the kernel when
the target process descriptor was in the reference cluster.
This physical pages release should be done only when the page
forks counter value is zero.
All other modifications are cosmetic.

File size: 19.8 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.
[610]160// It signal a fatal error in case of illegal access. In case of page unmapped,
161// it get the client process to access the relevant VMM: for a RPC thread, the client
162// process is NOT the calling thread process.
163// Then, it checks that the faulty address belongs to a registered vseg, update the local
[380]164// vseg list from the reference cluster if required, and signal a fatal user error
165// in case of illegal virtual address. Finally, it updates the local page table from the
166// reference cluster.
167//////////////////////////////////////////////////////////////////////////////////////////
168// @ this     : pointer on faulty thread descriptor.
[440]169// @ excPC    :
[406]170// @ is_ins   : IBE if true / DBE if false.
[380]171// @ return EXCP_NON_FATAL / EXCP_USER_ERROR / EXCP_KERNEL_PANIC
172//////////////////////////////////////////////////////////////////////////////////////////
[406]173error_t hal_mmu_exception( thread_t * this,
[437]174                           uint32_t   excPC,
[406]175                           bool_t     is_ins ) 
[380]176{
[406]177        process_t      * process;
178    error_t          error;
[380]179
[406]180    uint32_t         mmu_ins_excp_code;
181    uint32_t         mmu_ins_bad_vaddr;
182    uint32_t         mmu_dat_excp_code;
183    uint32_t         mmu_dat_bad_vaddr;
[380]184
[406]185    uint32_t         bad_vaddr;
[380]186    uint32_t         excp_code;
[610]187
188    // check thread type
189    if( CURRENT_THREAD->type != THREAD_USER )
190    {
[625]191        printk("\n[PANIC] in %s : illegal thread type %s\n",
[610]192        __FUNCTION__, thread_type_str(CURRENT_THREAD->type) );
193
194        return EXCP_KERNEL_PANIC;
195    }
196
197    // get faulty thread process 
[406]198    process = this->process;
[380]199
200    // get relevant values from MMU
201        hal_get_mmu_excp( &mmu_ins_excp_code,
202                          &mmu_ins_bad_vaddr,
203                          &mmu_dat_excp_code, 
204                          &mmu_dat_bad_vaddr );
205
[406]206    // get exception code and faulty vaddr, depending on IBE/DBE
207    if( is_ins )
[380]208    {
209        excp_code = mmu_ins_excp_code;
210        bad_vaddr = mmu_ins_bad_vaddr;
211    }
[406]212    else 
[380]213    {
214        excp_code = mmu_dat_excp_code;
215        bad_vaddr = mmu_dat_bad_vaddr;
216    }
217
[438]218#if DEBUG_HAL_EXCEPTIONS
[432]219uint32_t cycle = (uint32_t)hal_get_cycles();
[438]220if( DEBUG_HAL_EXCEPTIONS < cycle )
[619]221printk("\n[%s] thread[%x,%x] on core [%x,%x] enter\n  is_ins %d / %s / vaddr %x / cycle %d\n",
[610]222__FUNCTION__, process->pid, this->trdid, local_cxy, this->core->lid,
[469]223is_ins, hal_mmu_exception_str(excp_code), bad_vaddr, cycle);
[432]224#endif
[408]225
[407]226   // analyse exception code
227    switch( excp_code )
[380]228    {
[610]229        case MMU_WRITE_PT1_UNMAPPED:      // can be non fatal
230        case MMU_WRITE_PT2_UNMAPPED:      // can be non fatal
231        case MMU_READ_PT1_UNMAPPED:       // can be non fatal
232        case MMU_READ_PT2_UNMAPPED:       // can be non fatal
[407]233        {
234            // try to map the unmapped PTE
235            error = vmm_handle_page_fault( process, 
[587]236                                           bad_vaddr >> CONFIG_PPM_PAGE_SHIFT );
[406]237
[587]238            if( error == EXCP_NON_FATAL )            // page-fault successfully handled
[407]239            {
[391]240
[438]241#if DEBUG_HAL_EXCEPTIONS
[432]242cycle = (uint32_t)hal_get_cycles();
[438]243if( DEBUG_HAL_EXCEPTIONS < cycle )
[619]244printk("\n[%s] thread[%x,%x] on core [%x,%x] exit\n  page-fault handled for vaddr = %x\n",
[610]245__FUNCTION__, process->pid, this->trdid, local_cxy, this->core->lid, bad_vaddr );
[432]246#endif
[407]247 
248                return EXCP_NON_FATAL;
249            }
[587]250            else if( error == EXCP_USER_ERROR )      // illegal vaddr
251            {
[625]252                printk("\n[ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
[610]253                "  %s : epc %x / badvaddr %x / is_ins %d\n",
254                __FUNCTION__, this->process->pid, this->trdid, local_cxy,
255                this->core->lid, (uint32_t)hal_get_cycles(),
256                hal_mmu_exception_str(excp_code), excPC, bad_vaddr, is_ins );
[587]257
258                        return EXCP_USER_ERROR;
259            } 
260            else  // error == EXCP_KERNEL_PANIC 
261            {
[625]262                printk("\n[PANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
[610]263                "  %s : epc %x / badvaddr %x / is_ins %d\n",
264                __FUNCTION__, this->process->pid, this->trdid, local_cxy,
265                this->core->lid, (uint32_t)hal_get_cycles(),
266                hal_mmu_exception_str(excp_code), excPC, bad_vaddr, is_ins );
[587]267
268                        return EXCP_KERNEL_PANIC;
269            } 
[407]270        }
[610]271        case MMU_WRITE_PRIVILEGE_VIOLATION:  // illegal user error
272        case MMU_READ_PRIVILEGE_VIOLATION:   // illegal
[380]273        {
[625]274            printk("\n[ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
[610]275            "  %s : epc %x / badvaddr %x / is_ins %d\n",
276            __FUNCTION__, this->process->pid, this->trdid, local_cxy,
277            this->core->lid, (uint32_t)hal_get_cycles(),
278            hal_mmu_exception_str(excp_code), excPC, bad_vaddr, is_ins );
[380]279
[407]280            return EXCP_USER_ERROR;
281        }
[610]282        case MMU_WRITE_ACCESS_VIOLATION:    // can be non fatal if COW
[380]283        {
[610]284            // try to handle a possible COW
285            error = vmm_handle_cow( process,
286                                    bad_vaddr >> CONFIG_PPM_PAGE_SHIFT );
[380]287
[610]288            if( error == EXCP_NON_FATAL )        // COW successfully handled
[407]289            {
[380]290
[438]291#if DEBUG_HAL_EXCEPTIONS
[432]292cycle = (uint32_t)hal_get_cycles();
[438]293if( DEBUG_HAL_EXCEPTIONS < cycle )
[610]294printk("\n[%s] thread[%x,%x] exit / copy-on-write handled for vaddr = %x\n",
[587]295__FUNCTION__, process->pid, this->trdid, bad_vaddr );
[432]296#endif
[610]297                return EXCP_NON_FATAL;
298            } 
299            else if( error == EXCP_USER_ERROR )  // illegal write access
300            {
[625]301                    printk("\n[ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
[610]302                    "  %s : epc %x / badvaddr %x / is_ins %d\n",
303                    __FUNCTION__, this->process->pid, this->trdid, local_cxy,
304                    this->core->lid, (uint32_t)hal_get_cycles(),
305                    hal_mmu_exception_str(excp_code), excPC, bad_vaddr, is_ins );
[380]306
[587]307                            return EXCP_USER_ERROR;
[407]308            }
[610]309            else   // error == EXCP_KERNEL_PANIC
[407]310            {
[625]311                printk("\n[PANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
[610]312                "  %s : epc %x / badvaddr %x / is_ins %d\n",
313                __FUNCTION__, this->process->pid, this->trdid, local_cxy,
314                this->core->lid, (uint32_t)hal_get_cycles(),
315                hal_mmu_exception_str(excp_code), excPC, bad_vaddr, is_ins );
[407]316
[610]317                        return EXCP_USER_ERROR;
[407]318            }
319        }
320        case MMU_READ_EXEC_VIOLATION:        // user error
321        {
[625]322            printk("\n[ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
[610]323            "  %s : epc %x / badvaddr %x / is_ins %d\n",
324            __FUNCTION__, this->process->pid, this->trdid, local_cxy,
325            this->core->lid, (uint32_t)hal_get_cycles(),
326            hal_mmu_exception_str(excp_code), excPC, bad_vaddr, is_ins );
[407]327
328            return EXCP_USER_ERROR;
329        }
[469]330        default:                             // this is a kernel error   
[407]331        {
[625]332            printk("\n[PANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
[610]333            "  %s : epc %x / badvaddr %x / is_ins %d\n",
334            __FUNCTION__, this->process->pid, this->trdid, local_cxy,
335            this->core->lid, (uint32_t)hal_get_cycles(),
336            hal_mmu_exception_str(excp_code), excPC, bad_vaddr, is_ins );
[407]337
338            return EXCP_KERNEL_PANIC;
339        }
340    } 
[380]341} // end hal_mmu_exception()
342
343//////////////////////////////////////////////////////////////////////////////////////////
[619]344// This function prints on the kernel terminal the saved context (core registers)
[380]345// and the thread state of a faulty thread.
346//////////////////////////////////////////////////////////////////////////////////////////
347// @ this     : pointer on faulty thread descriptor.
348//////////////////////////////////////////////////////////////////////////////////////////
[625]349static void hal_exception_dump( thread_t * this )
[380]350{
[408]351    core_t    * core    = this->core;
352    process_t * process = this->process;
[619]353    reg_t     * uzone   = this->uzone_current;
[380]354
355    // get pointers on TXT0 chdev
[407]356    xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
[380]357    cxy_t     txt0_cxy = GET_CXY( txt0_xp );
358    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
359
360    // get extended pointer on remote TXT0 chdev lock
361    xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
362
363    // get TXT0 lock in busy waiting mode
[570]364    remote_busylock_acquire( lock_xp );
[380]365
[625]366    nolock_printk("\n=== thread(%x,%x) / core[%d] / cycle %d ===\n",
367    process->pid, this->trdid, core->lid, (uint32_t)hal_get_cycles() );
[380]368
[570]369        nolock_printk("busylocks = %d / blocked_vector = %X / flags = %X\n\n",
370    this->busylocks, this->blocked, this->flags );
[380]371
[408]372    nolock_printk("c0_cr   %X  c0_epc  %X  c0_sr  %X  c0_th  %X\n",
373    uzone[UZ_CR], uzone[UZ_EPC], uzone[UZ_SR], uzone[UZ_TH] );
[380]374
[408]375    nolock_printk("c2_mode %X  c2_ptpr %X\n",
376    uzone[UZ_MODE], uzone[UZ_PTPR] );
[380]377
[408]378    nolock_printk("at_01   %X  v0_2    %X  v1_3   %X  a0_4   %X  a1_5   %X\n",
379        uzone[UZ_AT], uzone[UZ_V0], uzone[UZ_V1], uzone[UZ_A0], uzone[UZ_A1] );
380
381    nolock_printk("a2_6    %X  a3_7    %X  t0_8   %X  t1_9   %X  t2_10  %X\n",
382        uzone[UZ_A2], uzone[UZ_A3], uzone[UZ_T0], uzone[UZ_T1], uzone[UZ_T2] );
[380]383 
[408]384    nolock_printk("t3_11   %X  t4_12   %X  t5_13  %X  t6_14  %X  t7_15  %X\n",
385        uzone[UZ_T3], uzone[UZ_T4], uzone[UZ_T5], uzone[UZ_T6], uzone[UZ_T7] );
[380]386
[408]387    nolock_printk("s0_16   %X  s1_17   %X  s2_18  %X  s3_19  %X  s4_20  %X\n",
388        uzone[UZ_S0], uzone[UZ_S1], uzone[UZ_S2], uzone[UZ_S3], uzone[UZ_S4] );
[380]389 
[619]390    nolock_printk("s5_21   %X  s6_22   %X  s7_23  %X  t8_24  %X  t9_25  %X\n",
[408]391        uzone[UZ_S5], uzone[UZ_S6], uzone[UZ_S7], uzone[UZ_T8], uzone[UZ_T9] );
[380]392
[408]393    nolock_printk("gp_28   %X  sp_29   %X  S8_30  %X  ra_31  %X\n",
394        uzone[UZ_GP], uzone[UZ_SP], uzone[UZ_S8], uzone[UZ_RA] );
[407]395
[380]396    // release the lock
[570]397    remote_busylock_release( lock_xp );
[380]398
399}  // end hal_exception_dump()
400
[610]401/////////////////////////////
[481]402void hal_do_exception( void )
[16]403{
[408]404    uint32_t   * uzone;
405    thread_t   * this;
406        error_t      error;
407        uint32_t     excCode;                  // 4 bits XCODE from CP0_CR
[437]408        uint32_t     excPC;                    // fauty instruction address
[16]409
[408]410    // get pointer on faulty thread uzone
411    this  = CURRENT_THREAD;
[425]412    uzone = (uint32_t *)CURRENT_THREAD->uzone_current;
[408]413
[437]414    // get XCODE and EPC from UZONE
[408]415        excCode        = (uzone[UZ_CR] >> 2) & 0xF;
[437]416    excPC          = uzone[UZ_EPC];
[16]417
[438]418#if DEBUG_HAL_EXCEPTIONS
[432]419uint32_t cycle = (uint32_t)hal_get_cycles();
[438]420if( DEBUG_HAL_EXCEPTIONS < cycle )
[610]421printk("\n[%s] thread[%x,%x] enter / core[%x,%d] / epc %x / xcode %x / cycle %d\n",
422__FUNCTION__, this->process->pid, this->trdid,
423local_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            {
[611]446                printk("\n[USER_ERROR] in %s for thread[%x,%x]\n"
[469]447                "   undefined coprocessor / epc %x\n",
[611]448                __FUNCTION__, this->process->pid, this->trdid, excPC );
[469]449
[16]450                        error = EXCP_USER_ERROR;
451            }
[406]452                    break;
[16]453        }
[469]454        case XCODE_OVR:    // Arithmetic Overflow : user fatal error
455        {
[611]456            printk("\n[USER_ERROR] in %s for thread[%x,%x]\n"
[469]457            "   arithmetic overflow / epc %x\n",
[611]458            __FUNCTION__, this->process->pid, this->trdid, excPC );
[469]459
460                    error = EXCP_USER_ERROR;
461                break;
462        }
463        case XCODE_RI:     // Reserved Instruction : user fatal error
464        {
[611]465            printk("\n[USER_ERROR] in %s for thread[%x,%x]\n"
[469]466            "   reserved instruction / epc %x\n",
[611]467            __FUNCTION__, this->process->pid, this->trdid, excPC );
[469]468
469                    error = EXCP_USER_ERROR;
470                break;
471        }
[380]472        case XCODE_ADEL:   // user fatal error
[16]473        {
[611]474            printk("\n[USER_ERROR] in %s for thread[%x,%x]\n"
[610]475            "   illegal data load address / epc %x / bad_address %x\n",
[611]476            __FUNCTION__, this->process->pid, this->trdid, excPC, hal_get_bad_vaddr() );
[469]477
[16]478                    error = EXCP_USER_ERROR;
[406]479                break;
[16]480        }
[469]481        case XCODE_ADES:   //   user fatal error
482        {
[611]483            printk("\n[USER_ERROR] in %s for thread[%x,%x]\n"
[610]484            "   illegal data store address / epc %x / bad_address %x\n",
[611]485            __FUNCTION__, this->process->pid, this->trdid, excPC, hal_get_bad_vaddr() );
[469]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        {
[625]499        hal_exception_dump( this );
[407]500
[440]501        sys_exit( EXIT_FAILURE );
[16]502        }
503    else if( error == EXCP_KERNEL_PANIC )   // kernel error => kernel panic
504    {
[625]505        hal_exception_dump( this );
[425]506
[610]507        hal_core_sleep();
[16]508    }
[406]509
[438]510#if DEBUG_HAL_EXCEPTIONS
[432]511cycle = (uint32_t)hal_get_cycles();
[438]512if( DEBUG_HAL_EXCEPTIONS < cycle )
[610]513printk("\n[%s] thread[%x,%x] exit / core[%x,%d] / epc %x / xcode %x / cycle %d\n",
514__FUNCTION__, this->process->pid, this->trdid,
515local_cxy, this->core->lid, excPC, excCode, cycle );
[432]516#endif
[406]517
[16]518}  // end hal_do_exception()
519
520
Note: See TracBrowser for help on using the repository browser.