Ignore:
Timestamp:
Nov 7, 2017, 3:08:12 PM (6 years ago)
Author:
alain
Message:

First implementation of fork/exec.

Location:
trunk/hal/tsar_mips32/core
Files:
1 added
12 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/hal/tsar_mips32/core/hal_context.c

    r406 r407  
    4444
    4545/////////////////////////////////////////////////////////////////////////////////////////
    46 // This structuree defines the cpu_context for TSAR MIPS32.
    47 // These registers are saved/restored at each context switch.
     46// This structure defines the CPU context for TSAR MIPS32.
     47// The following registers are saved/restored at each context switch:
     48// - GPR : all, but (zero, k0, k1), plus (hi, lo)
     49// - CP0 : c0_th , c0_sr , C0_epc
     50// - CP2 : c2_ptpr , C2_mode
     51//
    4852// WARNING : check the two CONFIG_CPU_CTX_SIZE & CONFIG_FPU_CTX_SIZE configuration
    4953//           parameterss when modifying this structure.
     
    8589    uint32_t gp_28;      // slot 28
    8690        uint32_t sp_29;      // slot 29
    87         uint32_t fp_30;      // slot 30
     91        uint32_t s8_30;      // slot 30
    8892        uint32_t ra_31;      // slot 31
    8993
     
    108112
    109113/////////////////////////////////////////////////////////////////////////////////////////
    110 //        CPU context access functions
    111 /////////////////////////////////////////////////////////////////////////////////////////
    112 
    113 /////////////////////////////////////////////////////////////////////////////////////////
    114 // This function allocates and initializes the cpu_context stucture in thread descriptor.
    115 // The following context slots are initialised by this function:
    116 // GPR : a0_04 / sp_29 / fp_30 / ra_31
     114//        CPU context related functions
     115/////////////////////////////////////////////////////////////////////////////////////////
     116
     117
     118//////////////////////////////////////////////////
     119error_t hal_cpu_context_alloc( thread_t * thread )
     120{
     121    assert( (sizeof(hal_cpu_context_t) <= CONFIG_CPU_CTX_SIZE) , __FUNCTION__ ,
     122    "illegal CPU context size" );
     123
     124    // allocate memory for cpu_context
     125    kmem_req_t  req;
     126    req.type   = KMEM_CPU_CTX;
     127    req.flags  = AF_KERNEL | AF_ZERO;
     128
     129    hal_cpu_context_t * context = (hal_cpu_context_t *)kmem_alloc( &req );
     130    if( context == NULL ) return -1;
     131
     132    // link to thread
     133    thread->cpu_context = (void *)context;
     134    return 0;
     135
     136}   // end hal_cpu_context_alloc()
     137
     138///////////////////////////////////////////////////
     139// The following context slots are initialised :
     140// GPR : a0_04 / sp_29 / ra_31
    117141// CP0 : c0_sr / c0_th / c0_epc
    118142// CP2 : c2_ptpr / c2_mode
    119 /////////////////////////////////////////////////////////////////////////////////////////
     143///////////////////////////////////////////////////
    120144error_t hal_cpu_context_create( thread_t * thread )
    121145{
    122     kmem_req_t  req;
    123 
    124     assert( (sizeof(hal_cpu_context_t) <= CONFIG_CPU_CTX_SIZE) , __FUNCTION__ ,
    125     "inconsistent CPU context size" );
    126 
    127     context_dmsg("\n[DMSG] %s : enters for thread %x in process %x\n",
    128                  __FUNCTION__ , thread->trdid , thread->process->pid );
    129 
    130     // allocate memory for cpu_context
    131     req.type   = KMEM_CPU_CTX;
    132     req.flags  = AF_KERNEL | AF_ZERO;
    133 
    134     hal_cpu_context_t * context = (hal_cpu_context_t *)kmem_alloc( &req );
    135     if( context == NULL ) return ENOMEM;
    136 
    137     // set cpu context pointer in thread
    138     thread->cpu_context = (void*)context;
    139 
    140     // stack pointer, status register and mmu_mode depends on thread type
    141         uint32_t sp_29;
    142     uint32_t c0_sr;
    143     uint32_t c2_mode;
     146    // allocate memory for a CPU context
     147    error_t error = hal_cpu_context_alloc( thread );
     148
     149    if( error ) return error;
     150
     151    hal_cpu_context_t * context = (hal_cpu_context_t *)thread->cpu_context;
     152
     153    // initialisation depends on thread type
    144154    if( thread->type == THREAD_USER )
    145155    {
    146         sp_29   = ((uint32_t)thread->u_stack_base) + thread->u_stack_size;
    147         c0_sr   = SR_USR_MODE;
    148         c2_mode = 0xF;
     156        context->a0_04   = (uint32_t)thread->entry_args;
     157        context->sp_29   = (uint32_t)thread->u_stack_base + (uint32_t)thread->u_stack_size - 8;
     158        context->ra_31   = (uint32_t)&hal_kentry_eret;
     159        context->c0_epc  = (uint32_t)thread->entry_func;
     160        context->c0_sr   = SR_USR_MODE;
     161            context->c0_th   = (uint32_t)thread;
     162            context->c2_ptpr = (uint32_t)((thread->process->vmm.gpt.ppn) >> 1);
     163        context->c2_mode = 0xF;
    149164    }
    150     else
     165    else  // kernel thread
    151166    {
    152         sp_29   = ((uint32_t)thread->k_stack_base) + thread->k_stack_size;
    153         c0_sr   = SR_SYS_MODE;
    154         c2_mode = 0x3;
     167        context->a0_04   = (uint32_t)thread->entry_args;
     168        context->sp_29   = (uint32_t)thread->k_stack_base + (uint32_t)thread->k_stack_size - 8;
     169        context->ra_31   = (uint32_t)thread->entry_func;
     170        context->c0_sr   = SR_SYS_MODE;
     171            context->c0_th   = (uint32_t)thread;
     172            context->c2_ptpr = (uint32_t)((thread->process->vmm.gpt.ppn) >> 1);
     173        context->c2_mode = 0x3;
    155174    }
    156175
    157     // align stack pointer on a double word boundary
    158         sp_29 = (sp_29 - 8) & (~ 0x7);
    159 
    160     // initialise context
    161     context->a0_04      = (uint32_t)thread->entry_args;
    162         context->sp_29      = sp_29;
    163         context->fp_30      = sp_29;                               // TODO check this [AG]
    164     context->ra_31      = (uint32_t)&hal_kentry_eret;
    165     context->c0_epc     = (uint32_t)thread->entry_func;
    166         context->c0_sr      = c0_sr;
    167         context->c0_th      = (uint32_t)thread;
    168         context->c2_ptpr    = (uint32_t)((thread->process->vmm.gpt.ppn) >> 1);
    169         context->c2_mode    = c2_mode;
    170 
    171     context_dmsg("\n[DMSG] %s : exit for thread %x in process %x\n"
     176context_dmsg("\n[DBG] %s : thread %x in process %x\n"
    172177                 " - a0   = %x\n"
    173178                 " - sp   = %x\n"
    174                  " - fp   = %x\n"
    175179                 " - ra   = %x\n"
    176180                 " - sr   = %x\n"
     
    180184                 " - mode = %x\n", 
    181185                 __FUNCTION__ , thread->trdid , thread->process->pid,
    182                  context->a0_04, context->sp_29, context->fp_30, context->ra_31,
     186                 context->a0_04, context->sp_29, context->ra_31,
    183187                 context->c0_sr, context->c0_th, context->c0_epc,
    184188                 context->c2_ptpr, context->c2_mode );
     
    201205           ctx->c2_ptpr , ctx->c2_mode );
    202206
    203 }  // end hal_context_display()
    204 
    205 /////////////////////////////////////////////////////////////////////////////////////////
    206 // These registers are saved/restored to/from CPU context defined by <ctx> argument.
    207 // - GPR : all, but (zero, k0, k1), plus (hi, lo)
    208 // - CP0 : c0_th , c0_sr , C0_epc
    209 // - CP2 : c2_ptpr , C2_mode
    210 /////////////////////////////////////////////////////////////////////////////////////////
    211 // old_thread  : pointer on current thread descriptor
    212 // new_thread  : pointer on new thread descriptor
    213 /////////////////////////////////////////////////////////////////////////////////////////
    214 void hal_cpu_context_switch( thread_t * old_thread,
    215                              thread_t * new_thread )
    216 {
    217     hal_cpu_context_t * ctx_old = old_thread->cpu_context;
    218     hal_cpu_context_t * ctx_new = new_thread->cpu_context;
    219 
    220     #if CONFIG_CONTEXT_DEBUG
    221     hal_cpu_context_display( old_thread );
    222     hal_cpu_context_display( new_thread );
    223     #endif
    224 
    225     // reset loadable field in new thread descriptor
    226     new_thread->flags &= ~THREAD_FLAG_LOADABLE;
    227 
    228     hal_do_switch( ctx_old , ctx_new );
    229 }
    230 
    231 /////////////////////////////////////////////
    232 error_t hal_cpu_context_copy( thread_t * dst,
    233                               thread_t * src )
    234 {
    235     kmem_req_t  req;
    236 
    237     // allocate memory for dst cpu_context
    238     req.type   = KMEM_CPU_CTX;
    239     req.size   = sizeof(hal_cpu_context_t);
    240     req.flags  = AF_KERNEL | AF_ZERO;
    241 
    242     hal_cpu_context_t * dst_context = (hal_cpu_context_t *)kmem_alloc( &req );
    243     if( dst_context == NULL ) return ENOMEM;
    244 
    245     // set cpu context pointer in dst thread
    246     dst->cpu_context = dst_context;
    247 
    248     // get cpu context pointer from src thread
    249     hal_cpu_context_t * src_context = src->cpu_context;
    250 
    251     // copy CPU context from src to dst
    252     memcpy( dst_context , src_context , sizeof(hal_cpu_context_t) );
    253 
    254     return 0;
    255 
    256 }  // end hal_cpu_context_copy()
     207}  // end hal_cpu_context_display()
    257208
    258209/////////////////////////////////////////////////
     
    268219
    269220
    270 ///////////////////////////////////////////////////
    271 error_t hal_fpu_context_create( thread_t * thread )
    272 {
     221
     222
     223
     224//////////////////////////////////////////////////
     225error_t hal_fpu_context_alloc( thread_t * thread )
     226{
     227    assert( (sizeof(hal_fpu_context_t) <= CONFIG_FPU_CTX_SIZE) , __FUNCTION__ ,
     228    "illegal CPU context size" );
     229
     230    // allocate memory for fpu_context
    273231    kmem_req_t  req;
    274 
    275     assert( (sizeof(hal_fpu_context_t) <= CONFIG_FPU_CTX_SIZE) , __FUNCTION__ ,
    276     "inconsistent FPU context size" );
    277 
    278     // allocate memory for uzone
    279232    req.type   = KMEM_FPU_CTX;
    280233    req.flags  = AF_KERNEL | AF_ZERO;
    281234
    282235    hal_fpu_context_t * context = (hal_fpu_context_t *)kmem_alloc( &req );
    283     if( context == NULL ) return ENOMEM;
    284 
    285     // set fpu context pointer in thread
    286     thread->fpu_context = (void*)context;
    287    
     236    if( context == NULL ) return -1;
     237
     238    // link to thread
     239    thread->fpu_context = (void *)context;
    288240    return 0;
    289 }  // hal_fpu_context_create()
    290 
    291 /////////////////////////////////////////////
    292 error_t hal_fpu_context_copy( thread_t * dst,
    293                               thread_t * src )
    294 {
    295     kmem_req_t  req;
    296 
    297     // allocate memory for dst fpu_context
    298     req.type   = KMEM_FPU_CTX;
    299     req.flags  = AF_KERNEL | AF_ZERO;
    300 
    301     hal_fpu_context_t * dst_context = (hal_fpu_context_t *)kmem_alloc( &req );
    302     if( dst_context == NULL ) return ENOMEM;
    303 
    304     // set fpu context pointer in dst thread
    305     dst->fpu_context = (void*)dst_context;
    306 
    307     // get fpu context pointer from src thread
     241
     242}   // end hal_fpu_context_alloc()
     243
     244//////////////////////////////////////////
     245void hal_fpu_context_copy( thread_t * dst,
     246                           thread_t * src )
     247{
     248    assert( (src != NULL) , __FUNCTION__ , "src thread pointer is NULL\n");
     249    assert( (dst != NULL) , __FUNCTION__ , "dst thread pointer is NULL\n");
     250
     251    // get fpu context pointers
    308252    hal_fpu_context_t * src_context = src->fpu_context;
     253    hal_fpu_context_t * dst_context = dst->fpu_context;
    309254
    310255    // copy CPU context from src to dst
    311256    memcpy( dst_context , src_context , sizeof(hal_fpu_context_t) );
    312257
    313     return 0;
    314258}  // end hal_fpu_context_copy()
    315259
     
    413357} // end hal_cpu_context_restore()
    414358
    415 /////////////////////////////////////
    416 void hal_fpu_context_dup( xptr_t dst,
    417                           xptr_t src )
    418 {
    419         hal_remote_memcpy( dst , src , sizeof(hal_fpu_context_t) );
    420 }
    421 
     359
  • trunk/hal/tsar_mips32/core/hal_drivers.c

    r346 r407  
    4949                           uint32_t   impl )
    5050{
    51         if( impl == IMPL_TXT_TTY )
    52         {
    53                 soclib_tty_init( txt );
    54         }
    55         else
    56         {
    57                 assert( false , __FUNCTION__ , "undefined TXT device implementation" );
    58         }
     51        assert( (impl == IMPL_TXT_TTY), __FUNCTION__ , "bad implementation" );
     52
     53        soclib_tty_init( txt );
    5954}
    6055
     
    6762                           uint32_t   impl )
    6863{
    69     if( impl != IMPL_PIC_SCL )
    70     {
    71         assert( false , __FUNCTION__ , "undefined PIC device implementation" );
    72     }
     64    assert( (impl == IMPL_PIC_SCL), __FUNCTION__, "bad implementation" );
    7365
    7466        soclib_pic_init( pic );
     
    8173        pic->ext.pic.bind_irq     = &soclib_pic_bind_irq;
    8274        pic->ext.pic.send_ipi     = &soclib_pic_send_ipi;
     75        pic->ext.pic.ack_ipi      = &soclib_pic_ack_ipi;
    8376        pic->ext.pic.extend_init  = &soclib_pic_extend_init;
    8477}
     
    9285                           uint32_t   impl )
    9386{
    94         if (impl != IMPL_IOB_TSR)
    95         {
    96                 assert( false , __FUNCTION__ , "undefined IOB device implementation" );
    97         }
     87        assert( (impl == IMPL_IOB_TSR), __FUNCTION__ , "bad implementation" );
    9888
    9989        soclib_iob_init( iob );
     
    138128                           uint32_t   impl )
    139129{
    140     if( impl == IMPL_MMC_TSR )
    141     {
    142         soclib_mmc_init( mmc );
    143     }
    144     else
    145     {
    146         assert( false , __FUNCTION__ , "undefined MMC device implementation" );
    147     }
     130        assert( (impl == IMPL_MMC_TSR), __FUNCTION__ , "bad implementation" );
     131 
     132    soclib_mmc_init( mmc );
    148133}
    149134
     
    156141                           uint32_t   impl )
    157142{
    158     if( impl == IMPL_NIC_SOC )
    159     {
    160         soclib_nic_init( nic );
    161     }
    162     else
    163     {
    164         assert( false , __FUNCTION__ , "undefined NIC device implementation" );
    165     }
     143        assert( (impl == IMPL_NIC_CBF), __FUNCTION__ , "bad implementation" );
     144 
     145    soclib_nic_init( nic );
    166146}
    167147
     
    174154                           uint32_t   impl )
    175155{
    176     if( impl == IMPL_DMA_SCL )
    177     {
    178         soclib_dma_init( dma );
    179     }
    180     else
    181     {
    182         assert( false , __FUNCTION__ , "undefined DMA implementation" );
    183     }
     156        assert( (impl == IMPL_DMA_SCL), __FUNCTION__ , "bad implementation" );
     157 
     158    soclib_dma_init( dma );
    184159}
    185160
  • trunk/hal/tsar_mips32/core/hal_exception.c

    r406 r407  
    5858
    5959//////////////////////////////////////////////////////////////////////////////////////////
    60 // This enum defines the mask valuesi for an MMU exception code reported by the mips32.
     60// This enum defines the mask values for an MMU exception code reported by the mips32.
    6161//////////////////////////////////////////////////////////////////////////////////////////
    6262
    6363typedef enum
    6464{
    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,
    6982}
    7083mmu_exception_subtype_t;
     
    148161    process = this->process;
    149162
    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 
    153163    // get relevant values from MMU
    154164        hal_get_mmu_excp( &mmu_ins_excp_code,
     
    157167                          &mmu_dat_bad_vaddr );
    158168
    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 
    163169    // get exception code and faulty vaddr, depending on IBE/DBE
    164170    if( is_ins )
     
    173179    }
    174180
    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
     205excp_dmsg("\n[DBG] %s : core[%x,%d] / page-fault handled for vaddr = %x\n",
     206__FUNCTION__ , local_cxy , this->core->lid , bad_vaddr );
    203207 
    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
     240excp_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    } 
    236269} // end hal_mmu_exception()
    237270
     
    242275// @ this     : pointer on faulty thread descriptor.
    243276// @ regs_tbl : pointer on register array.
    244 // @ return always EXCP_NON_FATAL
     277// @ error    : EXCP_USER_ERROR or EXCP_KERNEL_PANIC
    245278//////////////////////////////////////////////////////////////////////////////////////////
    246279static void hal_exception_dump( thread_t * this,
    247                                 reg_t    * regs_tbl )
     280                                reg_t    * regs_tbl,
     281                                error_t    error )
    248282{
    249283    uint32_t  save_sr;
     284    core_t  * core = this->core;
    250285
    251286    // get pointers on TXT0 chdev
    252     xptr_t    txt0_xp  = chdev_dir.txt[0];
     287    xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
    253288    cxy_t     txt0_cxy = GET_CXY( txt0_xp );
    254289    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
     
    260295    remote_spinlock_lock_busy( lock_xp , &save_sr );
    261296
    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    }
    265302    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    }
    268307
    269308        nolock_printk("  thread type = %s / trdid = %x / pid %x / core[%x,%d]\n"
     
    272311           this->core->lid, this->local_locks, this->remote_locks, this->blocked );
    273312
    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]);
    279318
    280319    nolock_printk("a2_6  %X  a3_7  %X  t0_8  %X  t1_9   %X  t2_10  %X\n",
     
    284323                   regs_tbl[UZ_T3],regs_tbl[UZ_T4],regs_tbl[UZ_T5],regs_tbl[UZ_T6],regs_tbl[UZ_T7]);
    285324
    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 
    289325    nolock_printk("s0_16 %X  s1_17 %X  s2_18 %X  s3_19  %X  s4_20  %X\n",
    290326                   regs_tbl[UZ_S0],regs_tbl[UZ_S1],regs_tbl[UZ_S2],regs_tbl[UZ_S3],regs_tbl[UZ_S4]);
    291327 
    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]);
    294333
    295334    // release the lock
     
    311350        excCode        = (regs_tbl[UZ_CR] >> 2) & 0xF;
    312351
    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() );
     352excp_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,
     354this->process->pid, excCode, (uint32_t)hal_get_cycle() );
    315355
    316356        switch(excCode)
     
    355395        if( error == EXCP_USER_ERROR )          //  user error => kill user process
    356396        {
    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 );
    359402        }
    360403    else if( error == EXCP_KERNEL_PANIC )   // kernel error => kernel panic
    361404    {
    362         hal_exception_dump( this , regs_tbl );
     405        hal_exception_dump( this , regs_tbl , error );
    363406        hal_core_sleep();
    364407    }
    365408
    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() );
     409excp_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() );
    368411
    369412}  // end hal_do_exception()
  • trunk/hal/tsar_mips32/core/hal_gpt.c

    r406 r407  
    135135    uint32_t   attr;
    136136
    137     gpt_dmsg("\n[DMSG] %s : core[%x,%d] enter\n",
    138     __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );
     137gpt_dmsg("\n[DBG] %s : core[%x,%d] enter\n",
     138__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );
    139139
    140140    // check page size
     
    157157    // initialize generic page table descriptor
    158158    page_xp   = XPTR( local_cxy , page );
    159 
    160159        gpt->ptr  = GET_PTR( ppm_page2base( page_xp ) );
    161160        gpt->ppn  = ppm_page2ppn( page_xp );
    162         gpt->page = GET_PTR( page_xp );
    163161
    164162    // identity map the kentry_vseg (must exist for all processes)
     
    167165         vpn < (CONFIG_VMM_KENTRY_BASE + CONFIG_VMM_KENTRY_SIZE); vpn++ )
    168166    {
    169         gpt_dmsg("\n[DMSG] %s : identity map vpn %d\n", __FUNCTION__ , vpn );
     167
     168gpt_dmsg("\n[DBG] %s : identity map vpn %d\n", __FUNCTION__ , vpn );
    170169
    171170        error = hal_gpt_set_pte( gpt,
     
    181180    }
    182181
    183     gpt_dmsg("\n[DMSG] %s : core[%x,%d] exit\n",
    184     __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );
     182gpt_dmsg("\n[DBG] %s : core[%x,%d] exit\n",
     183__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );
    185184
    186185        return 0;
     
    271270} // end hal_gpt_destroy()
    272271
    273 ////////////////////////////////
    274 void hal_gpt_print( gpt_t * gpt,
    275                     pid_t   pid )
    276 {
     272///////////////////////////////////////////
     273void hal_gpt_display( process_t * process )
     274{
     275    gpt_t    * gpt;
    277276        uint32_t   ix1;
    278277        uint32_t   ix2;
     
    285284    vpn_t      vpn;
    286285
    287 
     286    assert( (process != NULL) , __FUNCTION__ , "NULL process pointer\n");
     287
     288    // get pointer on gpt
     289    gpt = &(process->vmm.gpt);
     290
     291    // get pointer on PT1
    288292    pt1 = (uint32_t *)gpt->ptr;
    289293
    290294    printk("\n***** Generic Page Table for process %x : &gpt = %x / &pt1 = %x\n\n",
    291     pid , gpt , pt1 );
     295    process->pid , gpt , pt1 );
    292296
    293297    // scan the PT1
     
    324328        }
    325329        }
    326 } // end hal_gpt_print()
     330} // end hal_gpt_display()
    327331
    328332
     
    351355    uint32_t            tsar_attr;           // PTE attributes for TSAR MMU
    352356
    353     gpt_dmsg("\n[DMSG] %s : core[%x,%d] enter for vpn = %x / ppn = %x / gpt_attr = %x\n",
     357    gpt_dmsg("\n[DBG] %s : core[%x,%d] enter for vpn = %x / ppn = %x / gpt_attr = %x\n",
    354358    __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , ppn , attr );
    355359 
     
    364368    tsar_attr = gpt2tsar( attr );
    365369
    366     gpt_dmsg("\n[DMSG] %s : core[%x,%d] / vpn = %x / &pt1 = %x / tsar_attr = %x\n",
     370    gpt_dmsg("\n[DBG] %s : core[%x,%d] / vpn = %x / &pt1 = %x / tsar_attr = %x\n",
    367371    __FUNCTION__, local_cxy , CURRENT_THREAD->core->lid , vpn , pt1 , tsar_attr );
    368372
     
    396400        pte1 = *pte1_ptr;
    397401       
    398         gpt_dmsg("\n[DMSG] %s : core[%x,%d] / vpn = %x / current_pte1 = %x\n",
     402        gpt_dmsg("\n[DBG] %s : core[%x,%d] / vpn = %x / current_pte1 = %x\n",
    399403        __FUNCTION__, local_cxy , CURRENT_THREAD->core->lid , vpn , pte1 );
    400404       
     
    438442            pt2     = (uint32_t *)GET_PTR( ppm_ppn2base( pt2_ppn ) );
    439443
    440         gpt_dmsg("\n[DMSG] %s : core[%x,%d] / vpn = %x / pte1 = %x / &pt2 = %x\n",
     444        gpt_dmsg("\n[DBG] %s : core[%x,%d] / vpn = %x / pte1 = %x / &pt2 = %x\n",
    441445        __FUNCTION__, local_cxy , CURRENT_THREAD->core->lid , vpn , pte1 , pt2 );
    442446       
     
    450454        hal_fence();
    451455
    452     gpt_dmsg("\n[DMSG] %s : core[%x,%d] exit / vpn = %x / pte2_attr = %x / pte2_ppn = %x\n",
     456    gpt_dmsg("\n[DBG] %s : core[%x,%d] exit / vpn = %x / pte2_attr = %x / pte2_ppn = %x\n",
    453457    __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn ,
    454458    pt2[2 * ix2] , pt2[2 * ix2 + 1] );
     
    727731error_t hal_gpt_copy( gpt_t  * dst_gpt,
    728732                      gpt_t  * src_gpt,
     733                      vpn_t    vpn_base,
     734                      vpn_t    vpn_size,
    729735                      bool_t   cow )
    730736{
     737    vpn_t        vpn;       // current vpn
     738
    731739    uint32_t     ix1;       // index in PT1
    732740    uint32_t     ix2;       // index in PT2
     
    737745    uint32_t   * src_pt2;   // local pointer on PT2 for SRC_GPT
    738746
    739     uint32_t     pte1;
     747        kmem_req_t   req;       // for dynamic PT2 allocation
     748
     749    uint32_t     src_pte1;
     750    uint32_t     dst_pte1;
     751
    740752    uint32_t     pte2_attr;
    741753    uint32_t     pte2_ppn;
    742     uint32_t     pte2_writable;
    743754
    744755    page_t     * page;
     
    748759    ppn_t        dst_pt2_ppn;
    749760
    750     // get pointers on PT1 for src_gpt & dst_gpt
     761gpt_dmsg("\n[DBG] %s : core[%x,%d] enter\n",
     762__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );
     763
     764    // check page size
     765    assert( (CONFIG_PPM_PAGE_SIZE == 4096) , __FUNCTION__ ,
     766    "for TSAR, the page must be 4 Kbytes\n" );
     767
     768    // check SRC_PT1 and DST_PT1 existence
     769    assert( (src_gpt->ptr != NULL) , __FUNCTION__ , "SRC_PT1 does not exist\n");
     770    assert( (dst_gpt->ptr != NULL) , __FUNCTION__ , "DST_PT1 does not exist\n");
     771
     772    // get pointers on SRC_PT1 and DST_PT1
    751773    src_pt1 = (uint32_t *)src_gpt->ptr;
    752774    dst_pt1 = (uint32_t *)dst_gpt->ptr;
    753775
     776    // scan pages in vseg
     777    for( vpn = vpn_base ; vpn < (vpn_base + vpn_size) ; vpn++ )
     778    {
     779        ix1 = TSAR_MMU_IX1_FROM_VPN( vpn );
     780        ix2 = TSAR_MMU_IX2_FROM_VPN( vpn );
     781
     782        // get SRC_PT1 entry
     783        src_pte1 = src_pt1[ix1];
     784
     785        // do nothing if SRC_PTE1 unmapped
     786                if( (src_pte1 & TSAR_MMU_MAPPED) != 0 )   // SRC_PTE1 is mapped
     787        {
     788            assert( (src_pte1 & TSAR_MMU_SMALL) , __FUNCTION__ ,
     789            "no BIG page for user process in TSAR architecture\n" );
     790
     791            // get DST_PT1 entry
     792            dst_pte1 = dst_pt1[ix1];
     793
     794            // map dst_pte1 if required
     795            if( (dst_pte1 & TSAR_MMU_MAPPED) == 0 )
     796            {
     797                // allocate one physical page for a new DST_PT2
     798                    req.type  = KMEM_PAGE;
     799                    req.size  = 0;                     // 1 small page
     800                    req.flags = AF_KERNEL | AF_ZERO;
     801                    page = (page_t *)kmem_alloc( &req );
     802
     803                if( page == NULL )
     804                {
     805                                printk("\n[ERROR] in %s : cannot allocate PT2\n", __FUNCTION__ );
     806                    return ENOMEM;
     807                }
     808
     809                // build extended pointer on page descriptor
     810                page_xp = XPTR( local_cxy , page );
     811
     812                // get PPN for this new DST_PT2
     813                dst_pt2_ppn    = (ppn_t)ppm_page2ppn( page_xp );
     814
     815                // build the new dst_pte1
     816                dst_pte1 = TSAR_MMU_MAPPED | TSAR_MMU_SMALL | dst_pt2_ppn;
     817
     818                // register it in DST_GPT
     819                dst_pt1[ix1] = dst_pte1;
     820            }
     821
     822            // get PPN and pointer on SRC_PT2
     823            src_pt2_ppn = (ppn_t)TSAR_MMU_PTBA_FROM_PTE1( src_pte1 );
     824            src_pt2     = (uint32_t *)GET_PTR( ppm_ppn2base( src_pt2_ppn ) );
     825
     826            // get PPN and pointer on DST_PT2
     827            dst_pt2_ppn = (ppn_t)TSAR_MMU_PTBA_FROM_PTE1( dst_pte1 );
     828            dst_pt2     = (uint32_t *)GET_PTR( ppm_ppn2base( dst_pt2_ppn ) );
     829
     830            // get attr and ppn from SRC_PT2
     831            pte2_attr = TSAR_MMU_ATTR_FROM_PTE2( src_pt2[2 * ix2] );
     832            pte2_ppn  = TSAR_MMU_PPN_FROM_PTE2(  src_pt2[2 * ix2 + 1] );
     833
     834            // no copy if SRC_PTE2 unmapped
     835            if( (pte2_attr & TSAR_MMU_MAPPED) != 0 )  // valid PTE2 in SRC_GPT
     836            {
     837                // set a new PTE2 in DST_PT2
     838                dst_pt2[2*ix2]     = pte2_attr;
     839                dst_pt2[2*ix2 + 1] = pte2_ppn;
     840                       
     841                // FIXME increment page descriptor refcount for the referenced page
     842
     843                // handle Copy-On-Write
     844                if( cow && (pte2_attr & TSAR_MMU_WRITABLE) )
     845                {
     846                    // reset WRITABLE flag in DST_GPT
     847                    hal_atomic_and( &dst_pt2[2*ix2] , ~TSAR_MMU_WRITABLE );
     848
     849                    // set COW flag in DST_GPT
     850                    hal_atomic_or( &dst_pt2[2*ix2] , TSAR_MMU_COW );
     851                }
     852            }
     853        }   // end if PTE1 mapped
     854    }   // end loop on vpn
     855
     856    hal_fence();
     857
     858gpt_dmsg("\n[DBG] %s : core[%x,%d] exit\n",
     859__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );
     860
     861    return 0;
     862
     863}  // end hal_gpt_copy()
     864
     865///////////////////////////////////////
     866bool_t hal_gpt_pte_is_cow( gpt_t * gpt,
     867                           vpn_t   vpn )
     868{
     869    uint32_t * pt1;
     870    uint32_t   pte1;
     871
     872    uint32_t * pt2;
     873    ppn_t      pt2_ppn;
     874
     875    uint32_t   ix1 = TSAR_MMU_IX1_FROM_VPN( vpn );
     876    uint32_t   ix2 = TSAR_MMU_IX2_FROM_VPN( vpn );
     877
     878    // get PTE1 value
     879        pt1  = gpt->ptr;
     880    pte1 = pt1[ix1];
     881
     882        if( (pte1 & TSAR_MMU_MAPPED) == 0 )    // PT1 entry not mapped
     883        {
     884                return false;
     885        }
     886
     887        if( (pte1 & TSAR_MMU_SMALL) == 0 )     // it's a PTE1
     888        {
     889                return false;
     890        }
     891    else                                   // it's a PTD1
     892    {
     893        // compute PT2 base address
     894        pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 );
     895        pt2     = (uint32_t*)GET_PTR( ppm_ppn2base( pt2_ppn ) );
     896
     897        if( pt2[2*ix2] & TSAR_MMU_COW ) return true;
     898        else                            return false;
     899    }
     900}   // end hal_gpt_pte_is_cow()
     901
     902
     903
     904
     905
     906
     907
     908
     909
     910
     911
     912
     913/* deprecated : old hal_gpt_copy [AG]
     914 
    754915    // scan the SRC_PT1
    755916        for( ix1 = 0 ; ix1 < 2048 ; ix1++ )
     
    834995}  // end hal_gpt_copy()
    835996
     997*/
  • trunk/hal/tsar_mips32/core/hal_interrupt.c

    r406 r407  
    3333                               reg_t    * regs_tbl )
    3434{
    35     irq_dmsg("\n[DMSG] %s : enter / core[%x,%d] / cycle %d\n",
    36     __FUNCTION__ , local_cxy , this->core->lid , hal_time_stamp() );
    3735
    38     // access local ICU to call the relevant ISR
     36irq_dmsg("\n[DBG] %s : core[%x,%d] enter at cycle %d\n",
     37__FUNCTION__ , local_cxy , this->core->lid , hal_time_stamp() );
     38
     39    // As ALMOS-MKH does not define a generic interrupt handler,
     40    // we directly access the local TSAR ICU to call the relevant ISR
    3941    soclib_pic_irq_handler();
    40            
    41     irq_dmsg("\n[DMSG] %s : exit / core[%x,%d] / cycle %d\n",
    42     __FUNCTION__ , local_cxy , this->core->lid , hal_time_stamp() );
     42
     43irq_dmsg("\n[DBG] %s : core[%x,%d] exit at cycle %d\n",
     44__FUNCTION__ , local_cxy , this->core->lid , hal_time_stamp() );
     45
    4346}
  • trunk/hal/tsar_mips32/core/hal_kentry.S

    r406 r407  
    189189        mtc0    $3,         $12                         # set new sr
    190190
    191         # signal that core enters kernel
    192         la      $1,     cluster_core_kernel_enter
    193         jalr    $1
    194     nop
    195 
    196191#---------------------------------------------------------------------------------------
    197192# This code call the relevant Interrupt / Exception / Syscall handler,
     
    241236# -----------------------------------------------------------------------------------
    242237kentry_exit:
    243 
    244         # signal that core exit kernel
    245     la      $1,     cluster_core_kernel_exit
    246     jalr    $1
    247     nop
    248238
    249239        # restore registers from uzone
  • trunk/hal/tsar_mips32/core/hal_kentry.h

    r406 r407  
    4141
    4242#define      UZ_MODE         0    /* c2_mode */             
    43 #define      UZ_AT           1
    44 #define      UZ_V0           2
    45 #define      UZ_V1           3
    46 #define      UZ_A0           4
    47 #define      UZ_A1           5
    48 #define      UZ_A2           6
    49 #define      UZ_A3           7
    50 #define      UZ_T0           8
    51 #define      UZ_T1           9
    52 #define      UZ_T2           10
    53 #define      UZ_T3           11
    54 #define      UZ_T4           12
    55 #define      UZ_T5           13
    56 #define      UZ_T6           14
    57 #define      UZ_T7           15
    58 #define      UZ_T8           16
    59 #define      UZ_T9           17
    60 #define      UZ_S0           18
    61 #define      UZ_S1           19
    62 #define      UZ_S2           20
    63 #define      UZ_S3           21
    64 #define      UZ_S4           22
    65 #define      UZ_S5           23
    66 #define      UZ_S6           24
    67 #define      UZ_S7           25
    68 #define      UZ_S8           26
    69 #define      UZ_GP           27
    70 #define      UZ_RA           28
    71 #define      UZ_EPC          29   /* c0_epc */
    72 #define      UZ_CR           30   /* c0_cr */
    73 #define      UZ_SP           31
    74 #define      UZ_SR           32   /* c0_sr */
     43#define      UZ_AT           1    /* at_01   */
     44#define      UZ_V0           2    /* v0_02   */
     45#define      UZ_V1           3    /* v1_03   */
     46#define      UZ_A0           4    /* a0_04   */
     47#define      UZ_A1           5    /* a1_05   */
     48#define      UZ_A2           6    /* a2_06   */
     49#define      UZ_A3           7    /* a3_07   */
     50#define      UZ_T0           8    /* t0_08   */
     51#define      UZ_T1           9    /* t1_09   */
     52#define      UZ_T2           10   /* t2_10   */
     53#define      UZ_T3           11   /* t3_11   */
     54#define      UZ_T4           12   /* t4_12   */
     55#define      UZ_T5           13   /* t5_13   */
     56#define      UZ_T6           14   /* t6_14   */
     57#define      UZ_T7           15   /* t7_15   */
     58#define      UZ_T8           16   /* t8_24   */
     59#define      UZ_T9           17   /* t9_25   */
     60#define      UZ_S0           18   /* s0_16   */
     61#define      UZ_S1           19   /* s1_17   */
     62#define      UZ_S2           20   /* s2_18   */
     63#define      UZ_S3           21   /* s3_19   */
     64#define      UZ_S4           22   /* s4_20   */
     65#define      UZ_S5           23   /* s5_21   */
     66#define      UZ_S6           24   /* s6_22   */
     67#define      UZ_S7           25   /* s7_23   */
     68#define      UZ_S8           26   /* s8_30   */
     69#define      UZ_GP           27   /* gp_28   */
     70#define      UZ_RA           28   /* ra_31   */
     71#define      UZ_EPC          29   /* c0_epc  */
     72#define      UZ_CR           30   /* c0_cr   */
     73#define      UZ_SP           31   /* sp_29   */
     74#define      UZ_SR           32   /* c0_sr   */
    7575#define      UZ_LO           33
    7676#define      UZ_HI           34
  • trunk/hal/tsar_mips32/core/hal_ppm.c

    r315 r407  
    4545// kmem memory allocator in the local cluster. This array starts in first free page
    4646// after kernel code, as defined by the 'offset' field in boot_info.
    47 //
    48 // For the TSAR architecture the MIP32 EBASE register defining the kernel entry point
    49 // fot Interrupts, Exceptions and Syscalls, has to be redefined.
    5047//////////////////////////////////////////////////////////////////////////////////////////
    5148
     
    124121}  // end hal_ppm_init()
    125122
    126 ////////////////////////////////////////
    127 void hal_core_init( boot_info_t * info )
    128 {
    129         // get relevant info from boot_info structure
    130         reg_t kentry_base = info->kentry_base;
    131123
    132     // set CP0_EBASE register
    133     hal_set_ebase( kentry_base );
    134 
    135 }  // end hal_core_init()
    136 
    137 
  • trunk/hal/tsar_mips32/core/hal_special.c

    r406 r407  
    3131
    3232struct thread_s;
    33 
    34 /////////////////////////////////
    35 void hal_set_ebase( reg_t  base )
    36 {
    37         asm volatile ("mtc0    %0,  $15,  1" : : "r" (base));
    38 }
    3933
    4034//////////////////////////
     
    200194void hal_fence()
    201195{
    202         asm volatile
    203         ( "sync    \n":: );
     196        asm volatile ("sync");
    204197}
    205198
     
    213206void hal_core_sleep()
    214207{
    215         asm volatile
    216         ("wait   \n"::);
     208        asm volatile ("wait");
    217209}
    218210
     
    221213{
    222214    asm volatile
    223     ( "1:                    \n"
     215    ( ".set noreorder        \n"
    224216      "or    $27,  %0,  $0   \n"
     217      "1:                    \n"
    225218      "addi  $27, $27,  -1   \n"
     219      "nop                   \n"
    226220      "bne   $27,  $0,  1b   \n"
    227221      "nop                   \n"
    228       : : "r" (delay) : "$27" );
     222      ".set reorder          \n"
     223      : : "r" (delay>>2) : "$27" );
    229224}
    230225
  • trunk/hal/tsar_mips32/core/hal_switch.S

    r406 r407  
    2222 */
    2323
    24 #---------------------------------------------------------------------------------
    25 # This code makes the following assumptions:
     24    .section   .switch , "ax" , @progbits
     25
     26    .global  hal_do_cpu_switch
     27    .global  hal_do_cpu_save
     28
     29    .set     noat
     30    .set     noreorder
     31
     32#---------------------------------------------------------------------------------
     33# The hal_do_cpu_switch() function makes the following assumptions:
    2634# - register $4 contains a pointer on the old thread context.
    2735# - register $5 contains a pointer on the new thread context.
    28 # When the switch is completed, it jumps to address contained in register $31
    29 # of the new context.
    30 #---------------------------------------------------------------------------------
    31 
    32     .section   .switch , "ax" , @progbits
    33 
    34     .ent     hal_do_switch
    35     .global  hal_do_switch
    36 
    37     .set     noat
    38     .set     noreorder
    39 
    40 hal_do_switch:
     36#---------------------------------------------------------------------------------
     37hal_do_cpu_switch:
    4138
    4239    move    $26,   $4                  /* $26 <= ctx_old */
     
    133130    mthi    $27                        /* restore hi from slot 26 */
    134131    lw      $27,  27*4($26)         
    135     mtlo    $27                        /* restote lo from slot 27 */
     132    mtlo    $27                        /* restore lo from slot 27 */
    136133
    137134        lw      $28,  28*4($26)         
    138135        lw      $29,  29*4($26)         
    139136        lw      $30,  30*4($26)         
    140         lw      $31,  31*4($26)         
    141 
    142         lw      $27,  32*4($26)            /* $27 <= c2_ptpr */
     137        lw      $31,  31*4($26)            /* restore ra from slot 31 */
     138
     139        lw      $27,  32*4($26)
    143140        mtc2    $27,  $0                   /* restore c2_ptpr from slot 32 */
    144141
    145         lw      $27,  35*4($26)            /* $27 <= c0_th */     
     142        lw      $27,  35*4($26)     
    146143    mtc0        $27,  $4, 2                /* restore c0_th from slot 35 */
    147144
    148         lw      $27,  33*4($26)            /* $27 <= c2_mode */
    149         lw      $26,  34*4($26)            /* $26 <= c0_sr */
     145        lw      $27,  33*4($26)
     146        lw      $26,  34*4($26)
    150147
    151148        mtc2    $27,  $1                   /* restore c2_mode from slot 33 */
     
    155152    nop
    156153
     154#---------------------------------------------------------------------------------
     155# The hal_do_cpu_save()function makes the following assumptions:
     156# - register $4 contains a pointer on the target thread context.
     157# - register $5 contains the target thread descriptor pointer.
     158# - register $6 contains the offset to add to stack pointer.
     159#---------------------------------------------------------------------------------
     160hal_do_cpu_save:
     161
     162    move    $26,  $4                  /* $26 <= context */
     163
     164    move    $27,  $5
     165        sw      $27,  35*4($26)           /* save child thread to slot 35 */
     166
     167    add     $27,  $6,  $29
     168    sw      $27,  29*4($26)           /* save (sp_29 + offset) to slot 29 */
     169
     170    mfc0    $27,  $12               
     171        sw      $27,  34*4($26)           /* save c0_sr to slot 34 */
     172
     173        mfc2    $27,  $0               
     174        sw      $27,  32*4($26)           /* save c2_ptpr to slot 32 */
     175
     176        mfc2    $27,  $1               
     177        sw      $27,  33*4($26)           /* save c2_mode to slot 33 */
     178
     179    mfc0    $27,   $14             
     180    sw      $27,   0*4($26)           /* save c0_epc to slot 0 */
     181 
     182    sw      $1,    1*4($26)         
     183    sw      $2,    2*4($26)         
     184    sw      $3,    3*4($26)         
     185    sw      $4,    4*4($26)         
     186    sw      $5,    5*4($26)         
     187    sw      $6,    6*4($26)         
     188    sw      $7,    7*4($26)         
     189
     190    sw      $8,    8*4($26)         
     191    sw      $9,    9*4($26)         
     192    sw      $10,  10*4($26)         
     193    sw      $11,  11*4($26)         
     194    sw      $12,  12*4($26)         
     195    sw      $13,  13*4($26)         
     196    sw      $14,  14*4($26)         
     197    sw      $15,  15*4($26)         
     198
     199    sw      $16,  16*4($26)         
     200    sw      $17,  17*4($26)         
     201    sw      $18,  18*4($26)         
     202    sw      $19,  19*4($26)         
     203    sw      $20,  20*4($26)         
     204    sw      $21,  21*4($26)         
     205    sw      $22,  22*4($26)         
     206    sw      $23,  23*4($26)         
     207
     208    sw      $24,  24*4($26)         
     209    sw      $25,  25*4($26)         
     210
     211    mfhi    $27                     
     212    sw      $27,  26*4($26)           /* save hi to slot 26 */
     213
     214    mflo    $27                     
     215    sw      $27,  27*4($26)           /* save lo to slot 27 */
     216
     217    sw      $28,  28*4($26)           /* save gp to slot 28 */
     218
     219    sw      $30,  30*4($26)           /* save s8 to slot 30 */
     220    sw      $31,  31*4($26)           /* save ra to slot 31 */
     221
     222    sync
     223
     224    jr      $31                       /* return to caller */
     225    nop
     226
    157227        .set reorder                   
    158228    .set at                         
    159229
    160     .end hal_do_switch
    161 
  • trunk/hal/tsar_mips32/core/hal_syscall.c

    r406 r407  
    2626#include <do_syscall.h>
    2727#include <thread.h>
     28#include <printk.h>
    2829#include <hal_kentry.h>
    2930
     
    3334                     reg_t    * regs_tbl )
    3435{
     36
     37#if(CONFIG_SYSCALL_DEBUG & 0x1)
     38printk("\n[DBG] %s : core[%x,%d] enter at cycle %d\n",
     39__FUNCTION__ , local_cxy , this->core->lid , hal_time_stamp() );
     40#endif
     41
    3542        register reg_t      arg0;
    3643        register reg_t      arg1;
     
    5865        regs_tbl[UZ_V1]   = this->errno;
    5966        regs_tbl[UZ_EPC] += 4;
     67
     68#if(CONFIG_SYSCALL_DEBUG & 0x1)
     69printk("\n[DBG] %s : core[%x,%d] exit at cycle %d\n",
     70__FUNCTION__ , local_cxy , this->core->lid , hal_time_stamp() );
     71#endif
     72
    6073}
  • trunk/hal/tsar_mips32/core/hal_types.h

    r315 r407  
    4848typedef   signed long long int      int64_t;
    4949typedef unsigned long long int     uint64_t;
    50 
    51 /***************************************************************************
    52  * Pthread related types
    53  **************************************************************************/
    54 
    55 typedef uint32_t      pthread_t;               
    56 typedef uint32_t      pthread_mutexattr_t;
    57 typedef uint32_t      pthread_barrier_t;
    58 typedef uint32_t      pthread_barrierattr_t;
    59 typedef uint32_t      sem_t;
    60 typedef uint32_t      pthread_cond_t;
    61 typedef uint32_t      pthread_condattr_t;
    62 typedef uint32_t      pthread_rwlock_t;
    63 typedef uint32_t      pthread_rwlockattr_t;
    64 typedef uint32_t      pthread_key_t;
    6550
    6651/***************************************************************************
  • trunk/hal/tsar_mips32/core/hal_uspace.c

    r315 r407  
    4545    hal_disable_irq( &save_sr );
    4646
     47
    4748        for( i = 0 ; i < wsize ; i++ )          // transfer one word per iteration
    4849        {
     
    129130}  // end hal_copy_to_uspace()
    130131
    131 //////////////////////////////////////////
    132 error_t hal_strcpy_from_uspace( char     * k_dst,
    133                                 char     * u_src,
    134                                 uint32_t   max_size )
    135 
    136 {
    137 
    138 // TODO implement the max_size handling, and error handling
    139 
    140     uint32_t save_sr;
     132//////////////////////////////////////////////
     133void hal_strcpy_from_uspace( char     * k_dst,
     134                             char     * u_src,
     135                             uint32_t   size )
     136{
     137    uint32_t save_sr;
     138
    141139    uint32_t src = (uint32_t)u_src;
    142140    uint32_t dst = (uint32_t)k_dst;
    143     uint32_t length;
    144     error_t error;
    145     paddr_t paddr;
    146 
    147     // XXX XXX XXX: must be converted, to handle faults
    148     error = vmm_v2p_translate( false , u_src , &paddr );
    149     if( error )
    150     {
    151         return EFAULT;
    152     }
    153 
    154     length = hal_strlen_from_uspace( u_src );
    155     if( length >= max_size )
    156     {
    157         return EFAULT;
    158     }
    159 
    160     hal_disable_irq( &save_sr );
    161 
    162     // loop on characters while non NUL
     141
     142    hal_disable_irq( &save_sr );
     143
     144    // loop on characters while ( (character != NUL) and (count < size )
    163145    asm volatile(
    164         "mfc2   $15,   $1           \n"   /* save current MMU_MODE          */
    165         "1:                         \n"   /* loop entry                     */
    166         "ori    $14,   $0,  0x7     \n" 
    167         "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
    168         "lb         $13,   0(%0)        \n"   /* read char from user space      */
    169         "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
    170             "sb     $13,   0(%1)        \n"   /* store char to kernel space     */
    171         "addi   %0,    %0,  1       \n"   /* increment SRC pointer          */
    172         "addi   %1,    %1,  1       \n"   /* increment DST pointer          */
    173         "bne    $13,   $0,  1b      \n"   /* test NUL                       */
     146        ".set noreorder             \n"
     147        "move   $11,   %0           \n"   /* $11 <= count == size           */
     148        "move   $12,   %1           \n"   /* $12 <= u_src                   */
     149        "move   $13,   %2           \n"   /* $13 <= k_dst                   */
     150        "mfc2   $15,   $1           \n"   /* $15 <= MMU_MODE                */
     151        "ori    $14,   $15,  0x7    \n"   /* $14 <= mode DTLB on            */
     152        "1:                         \n"
     153        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
     154        "lb     $10,   0($12)       \n"   /* read char from user space      */
     155        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
     156            "sb     $10,   0($13)       \n"   /* store char to kernel space     */
     157        "beq    $13,   $0,   2f     \n"   /* exit if char = 0               */
     158        "addi   $11,   $11, -1      \n"   /* decrement count                */
     159        "addi   $12,   $12,  1      \n"   /* increment u_src pointer        */
     160        "beq    $11,   $0,   2f     \n"   /* exit if count == 0             */
     161        "addi   $13,   $13,  1      \n"   /* increment k_src pointer        */
     162        "j                   1b     \n"   /* jump to next iteration         */
     163        "2:                         \n"
    174164        "nop                        \n"
    175         : : "r"( src ) , "r"( dst ) : "$13","$14","$15", "memory" );
    176 
    177     hal_restore_irq( save_sr );
    178 
    179     return 0;
     165        ".set reorder               \n"
     166        :
     167        : "r"(size),"r"(src),"r"(dst)
     168        : "$10","$11","$12","$13","$14","$15" );
     169       
     170    hal_restore_irq( save_sr );
     171
    180172} // hal_strcpy_from_uspace()
    181173
    182174////////////////////////////////////////////
    183 error_t hal_strcpy_to_uspace( char     * u_dst,
    184                               char     * k_src,
    185                               uint32_t   max_size )
    186 {
    187 
    188 // TODO implement the max_size handling, and error handling
    189 
    190     uint32_t save_sr;
     175void hal_strcpy_to_uspace( char     * u_dst,
     176                           char     * k_src,
     177                           uint32_t   size )
     178{
     179    uint32_t save_sr;
     180
    191181    uint32_t src = (uint32_t)k_src;
    192182    uint32_t dst = (uint32_t)u_dst;
     
    194184    hal_disable_irq( &save_sr );
    195185
    196     // loop on characters while non NUL
     186    // loop on characters while ( (character != NUL) and (count < size) )
    197187    asm volatile(
    198         "mfc2   $15,   $1           \n"   /* save current MMU_MODE          */
    199         "1:                         \n"   /* loop entry                     */
    200         "lb         $13,   0(%0)        \n"   /* read char from kernel space    */
    201         "ori    $14,   $0,  0x7     \n" 
    202         "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
    203             "sb     $13,   0(%1)        \n"   /* store char to user space       */
    204         "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
    205         "addi   %0,    %0,  1       \n"   /* increment SRC pointer          */
    206         "addi   %1,    %1,  1       \n"   /* increment DST pointer          */
    207         "bne    $13,   $0,  1b      \n"   /* test NUL                       */
     188        ".set noreorder             \n"
     189        "move   $11,   %0           \n"   /* $11 <= count == size           */
     190        "move   $12,   %1           \n"   /* $12 <= k_src                   */
     191        "move   $13,   %2           \n"   /* $13 <= u_dst                   */
     192        "mfc2   $15,   $1           \n"   /* $15 <= MMU_MODE                */
     193        "ori    $14,   $15,  0x7    \n"   /* $14 <= mode DTLB on            */
     194        "1:                         \n"
     195        "lb     $10,   0($12)       \n"   /* read char from kernel space    */
     196        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
     197            "sb     $10,   0($13)       \n"   /* store char to user space       */
     198        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
     199        "beq    $13,   $0,   2f     \n"   /* exit if char == 0              */
     200        "addi   $11,   $11, -1      \n"   /* decrement count                */
     201        "addi   $12,   $12,  1      \n"   /* increment k_src pointer        */
     202        "beq    $11,   $0,   2f     \n"   /* exit if count == size          */
     203        "addi   $13,   $13,  1      \n"   /* increment u_src pointer        */
     204        "j                   1b     \n"   /* jump to next iteration         */
     205        "2:                         \n"
    208206        "nop                        \n"
    209         : : "r"( src ) , "r"( dst ) : "$13","$14","$15", "memory" );
    210 
    211     hal_restore_irq( save_sr );
    212 
    213     return 0;
     207        ".set reorder               \n"
     208        :
     209        : "r"(size),"r"(src),"r"(dst)
     210        : "$10","$11","$12","$13","$14","$15" );
     211       
     212    hal_restore_irq( save_sr );
     213
    214214} // hal_strcpy_to_uspace()
    215215
     
    218218{
    219219    uint32_t save_sr;
    220     uint32_t str      = (uint32_t)u_str;
    221     uint32_t count    = 0;
     220    uint32_t count = 0;
     221
     222    uint32_t str = (uint32_t)u_str;
    222223
    223224    hal_disable_irq( &save_sr );
    224225
    225226        asm volatile(
    226         "ori    $15,   %0,   0      \n"   /* $15 <= count                   */
     227        ".set noreorder             \n"
    227228        "ori    $13,   %1,   0      \n"   /* $13 <= str                     */
    228    
    229         "mfc2   $15,   $1           \n"   /* save   MMU_MODE                */
    230         "ori    $14,   $0,   0x7    \n"   /* $14 <= mode DTLB on            */
    231         "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
    232 
     229        "mfc2   $15,   $1           \n"   /* $15 <= MMU_MODE                */
     230        "ori    $14,   $15,  0x7    \n"   /* $14 <= mode DTLB on            */
     231        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
    233232        "1:                         \n"
    234         "lb         $13,   0(%0)        \n"   /* read char from kernel space    */
     233        "lb         $12,   0($13)       \n"   /* read char from user space      */
    235234        "addi   $13,   $13,  1      \n"   /* increment address              */
    236         "bne    $13,   $0,   1b     \n"   /* loop until NUL found           */
    237         "addi   $15,   $15,  1      \n"   /* increment counter              */
    238 
    239         "mtc2   $14,   $1                       \n"   /* restore MMU_MODE               */
    240         : "+r"(count) : "r"(str) : "$13","$14","$15" );
     235        "bne    $12,   $0,   1b     \n"   /* loop until NUL found           */
     236        "addi   %0,    %0,   1      \n"   /* increment count                */
     237        "mtc2   $15,   $1                       \n"   /* restore MMU_MODE               */
     238        ".set reorder               \n"
     239        : "+r"(count)
     240        : "r"(str)
     241        : "$12","$13","$14","$15" );
    241242
    242243    hal_restore_irq( save_sr );
Note: See TracChangeset for help on using the changeset viewer.