Changeset 407 for trunk/hal


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

First implementation of fork/exec.

Location:
trunk/hal
Files:
2 added
28 edited
2 copied
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/hal/generic/hal_context.h

    r337 r407  
    4040
    4141/****************************************************************************************
    42  * This function allocates, from the local cluster, the physical memory required for
    43  * the thread CPU context, initialises it, and links the context to the thread.
     42 * This function allocates memory for a CPU context and links it to the thread
     43 * identified by the <thread> argument. The context is not initialised.
     44 ****************************************************************************************
     45 * @ return 0 if success / return -1 if failure.
     46 ***************************************************************************************/
     47error_t hal_cpu_context_alloc( struct thread_s * thread );
     48
     49/****************************************************************************************
     50 * This function allocates memory for a CPU context, initialize it from scratch,
     51 * and links it to the thread identified by the <thread> argument.
    4452 ****************************************************************************************
    4553 * @ thread  : pointer on the thread descriptor.
    46  * @ return 0 if success / return ENOMEM if error
     54 * @ return 0 if success / return -1 if failure.
    4755 ***************************************************************************************/
    4856error_t hal_cpu_context_create( struct thread_s * thread );
    4957
    5058/****************************************************************************************
    51  * This function allocates, from the local cluster, the physical memory required for
    52  * a thread CPU context, initialises it from values contained in "src" thread context,
    53  * and links the context to the "dst" thread.
     59 * This function display the following slots of a thread CPU context:
     60 * - GPR : gp_28 , sp_29 , ra_31
     61 * - CP0 : c0_sr , c0_th , c0_epc
     62 * - CP2 : c2_ptpr , c2-mode
    5463 ****************************************************************************************
    55  * @ dst  : pointer on the destination thread descriptor.
    56  * @ src  : pointer on the source thread descriptor.
    57  * @ return 0 if success / return ENOMEM if error
     64 * @ thread  : local pointer on the thread descriptor.
    5865 ***************************************************************************************/
    59 error_t hal_cpu_context_copy( struct thread_s * dst,
    60                               struct thread_s * src );
     66void hal_cpu_context_display( struct thread_s * thread );
    6167
    6268/****************************************************************************************
     
    6773void hal_cpu_context_destroy( struct thread_s * thread );
    6874
    69 /****************************************************************************************
    70  * This function performs a context switch, saving the CPU register values into the
    71  * old thread, and initializing these registers with the values of the new thread.
    72  ****************************************************************************************
    73  * @ old     : pointer on current thread.
    74  * @ new     : pointer on the thread we want to switch to.
    75  ***************************************************************************************/
    76 void hal_cpu_context_switch( struct thread_s * old , struct thread_s * new );
     75
     76
     77
     78
     79
    7780
    7881/****************************************************************************************
    79  * This function loads the relevant CPU registers from values contained in
    80  * the thread context. It should be called for a thread that has not been executed yet.
    81  * It reset the loadable flag in thread descriptor.
     82 * This function allocates memory for a FPU context, reset all entries,
     83 * and links it to the thread identified by the <thread> argument.
    8284 ****************************************************************************************
    8385 * @ thread  : pointer on the thread descriptor.
     86 * @ return 0 if success / return -1 if failure.
    8487 ***************************************************************************************/
    85 void hal_cpu_context_load( struct thread_s * thread );
     88error_t hal_fpu_context_alloc( struct thread_s * thread );
    8689
    8790/****************************************************************************************
    88  * This function allocates, from the local cluster, the physical memory required for
    89  * the thread FPU context, and initialises the thread pointer.
    90  ****************************************************************************************
    91  * @ thread  : pointer on the thread descriptor.
    92  * @ return 0 if success / return ENOMEM if error
    93  ***************************************************************************************/
    94 error_t hal_fpu_context_create( struct thread_s * thread );
    95 
    96 /****************************************************************************************
    97  * This function allocates, from the local cluster, the physical memory required for
    98  * a thread FPU context, initialises it from values contained in "src" thread context,
    99  * and link the context to the "dst" thread.
     91 * This function copies a FPU context defined by the <src> argument to the FPU context
     92 * defined by the <dst> argument. It is used by the fork system call.
    10093 ****************************************************************************************
    10194 * @ dst  : pointer on the destination thread descriptor.
    10295 * @ src  : pointer on the source thread descriptor.
    103  * @ return 0 if success / return ENOMEM if error
    10496 ***************************************************************************************/
    105 error_t hal_fpu_context_copy( struct thread_s * dst,
     97void hal_fpu_context_copy( struct thread_s * dst,
    10698                           struct thread_s * src );
    10799
  • trunk/hal/generic/hal_gpt.h

    r406 r407  
    4343
    4444struct page_s;
     45struct process_s;
    4546
    4647/****************************************************************************************
     
    4849 ***************************************************************************************/
    4950
    50 #define GPT_MAPPED      0x0001  /*! PTE is mapped                                 */
    51 #define GPT_SMALL       0x0002  /*! PTE is a small page                           */
    52 #define GPT_READABLE    0x0004  /*! PTE is readable                               */
    53 #define GPT_WRITABLE    0x0008  /*! PTE is writable                               */
    54 #define GPT_EXECUTABLE  0x0010  /*! PTE is executable                             */
    55 #define GPT_CACHABLE    0x0020  /*! PTE can be cached                             */
    56 #define GPT_USER        0x0040  /*! PTE is user accessible                        */
    57 #define GPT_DIRTY       0x0080  /*! PTE has been "recently" written               */
    58 #define GPT_ACCESSED    0x0100  /*! PTE has been "recently" accessed              */
    59 #define GPT_GLOBAL      0x0200  /*! PTE is kept in TLB at context switch          */
    60 #define GPT_COW         0x0400  /*! PTE must be copied on write                   */
    61 #define GPT_SWAP        0x0800  /*! PTE swapped on disk (not implemented yet)     */
    62 #define GPT_LOCKED      0x1000  /*! PTE is protected against concurrent access    */
     51#define GPT_MAPPED      0x0001       /*! PTE is mapped                                 */
     52#define GPT_SMALL       0x0002       /*! PTE is a small page                           */
     53#define GPT_READABLE    0x0004       /*! PTE is readable                               */
     54#define GPT_WRITABLE    0x0008       /*! PTE is writable                               */
     55#define GPT_EXECUTABLE  0x0010       /*! PTE is executable                             */
     56#define GPT_CACHABLE    0x0020       /*! PTE can be cached                             */
     57#define GPT_USER        0x0040       /*! PTE is user accessible                        */
     58#define GPT_DIRTY       0x0080       /*! PTE has been "recently" written               */
     59#define GPT_ACCESSED    0x0100       /*! PTE has been "recently" accessed              */
     60#define GPT_GLOBAL      0x0200       /*! PTE is kept in TLB at context switch          */
     61#define GPT_COW         0x0400       /*! PTE must be copied on write                   */
     62#define GPT_SWAP        0x0800       /*! PTE swapped on disk (not implemented yet)     */
     63#define GPT_LOCKED      0x1000       /*! PTE is protected against concurrent access    */
    6364
    6465/****************************************************************************************
     
    7071        void           * ptr;    /*! local pointer on GPT root                             */
    7172        ppn_t            ppn;    /*! PPN of GPT root                                       */
    72         struct page_s  * page;   /*! local pointer on GPT root page descriptor             */
    7373}
    7474gpt_t;
     
    9898 * This function prints on the kernel terminal the content of a generic page table.
    9999 ****************************************************************************************
    100  * @ gpt     : pointer on generic page table descriptor.
    101  * @ pid     : process identifier.
    102  ***************************************************************************************/
    103 void hal_gpt_print( gpt_t * gpt,
    104                     pid_t   pid );
     100 * @ process : pointer on local process descriptor.
     101 ***************************************************************************************/
     102void hal_gpt_display( struct process_s * process );
    105103
    106104/****************************************************************************************
     
    169167
    170168/****************************************************************************************
    171  * This function copies all valid entries from the source <src_gpt> to the <dst_gpt>.
    172  * The <src_gpt> and the <dst_gpt> point on the same physical pages.
    173  * If the <cow> argument is true, the GPT_WRITABLE attribute is reset for all writable
    174  * entries in both <src_gpt> and <dst_gpt>, and the PG_COW flag is registered in all
    175  * writable physical page descriptors, to support the Copy-On-Write mechanism.
     169 * This function is used to implement the "fork" system call: It copies all valid GPT
     170 * entries for a given vseg identified by the <vpn_base> and <vpn_size> arguments,
     171 * from the source <src_gpt> to the <dst_gpt>.
     172 * It optionnally activates the "Copy on Write" mechanism: when the <cow> argument is
     173 * true, the GPT_WRITABLE flag is reset, and the GPT_COW flag is set for each valid
     174 * entry in the destination GPT (The data page will be dynamically allocated an copied
     175 * when a write access is detected).
    176176 ****************************************************************************************
    177177 * @ dst_gpt   : [in]  pointer on the destination GPT.
    178178 * @ src_gpt   : [in]  pointer on the source GPT.
     179 * @ vpn_base  : [in]  first vpn in vseg.
     180 * @ vpn_size  : [in]  number of pages in vseg.
    179181 * @ cow       : [in]  activate the COPY-On-Write mechanism if true.
    180182 ***************************************************************************************/
    181183error_t hal_gpt_copy( gpt_t    * dst_gpt,
    182184                      gpt_t    * src_gpt,
     185                      vpn_t      vpn_base,
     186                      vpn_t      vpn_size,
    183187                      bool_t     cow );
    184188
     189/****************************************************************************************
     190 * This function returns GPT_COW flag for a PTE defined by <gpt> and <vpn> arguments.
     191 ****************************************************************************************
     192 * @ gpt       : [in]  pointer on the page table
     193 * @ vpn       : [in]  virtual page number
     194 * @ returns true if GPT_COW is set.
     195 ***************************************************************************************/
     196bool_t hal_gpt_pte_is_cow( gpt_t * gpt,
     197                           vpn_t   vpn );
     198
    185199
    186200#endif  /* _GPT_H_ */
  • trunk/hal/generic/hal_ppm.h

    r315 r407  
    5454error_t hal_ppm_init( boot_info_t * info );
    5555
    56 /****************************************************************************************
    57  * This function initializes the architecture specific core registers, for the
    58  * calling core. It is executed by all cores during kernel_init().
    59  ****************************************************************************************
    60  * @ info       : pointer on the boot_info structure.
    61  ***************************************************************************************/
    62 void hal_core_init( boot_info_t * info );
    63 
    6456#endif  /* HAL_PPM_H_ */
  • trunk/hal/generic/hal_remote.h

    r313 r407  
    133133 * @ xp      : extended pointer to remote data
    134134 * @ mask    : local mask value.
    135  * @ return old value (before increment) of the remote integer
     135 * @ return old value (before mask) of the remote integer
    136136 ****************************************************************************************/
    137137uint32_t hal_remote_atomic_and( xptr_t    xp,
     
    144144 * @ xp      : extended pointer to remote data
    145145 * @ mask    : local mask value.
    146  * @ return old value (before increment) of the remote integer
     146 * @ return old value (before mask) of the remote integer
    147147 ****************************************************************************************/
    148148uint32_t hal_remote_atomic_or( xptr_t    xp,
  • trunk/hal/generic/hal_special.h

    r401 r407  
    7070
    7171/*****************************************************************************************
    72  * This function registers a new kentry base address in the relevant core register.
    73  ****************************************************************************************/
    74 void hal_set_ebase( reg_t base );
    75 
    76 /*****************************************************************************************
    7772 * This function writes into the proper core register to enable the floating point unit.
    7873 ****************************************************************************************/
     
    128123
    129124/*****************************************************************************************
    130  * This function returns after a fixed delay of (4 * delay) cycles.
     125 * This function returns after approximately <delay> cycles.
     126 * @ delay  : number of cycles.
    131127 ****************************************************************************************/
    132 void hal_fixed_delay();
     128void hal_fixed_delay( uint32_t delay );
    133129
    134130/*****************************************************************************************
  • trunk/hal/generic/hal_switch.h

    r405 r407  
    11/*
    2  * hal_switch.h - TSAR architecture context switch function
     2 * hal_switch.h - Generic architecture context switch function
    33 *
    4  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
    5  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     4 * Authorg   Alain Greiner  (2017)
     5 *
     6 * Copyright (c) UPMC Sorbonne Universites
    67 *
    7  * This file is part of ALMOS-kernel.
     8 * This file is part of ALMOS-MKH.
    89 *
    9  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1011 * under the terms of the GNU General Public License as published by
    1112 * the Free Software Foundation; version 2.0 of the License.
    1213 *
    13  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1415 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1718 *
    1819 * You should have received a copy of the GNU General Public License
    19  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2021 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2122 */
     
    2425#define _HAL_SWITCH_H_
    2526
     27struct thread_s;
     28
    2629/*************************************************************************************
    27  * The hal_do_switch() function is an assembly level code called by the
    28  * hal_cpu_context_switch() function to make the actual context swich.
    29  * The hal_cpu_context_t structure used to store a core context is defined
    30  * in the TSAR specific hal_context.c file.
    31  * The following core registers are saved in the old context & and restored
    32  * from the new context:
    33  * - GPR : all, but (zero, k0, k1), plus (hi, lo)
    34  * - CP0 : c0_th , c0_sr
    35  * - CP2 : c2_ptpr , C2_mode, C2_epc
    36  * When the switch is completed, it jumps to address contained in register $31
    37  * of the new context.
     30 * The hal_do_cpu_switch() function is an assembly level function, called by the
     31 * sched_yield() function, to make a CPU context switch.
     32 * The current thread CPU context is identified by the <ctx_current> pointer.
     33 * The new thread CPU context is identified by the <ctx_next> pointer.
     34 * The architecture specific hal_cpu_context_t structure used to store a CPU context
     35 * is defined in the architecture specific hal_context.c file.
     36 * This function does NOT modify any register before saving values into context.
     37 * When the switch is completed, it jumps to address contained in the relevant
     38 * register of the new thread CPU context.
    3839 *************************************************************************************
    39  * @ ctx_old  : local pointer on the old thread context.
    40  * @ ctx_new  : local pointer on the new thread context.
     40 * @ ctx_current  : local pointer on current thread CPU context.
     41 * @ ctx_next     : local pointer on new thread CPU context.
    4142 ************************************************************************************/
    42 void hal_do_switch( void * ctx_old,
    43                     void * ctx_new );
     43void hal_do_cpu_switch( void * ctx_old,
     44                        void * ctx_new );
    4445
     46/*************************************************************************************
     47 * The hal_do_cpu_save() function is an assembly level function, called by the
     48 * sys_fork() system call to save the parent thread register values to a child
     49 * CPU context identified by the <ctx> pointer.
     50 * This function does NOT modify any register before saving values into context.
     51 * The architecture specific hal_cpu_context_t structure used to store a CPU context
     52 * is defined in the architecture specific hal_context.c file.
     53 * Two context slots are not saved from the calling thread registers values :
     54 * - the "current_thread" slot is set from the value defined by the <thread> argument.
     55 * - the "stack_pointer" slot is set by adding the value defined by the <offset>
     56 *   argument to the current sp register value.
     57 * When the save is completed, it simply returns to the calling function.
     58 *************************************************************************************
     59 * @ ctx     : local pointer on target thread CPU context.
     60 * @ thread  : local pointer on target thread descriptor.
     61 * @ offset  : kernel stack pointer offset (&child - &parent).
     62 ************************************************************************************/
     63void hal_do_cpu_save( void * ctx,
     64                      void * thread,
     65                      int    offset );
    4566
    4667#endif  /* _HAL_SWITCH_H_ */
  • trunk/hal/generic/hal_syscall.h

    r405 r407  
    11/*
    2  * hal_syscall.h - Architecture specific syscall handler API definition.
     2 * hal_kernel_syscall.h - Architecture specific kernel_side syscall handler API definition.
    33 *
    44 * Author      Alain Greiner (2016,2017)
     
    2222 */
    2323
    24 #ifndef _HAL_SYSCALL_H_
    25 #define _HAL_SYSCALL_H_
     24#ifndef _HAL_KERNEL_SYSCALL_H_
     25#define _HAL_KERNEL_SYSCALL_H_
    2626
    2727#include <hal_types.h>
    2828
    2929//////////////////////////////////////////////////////////////////////////////////////////
    30 //     ARchitecture specific syscall handler API
     30//     Kernel-side syscall handler API
    3131//
    32 // The calling thread context has been saved in the cpu_uzone array,
    33 // stored in the user thread descriptor by the hal_kentry function.
    34 // The architecture specific handler must use this array to get the syscall
    35 // index and the arguments values.
     32// This hal_do_syscall() function extract from the regs_tbl[] array the syscall index,
     33// and the four syscall arguments. Then it calls the generic do_syscall() kernel function,
     34// that call itself the relevant kernel function, depending on the syscall index.
    3635//
    3736// Any architecture specific implementation must implement this API.
     
    4443
    4544/*****************************************************************************************
    46  * This function implements the ALMOS-MKH syscall handler.
     45 * This function implements the ALMOS-MKH kernel_side syscall handler.
    4746 *****************************************************************************************
    4847 * @ this     : pointer on the calling thread.
     
    5352
    5453
    55 #endif   // _HAL_SYSCALL_H_
     54#endif   // _HAL_KERNEL_SYSCALL_H_
  • trunk/hal/generic/hal_uspace.h

    r299 r407  
    6262
    6363/*****************************************************************************************
    64  * This function tranfers a NUL terminated string from the user space to the kernel space.
     64 * This function tranfers a string from the user space to the kernel space.
     65 * The transfer stops after the first encountered NUL character, and no more than
     66 * <max_size> characters are actually copied to target buffer.
    6567 * If the kernel uses physical addresses, it activates the MMU to access the user buffer.
    66  * TODO : implement the max_size argument handling, and error handling
    6768 *****************************************************************************************
    6869 * @ u_dst     : destination buffer address in user space.
     
    7071 * @ max_size  : max number of characters to be copied.
    7172 ****************************************************************************************/
    72 extern error_t hal_strcpy_from_uspace( char     * k_dst,
    73                                        char     * u_src,
    74                                        uint32_t   max_size );
     73extern void hal_strcpy_from_uspace( char     * k_dst,
     74                                    char     * u_src,
     75                                    uint32_t   max_size );
    7576
    7677/*****************************************************************************************
    77  * This function tranfers a NUL terminated string from the kernel space to the user space.
     78 * This function tranfers a string from the kernel space to the user space.
     79 * The transfer stops after the first encountered NUL character, and no more than
     80 * <max_size> characters are actually copied to target buffer.
    7881 * If the kernel uses physical addresses, it activates the MMU to access the user buffer.
    79  * TODO : implement the max_size argument handling, and error handling
    8082 *****************************************************************************************
    8183 * @ u_dst     : destination buffer address in user space.
     
    8385 * @ max_size  : max number of characters to be copied.
    8486 ****************************************************************************************/
    85 extern error_t hal_strcpy_to_uspace( char     * u_dst,
    86                                      char     * k_src,
    87                                      uint32_t   max_size );
     87extern void hal_strcpy_to_uspace( char     * u_dst,
     88                                  char     * k_src,
     89                                  uint32_t   max_size );
    8890
    8991/*****************************************************************************************
  • 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 );
  • trunk/hal/tsar_mips32/drivers/soclib_bdv.c

    r296 r407  
    104104
    105105    // waiting policy  depends on the command type
     106    // - for IOC_READ / IOC_WRITE commands, this function is called by the server thread
     107    // - for IOC_SYNC_READ command, this function is directly called by the client thread
    106108
    107     if( cmd_type == IOC_SYNC_READ )                  // polling policy
     109    if( cmd_type == IOC_SYNC_READ )                   // status polling policy
    108110    {
    109111        uint32_t status;
     
    131133    {
    132134        thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
    133         sched_yield( NULL );
     135        sched_yield();
     136
     137        // the IO operation status is reported in the command by the ISR
    134138    }
    135139   
  • trunk/hal/tsar_mips32/drivers/soclib_dma.c

    r296 r407  
    9191    // Block and deschedule server thread
    9292    thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
    93     sched_yield( NULL );
     93    sched_yield();
    9494   
    9595} // soclib_dma_cmd()
  • trunk/hal/tsar_mips32/drivers/soclib_hba.c

    r296 r407  
    197197            else                                // retry if asynchronous access.
    198198            {
    199                 sched_yield( NULL );
     199                sched_yield();
    200200            }
    201201        }
     
    240240    {
    241241        thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
    242         sched_yield( NULL );
     242        sched_yield();
    243243    }
    244244           
  • trunk/hal/tsar_mips32/drivers/soclib_pic.c

    r406 r407  
    4343extern  lapic_input_t  lapic_input;  // defined in dev_pic.h / allocated in kernel_init.c
    4444 
     45
     46
    4547//////////////////////////////////////////////////////////////////////////////////////
    4648//        SOCLIB PIC private functions
     
    127129                           &pti_status );
    128130
    129     irq_dmsg("\n[DMSG] %s : enter for core[%x,%d] / WTI = %x / HWI = %x / WTI = %x\n",
     131    irq_dmsg("\n[DBG] %s : core[%x,%d] enter / WTI = %x / HWI = %x / WTI = %x\n",
    130132             __FUNCTION__ , local_cxy , core->lid , wti_status , hwi_status , pti_status );
    131133
     
    140142            assert( (index == core->lid) , __FUNCTION__ , "illegal IPI index" );
    141143
    142             irq_dmsg("\n[DMSG] %s : core[%x,%d] received an IPI / cycle %d\n",
     144            irq_dmsg("\n[DBG] %s : core[%x,%d] received an IPI / cycle %d\n",
    143145             __FUNCTION__ , local_cxy , core->lid , hal_time_stamp() );
    144146
     
    168170            else                                 // call relevant ISR
    169171            {
    170                 irq_dmsg("\n[DMSG] %s : core[%x,%d] received external WTI %d / cycle %d\n",
     172                irq_dmsg("\n[DBG] %s : core[%x,%d] received external WTI %d / cycle %d\n",
    171173                __FUNCTION__ , local_cxy , core->lid , index , hal_time_stamp() );
    172174
     
    196198        else                    // call relevant ISR
    197199        {
    198             irq_dmsg("\n[DMSG] %s : core[%x,%d] received HWI %d / cycle %d\n",
     200            irq_dmsg("\n[DBG] %s : core[%x,%d] received HWI %d / cycle %d\n",
    199201            __FUNCTION__ , local_cxy , core->lid , index , hal_time_stamp() );
    200202
     
    208210        index = pti_status - 1;
    209211
    210         irq_dmsg("\n[DMSG] %s : core[%x,%d] received PTI %d / cycle %d\n",
     212        irq_dmsg("\n[DBG] %s : core[%x,%d] received PTI %d / cycle %d\n",
    211213        __FUNCTION__ , core->lid , local_cxy , index , hal_time_stamp() );
    212214
     
    248250    uint32_t * iopic_seg_ptr = (uint32_t *)GET_PTR( pic->base );
    249251
    250     // reset the IOPIC component registers : mask all input IRQs
     252    // reset the IOPIC component registers : disable all input IRQs
    251253    for( i = 0 ; i < CONFIG_MAX_EXTERNAL_IRQS ; i++ )
    252254    {
     
    364366    {
    365367        // get external IRQ index
    366         uint32_t  irq_id;   
    367         if     (  func == DEV_FUNC_IOC            ) irq_id = iopic_input.ioc[channel];
    368         else if(  func == DEV_FUNC_TXT            ) irq_id = iopic_input.txt[channel];
    369         else if( (func == DEV_FUNC_NIC) &&  is_rx ) irq_id = iopic_input.nic_rx[channel];
    370         else if( (func == DEV_FUNC_NIC) && !is_rx ) irq_id = iopic_input.nic_tx[channel];
    371         else if(  func == DEV_FUNC_IOB            ) irq_id = iopic_input.iob;
     368        uint32_t  hwi_id;   
     369        if     (  func == DEV_FUNC_IOC            ) hwi_id = iopic_input.ioc[channel];
     370        else if(  func == DEV_FUNC_TXT  &&  is_rx ) hwi_id = iopic_input.txt_rx[channel];
     371        else if(  func == DEV_FUNC_TXT  && !is_rx ) hwi_id = iopic_input.txt_tx[channel];
     372        else if( (func == DEV_FUNC_NIC) &&  is_rx ) hwi_id = iopic_input.nic_rx[channel];
     373        else if( (func == DEV_FUNC_NIC) && !is_rx ) hwi_id = iopic_input.nic_tx[channel];
     374        else if(  func == DEV_FUNC_IOB            ) hwi_id = iopic_input.iob;
    372375        else      assert( false , __FUNCTION__ , "illegal device functionnal type\n");
    373376
     
    385388        uint32_t lsb_wdata = (uint32_t)wti_xp;
    386389        uint32_t msb_wdata = (uint32_t)(wti_xp >> 32);
    387         xptr_t   lsb_xp = XPTR( seg_pic_cxy , seg_pic_ptr+irq_id*IOPIC_SPAN+IOPIC_ADDRESS );
    388         xptr_t   msb_xp = XPTR( seg_pic_cxy , seg_pic_ptr+irq_id*IOPIC_SPAN+IOPIC_EXTEND );
     390        xptr_t   lsb_xp = XPTR( seg_pic_cxy , seg_pic_ptr+hwi_id*IOPIC_SPAN+IOPIC_ADDRESS );
     391        xptr_t   msb_xp = XPTR( seg_pic_cxy , seg_pic_ptr+hwi_id*IOPIC_SPAN+IOPIC_EXTEND );
    389392        hal_remote_sw( lsb_xp , lsb_wdata );
    390393        hal_remote_sw( msb_xp , msb_wdata );
    391394
    392         // unmask IRQ in IOPIC
    393         hal_remote_sw( XPTR( seg_pic_cxy , seg_pic_ptr+irq_id*IOPIC_SPAN+IOPIC_MASK ), 1 );
     395        // enable IRQ in IOPIC
     396        hal_remote_sw( XPTR( seg_pic_cxy , seg_pic_ptr+hwi_id*IOPIC_SPAN+IOPIC_MASK ), 1 );
    394397
    395398        // update the WTI interrupt vector for core[lid]
    396399        core_t * core = &LOCAL_CLUSTER->core_tbl[lid];
    397400        ((soclib_pic_core_t *)core->pic_extend)->wti_vector[wti_id] = src_chdev;
     401
     402pic_dmsg("\n[DBG] %s : %s / channel = %d / rx = %d / hwi_id = %d / wti_id = %d / cluster = %x\n",
     403__FUNCTION__ , chdev_func_str( func ) , channel , is_rx , hwi_id , wti_id , local_cxy );
     404
    398405    }
    399406    else if( (func == DEV_FUNC_DMA) || (func == DEV_FUNC_MMC) )   // internal IRQ => HWI
     
    411418        core_t * core = &LOCAL_CLUSTER->core_tbl[lid];
    412419        ((soclib_pic_core_t *)core->pic_extend)->wti_vector[hwi_id] = src_chdev;
     420
     421pic_dmsg("\n[DBG] %s : %s / channel = %d / hwi_id = %d / cluster = %x\n",
     422__FUNCTION__ , chdev_func_str( func ) , channel , hwi_id , local_cxy );
     423
    413424    }
    414425    else
     
    494505
    495506    // set period value in XCU (in cycles)
    496     uint32_t cycles = period * SOCLIB_CYCLES_PER_MS * CONFIG_SCHED_TICK_MS_PERIOD;
     507    uint32_t cycles = period * SOCLIB_CYCLES_PER_MS;
    497508    base[(XCU_PTI_PER << 5) | lid] = cycles;
    498509
     
    525536}
    526537
    527 
    528 
     538/////////////////////////
     539void soclib_pic_ack_ipi()
     540{
     541    // get calling core local index
     542    lid_t      lid  = CURRENT_THREAD->core->lid;
     543
     544    // get pointer on local XCU segment base
     545    uint32_t * base = soclib_pic_xcu_base();
     546
     547    // acknowlege IPI
     548    uint32_t   ack  = base[(XCU_WTI_REG << 5) | lid];
     549
     550    // we must make a fake use for ack value to avoid a warning
     551    if( (ack + 1) == 0 ) panic("this should never happen");
     552}
     553   
     554
  • trunk/hal/tsar_mips32/drivers/soclib_pic.h

    r380 r407  
    11/*
    2  * soclib_pic.c - soclib PIC driver definition.
     2 * soclib_pic.h - soclib PIC driver definition.
    33 *
    44 * Author  Alain Greiner (2016,2017)
     
    9090#define SOCLIB_MAX_PTI         16
    9191
    92 #define SOCLIB_CYCLES_PER_MS   1000    // for a SystemC virtual prototype
     92#define SOCLIB_CYCLES_PER_MS   60    // SystemC virtual prototype at 60 KHz
    9393
    9494/******************************************************************************************
     
    238238
    239239/******************************************************************************************
    240  * This function activates the WTI[lid] in the local cluster, wherehe lid is the calling
     240 * This function activates the WTI[lid] in the local cluster, where lid is the calling
    241241 * core local index.
    242242 *****************************************************************************************/
     
    252252void soclib_pic_send_ipi( cxy_t    cxy,
    253253                          lid_t    lid );
     254
     255/******************************************************************************************
     256 * This function acknowleges the WTI[lid] in the local cluster, where lid is the calling
     257 * core local index.
     258 *****************************************************************************************/
     259void soclib_pic_ack_ipi();
    254260
    255261
  • trunk/hal/tsar_mips32/drivers/soclib_tty.c

    r296 r407  
    2727#include <remote_spinlock.h>
    2828#include <thread.h>
     29#include <printk.h>
    2930#include <hal_special.h>
     31
     32#if CONFIG_READ_DEBUG
     33extern uint32_t  enter_tty_cmd;
     34extern uint32_t  exit_tty_cmd;
     35
     36extern uint32_t  enter_tty_isr;
     37extern uint32_t  exit_tty_isr;
     38#endif
    3039
    3140///////////////////////////////////////
    3241void soclib_tty_init( chdev_t * chdev )
    3342{
     43    xptr_t reg_xp;
     44
    3445    chdev->cmd = &soclib_tty_cmd;
    3546    chdev->isr = &soclib_tty_isr;
    36 
    37     // get extended pointer on TTY-SOCLIB peripheral base address
    38     xptr_t tty_xp = chdev->base;
     47    chdev->aux = &soclib_tty_aux;
     48
     49    // get TTY channel and extended pointer on TTY peripheral base address
     50    xptr_t   tty_xp  = chdev->base;
     51    uint32_t channel = chdev->channel;
    3952
    4053    // get SOCLIB_TTY device cluster and local pointer
     
    4255    uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp );
    4356
    44     // mask both TTY_RX_IRQ and TTY_TX_IRQ
    45     hal_remote_sw( XPTR( tty_cxy , tty_ptr + TTY_CONFIG_REG ) , 0 );
     57    // reset TTY_RX_IRQ_ENABLE
     58    reg_xp = XPTR( tty_cxy , tty_ptr + (channel * TTY_SPAN) + TTY_RX_IRQ_ENABLE );
     59    hal_remote_sw( reg_xp , 0 );
     60
     61    // reset TTY_TX_IRQ_ENABLE
     62    reg_xp = XPTR( tty_cxy , tty_ptr + (channel * TTY_SPAN) + TTY_TX_IRQ_ENABLE );
     63    hal_remote_sw( reg_xp , 0 );
    4664}
    4765
     
    4967void __attribute__ ((noinline)) soclib_tty_cmd( xptr_t th_xp )
    5068{
     69
     70#if CONFIG_READ_DEBUG
     71enter_tty_cmd = hal_time_stamp();
     72#endif
     73
     74txt_dmsg("\n[DBG] %s : core[%x,%d] / DEV thread enter / cycle %d\n",
     75__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
     76
    5177    // get client thread cluster and local pointer
    5278    cxy_t      th_cxy = GET_CXY( th_xp );
     
    5783    xptr_t   dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) );
    5884
     85    assert( (type == TXT_READ) || (type == TXT_WRITE) , __FUNCTION__, "illegal command type");
     86
    5987    // get TXT device cluster and local pointer
    6088    cxy_t     dev_cxy = GET_CXY( dev_xp );
     
    72100    uint32_t * base    = tty_ptr + TTY_SPAN * channel;
    73101
    74     if( type == TXT_READ )              // descheduling strategy for calling thread
     102    // compute extended pointer on relevant TTY register
     103    xptr_t reg_xp;
     104    if( type == TXT_READ )  reg_xp = XPTR( tty_cxy , base + TTY_RX_IRQ_ENABLE );
     105    else                    reg_xp = XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE );
     106
     107    // enable relevant IRQ : data transfer will be done by the TTY_RX ISR)
     108    hal_remote_sw( reg_xp , 1 );
     109
     110txt_dmsg("\n[DBG] %s : core[%x,%d] DEV thread deschedule / cycle %d\n",
     111__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
     112
     113    // Block and deschedule server thread
     114    thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
     115    sched_yield();
     116
     117txt_dmsg("\n[DBG] %s : core[%x,%d] / DEV thread resume / cycle %d\n",
     118__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
     119
     120#if CONFIG_READ_DEBUG
     121exit_tty_cmd = hal_time_stamp();
     122#endif
     123
     124}  // end soclib_tty_cmd()
     125
     126/////////////////////////////////////////////////////////////
     127void __attribute__ ((noinline)) soclib_tty_aux( void * args )
     128{
     129    uint32_t   status;
     130    bool_t     empty;
     131    uint32_t   i;
     132
     133    xptr_t     dev_xp = ((txt_aux_t *)args)->dev_xp;
     134    char     * buffer = ((txt_aux_t *)args)->buffer;
     135    uint32_t   count  = ((txt_aux_t *)args)->count;
     136   
     137    // get TXT0 chdev cluster and local pointer
     138    cxy_t     dev_cxy = GET_CXY( dev_xp );
     139    chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
     140
     141    // get extended pointer on TTY channel base address
     142    xptr_t tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) );
     143
     144    // get TTY channel segment cluster and local pointer
     145    cxy_t      tty_cxy = GET_CXY( tty_xp );
     146    uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp );
     147
     148    // get extended pointers on TTY_WRITE & TTY_STATUS registers
     149    xptr_t write_xp  = XPTR( tty_cxy , tty_ptr + TTY_WRITE );
     150    xptr_t status_xp = XPTR( tty_cxy , tty_ptr + TTY_STATUS );
     151
     152    // loop on characters (busy waiting strategy)
     153    for( i = 0 ; i < count ; i++ )
    75154    {
    76         // unmask RX_IRQ (data transfer will be done by the TTY_RX ISR)
    77         xptr_t config_xp = XPTR( tty_cxy , base + TTY_CONFIG_REG );
    78         uint32_t old = hal_remote_lw( config_xp );
    79         uint32_t new = old | TTY_CONFIG_RX_ENABLE;
    80         hal_remote_atomic_cas( config_xp , old , new );
    81 
    82         // Block and deschedule server thread
    83         thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
    84         sched_yield( NULL );
     155        do
     156        {
     157            // get TTY_STATUS
     158            status = hal_remote_lw( status_xp );
     159            empty  = ( (status & TTY_STATUS_TX_FULL) == 0 );
     160
     161            // transfer one byte if TX buffer empty
     162            if ( empty )  hal_remote_sb( write_xp , buffer[i] );
     163        }
     164        while ( empty == false );
    85165    }
    86     else if( type == TXT_WRITE )        // descheduling strategy for calling thread
    87     {
    88         // unmask TX_IRQ (data transfer will be done by the TTY_TX ISR)
    89         xptr_t config_xp = XPTR( tty_cxy , base + TTY_CONFIG_REG );
    90         uint32_t old = hal_remote_lw( config_xp );
    91         uint32_t new = old | TTY_CONFIG_TX_ENABLE;
    92         hal_remote_atomic_cas( config_xp , old , new );
    93 
    94         // Block and deschedule server thread
    95         thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
    96         sched_yield( NULL );
    97     }
    98     else if( type == TXT_SYNC_WRITE )  // busy waiting strategy for calling thread
    99     {
    100         uint32_t   status;
    101         bool_t     empty;
    102         uint32_t   i;
    103 
    104         // get source buffer extended pointer & bytes count
    105         uint32_t count  = hal_remote_lw ( XPTR( th_cxy , &th_ptr->txt_cmd.count ) );
    106         xptr_t   buf_xp = hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.buf_xp ) );
    107 
    108         // loop on characters
    109         for( i = 0 ; i < count ; i++ )
    110         {
    111             do
    112             {
    113                 // get TTY_STATUS_REG
    114                 status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ) );
    115                 empty  = ( (status & TTY_STATUS_TX_FULL) == 0 );
    116 
    117                 if ( empty )  // TTY_TX empty => transfer one byte
    118                 {
    119                     // get one byte from command buffer in client cluster
    120                     char byte = (char)hal_remote_lb( buf_xp + i );
    121 
    122                     // write byte to TTY_WRITE_REG in TTY cluster
    123                     hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , byte );
    124                 }
    125             }
    126             while ( empty == false );
    127         }
    128     }
    129 }  // end soclib_tty_cmd()
     166}  // end soclib_tty_aux()
    130167
    131168
     
    135172    uint32_t   type;         // command type
    136173    uint32_t   count;        // number of bytes in buffer
    137     xptr_t     buf_xp;       // Rextended pointer on buffer
     174    xptr_t     buf_xp;       // extended pointer on buffer
     175    xptr_t     status_xp;    // extended pointer on TTY_STATUS register
     176    xptr_t     write_xp;     // extended pointer on TTY_WRITE register
     177    xptr_t     read_xp;      // extended pointer on TTY_READ register
    138178    uint32_t   status;       // TTY terminal status
    139179    char       byte;         // read byte
    140180    uint32_t   i;
     181
     182#if CONFIG_READ_DEBUG
     183enter_tty_isr = hal_time_stamp();
     184#endif
    141185
    142186    // get extended pointer on client thread
     
    153197    buf_xp  = hal_remote_lwd( XPTR( client_cxy , &client_ptr->txt_cmd.buf_xp ) );
    154198
     199txt_dmsg("\n[DBG] %s : core[%x,%d] enter / cycle %d\n",
     200__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid , hal_time_stamp() );
     201
    155202    // get SOCLIB_TTY peripheral cluster and local pointer
    156203    cxy_t      tty_cxy = GET_CXY( chdev->base );
     
    160207    uint32_t * base = tty_ptr + TTY_SPAN * chdev->channel;
    161208
     209    // get extended pointer on TTY registers
     210    status_xp = XPTR( tty_cxy , base + TTY_STATUS );
     211    write_xp  = XPTR( tty_cxy , base + TTY_WRITE );
     212    read_xp   = XPTR( tty_cxy , base + TTY_READ );
     213
    162214    if( type == TXT_READ )              // read one single character
    163215    {
    164         // get TTY_STATUS_REG
    165         status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ) );
    166 
    167         if( status & TTY_STATUS_RX_FULL )   // TTY_RX full => transfer one byte
    168         {
    169             // get a byte from TTY_READ_REG, and acknowledge RX_IRQ
    170             byte = (char)hal_remote_lb( XPTR( tty_cxy , base + TTY_READ_REG ) );
     216        // get TTY_STATUS
     217        status = hal_remote_lw( status_xp );
     218
     219        if( status & TTY_STATUS_RX_FULL )   // TTY_RX full => move one byte
     220        {
     221            // get a byte from TTY_READ, and acknowledge RX_IRQ
     222            byte = (char)hal_remote_lb( read_xp );
    171223
    172224            // write it to command buffer
    173225            hal_remote_sb( buf_xp , byte );
    174 
    175             // update TTY_WRITE_REG if echo mode
    176             if( CONFIG_TXT_ECHO_MODE )
    177             {
    178                 if( (byte == '\b') || (byte == 0x7F) )
    179                         {
    180                                 hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , '\b' );
    181                                 hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , ' '  );
    182                                 hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , '\b' );
    183                         }
    184                 else
    185                 {
    186                                 hal_remote_sw( XPTR( tty_cxy , base + TTY_WRITE_REG ) , byte );
    187                         }
    188             }
    189226        }
    190227        else                               // buffer empty => exit ISR for retry
     
    192229            return;
    193230        }
     231
     232        // disable RX_IRQ
     233        xptr_t reg_xp = XPTR( tty_cxy , base + TTY_RX_IRQ_ENABLE );
     234        hal_remote_sw( reg_xp , 0 );
    194235    }
    195     else if( type == TXT_WRITE )         // write a string
     236    else if( type == TXT_WRITE )         // write all characters in string
    196237    {
    197238        // loop on characters
    198239        for( i = 0 ; i < count ; i++ )
    199240        {
    200             // get TTY_STATUS_REG
    201             status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ) );
    202 
    203             if( (status & TTY_STATUS_TX_FULL) == 0 ) // TTY_TX empty => transfer one byte
     241            // get TTY_STATUS
     242            status = hal_remote_lw( status_xp );
     243
     244            if( (status & TTY_STATUS_TX_FULL) == 0 ) // TTY_TX empty => move one byte
    204245            {
    205246                // get one byte from command buffer
    206247                byte = (char)hal_remote_lb( buf_xp + i );
    207248
    208                 // write byte to TTY_WRITE_REG, and acknowledge TX_IRQ
    209                 hal_remote_sb( XPTR( tty_cxy , base + TTY_STATUS_REG ) , byte );
     249                // write byte to TTY_WRITE, and acknowledge TX_IRQ
     250                hal_remote_sb( write_xp , byte );
    210251            }
    211252            else         // TTY_TX full => update command arguments and exit ISR for retry
     
    216257            }
    217258        }
     259
     260        // disable TX_IRQ
     261        xptr_t reg_xp = XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE );
     262        hal_remote_sw( reg_xp , 0 );
    218263    }
    219264
    220265    // The I/O operation completed when we reach this point
    221 
    222     // mask both TTY_RX_IRQ and TTY_TX_IRQ
    223     hal_remote_sw( XPTR( tty_cxy , base + TTY_CONFIG_REG ) , 0 );
    224266
    225267    // set I/O operation status in command
     
    227269
    228270    // unblock server thread
    229     thread_unblock( XPTR( local_cxy , &chdev->server ) , THREAD_BLOCKED_DEV_ISR );
     271    thread_unblock( XPTR( local_cxy , chdev->server ) , THREAD_BLOCKED_DEV_ISR );
    230272
    231273    // unblock client thread
    232274    thread_unblock( client_xp , THREAD_BLOCKED_IO );
    233275
     276    hal_fence();
     277
     278txt_dmsg("\n[DBG] %s : core[%x,%d] exit / cycle %d\n",
     279__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
     280
     281#if CONFIG_READ_DEBUG
     282exit_tty_isr = hal_time_stamp();
     283#endif
     284
    234285}  // end soclib_tty_isr()
    235286
  • trunk/hal/tsar_mips32/drivers/soclib_tty.h

    r75 r407  
    3838 ***************************************************************************************/
    3939
    40 #define TTY_WRITE_REG          0
    41 #define TTY_STATUS_REG         1
    42 #define TTY_READ_REG           2
    43 #define TTY_CONFIG_REG         3
     40#define TTY_WRITE              0
     41#define TTY_STATUS             1
     42#define TTY_READ               2
     43#define TTY_RX_IRQ_ENABLE      3
     44#define TTY_TX_IRQ_ENABLE      4
    4445
    45 #define TTY_SPAN               4       // number of registers per channel
     46#define TTY_SPAN               8       // number of registers per channel
    4647
    4748/****************************************************************************************
     
    5152#define TTY_STATUS_RX_FULL     1       // TTY_READ_REG full if 1
    5253#define TTY_STATUS_TX_FULL     2       // TTY_WRITE_REG full if 1
    53 
    54 /****************************************************************************************
    55  * masks for TTY_CONFIG_REG
    56  ***************************************************************************************/
    57 
    58 #define TTY_CONFIG_RX_ENABLE   1       // TTY_RX IRQ enabled if 1
    59 #define TTY_CONFIG_TX_ENABLE   2       // TTY_TX IRQ enabled if 1
    6054
    6155/****************************************************************************************
     
    6862
    6963/****************************************************************************************
    70  * This function handles the command registered in the thread descriptor identified
    71  * by the <xp_thread> argument.
    72  * - For the TXT_READ and TXT_WRITE commands, it only unmask the proper TTY_RX / TTY_TX
    73  *   IRQ, and blocks the TXT device server thread on the THREAD_BLOCKED_DEV_ISR, as the
    74  *   data transfer is done by the ISR.
    75  * - For the TXT_SYNC_READ command, that should be only used by the kernel do display
    76  *   log or debug messages, it directly access the SOCLIB_TTY registers, using
    77  *   a busy waiting policy if required.
    78  ****************************************************************************************
     64 * This function implements the TXT_READ & TXT_WRITE commands registered in the client
     65 * thread descriptor (in the txt_cmd field), identified by the <xp_thread> argument.
     66 * Depending on the command type, it only unmasks the relevant TTY_RX / TTY_TX IRQ,
     67 * and blocks the TXT device server thread on the THREAD_BLOCKED_DEV_ISR, as the data
     68 * transfer is done by the ISR.
     69 * ****************************************************************************************
    7970 * @ thread_xp : extended pointer on client thread descriptor.
    8071 ***************************************************************************************/
    8172void soclib_tty_cmd( xptr_t thread_xp );
     73
     74/****************************************************************************************
     75 * This function implements the TXT_SYNC_WRITE command registered in the txt_aux_t
     76 * structure, using a busy waiting policy, without using the TTY IRQ.
     77 * It is used by the kernel do display debug messages on TXT0 terminal, without
     78 * interference with another TXT access to another terminal done by the same thread.
     79 ****************************************************************************************
     80 * @ thread_xp : pointer on the txt_aux_t structure containing the arguments.
     81 ***************************************************************************************/
     82void soclib_tty_aux( void * args );
    8283
    8384/****************************************************************************************
  • trunk/hal/x86_64/core/hal_ppm.c

    r307 r407  
    115115}
    116116
    117 void hal_core_init(boot_info_t *info)
    118 {
    119         /* Don't need to do anything */
    120 }
  • trunk/hal/x86_64/core/hal_types.h

    r320 r407  
    5959typedef uint64_t                    vaddr_t; // XXX
    6060typedef uint64_t                 pt_entry_t; // XXX
    61 
    62 /***************************************************************************
    63  * Pthread related types
    64  **************************************************************************/
    65 
    66 typedef uint32_t      pthread_t;
    67 typedef uint32_t      pthread_mutexattr_t;
    68 typedef uint32_t      pthread_barrier_t;
    69 typedef uint32_t      pthread_barrierattr_t;
    70 typedef uint32_t      sem_t;
    71 typedef uint32_t      pthread_cond_t;
    72 typedef uint32_t      pthread_condattr_t;
    73 typedef uint32_t      pthread_rwlock_t;
    74 typedef uint32_t      pthread_rwlockattr_t;
    75 typedef uint32_t      pthread_key_t;
    7661
    7762/***************************************************************************
  • trunk/hal/x86_64/core/hal_uspace.c

    r299 r407  
    4545}
    4646
    47 error_t hal_strcpy_to_uspace(char *u_dst, char *k_src, uint32_t max_size)
     47void hal_strcpy_to_uspace(char *u_dst, char *k_src, uint32_t max_size)
    4848{
    4949        x86_panic((char *)__func__);
     
    5151}
    5252
    53 error_t hal_strcpy_from_uspace(char *k_dst, char *u_src, uint32_t max_size)
     53void hal_strcpy_from_uspace(char *k_dst, char *u_src, uint32_t max_size)
    5454{
    5555        x86_panic((char *)__func__);
Note: See TracChangeset for help on using the changeset viewer.