- Timestamp:
- Nov 7, 2017, 3:08:12 PM (7 years ago)
- Location:
- trunk/hal
- Files:
-
- 2 added
- 28 edited
- 2 copied
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/generic/hal_context.h
r337 r407 40 40 41 41 /**************************************************************************************** 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 ***************************************************************************************/ 47 error_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. 44 52 **************************************************************************************** 45 53 * @ thread : pointer on the thread descriptor. 46 * @ return 0 if success / return ENOMEM if error54 * @ return 0 if success / return -1 if failure. 47 55 ***************************************************************************************/ 48 56 error_t hal_cpu_context_create( struct thread_s * thread ); 49 57 50 58 /**************************************************************************************** 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 54 63 **************************************************************************************** 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. 58 65 ***************************************************************************************/ 59 error_t hal_cpu_context_copy( struct thread_s * dst, 60 struct thread_s * src ); 66 void hal_cpu_context_display( struct thread_s * thread ); 61 67 62 68 /**************************************************************************************** … … 67 73 void hal_cpu_context_destroy( struct thread_s * thread ); 68 74 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 77 80 78 81 /**************************************************************************************** 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. 82 84 **************************************************************************************** 83 85 * @ thread : pointer on the thread descriptor. 86 * @ return 0 if success / return -1 if failure. 84 87 ***************************************************************************************/ 85 void hal_cpu_context_load( struct thread_s * thread );88 error_t hal_fpu_context_alloc( struct thread_s * thread ); 86 89 87 90 /**************************************************************************************** 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. 100 93 **************************************************************************************** 101 94 * @ dst : pointer on the destination thread descriptor. 102 95 * @ src : pointer on the source thread descriptor. 103 * @ return 0 if success / return ENOMEM if error104 96 ***************************************************************************************/ 105 error_thal_fpu_context_copy( struct thread_s * dst,97 void hal_fpu_context_copy( struct thread_s * dst, 106 98 struct thread_s * src ); 107 99 -
trunk/hal/generic/hal_gpt.h
r406 r407 43 43 44 44 struct page_s; 45 struct process_s; 45 46 46 47 /**************************************************************************************** … … 48 49 ***************************************************************************************/ 49 50 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 */ 63 64 64 65 /**************************************************************************************** … … 70 71 void * ptr; /*! local pointer on GPT root */ 71 72 ppn_t ppn; /*! PPN of GPT root */ 72 struct page_s * page; /*! local pointer on GPT root page descriptor */73 73 } 74 74 gpt_t; … … 98 98 * This function prints on the kernel terminal the content of a generic page table. 99 99 **************************************************************************************** 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 ***************************************************************************************/ 102 void hal_gpt_display( struct process_s * process ); 105 103 106 104 /**************************************************************************************** … … 169 167 170 168 /**************************************************************************************** 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). 176 176 **************************************************************************************** 177 177 * @ dst_gpt : [in] pointer on the destination GPT. 178 178 * @ 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. 179 181 * @ cow : [in] activate the COPY-On-Write mechanism if true. 180 182 ***************************************************************************************/ 181 183 error_t hal_gpt_copy( gpt_t * dst_gpt, 182 184 gpt_t * src_gpt, 185 vpn_t vpn_base, 186 vpn_t vpn_size, 183 187 bool_t cow ); 184 188 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 ***************************************************************************************/ 196 bool_t hal_gpt_pte_is_cow( gpt_t * gpt, 197 vpn_t vpn ); 198 185 199 186 200 #endif /* _GPT_H_ */ -
trunk/hal/generic/hal_ppm.h
r315 r407 54 54 error_t hal_ppm_init( boot_info_t * info ); 55 55 56 /****************************************************************************************57 * This function initializes the architecture specific core registers, for the58 * 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 64 56 #endif /* HAL_PPM_H_ */ -
trunk/hal/generic/hal_remote.h
r313 r407 133 133 * @ xp : extended pointer to remote data 134 134 * @ mask : local mask value. 135 * @ return old value (before increment) of the remote integer135 * @ return old value (before mask) of the remote integer 136 136 ****************************************************************************************/ 137 137 uint32_t hal_remote_atomic_and( xptr_t xp, … … 144 144 * @ xp : extended pointer to remote data 145 145 * @ mask : local mask value. 146 * @ return old value (before increment) of the remote integer146 * @ return old value (before mask) of the remote integer 147 147 ****************************************************************************************/ 148 148 uint32_t hal_remote_atomic_or( xptr_t xp, -
trunk/hal/generic/hal_special.h
r401 r407 70 70 71 71 /***************************************************************************************** 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 /*****************************************************************************************77 72 * This function writes into the proper core register to enable the floating point unit. 78 73 ****************************************************************************************/ … … 128 123 129 124 /***************************************************************************************** 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. 131 127 ****************************************************************************************/ 132 void hal_fixed_delay( );128 void hal_fixed_delay( uint32_t delay ); 133 129 134 130 /***************************************************************************************** -
trunk/hal/generic/hal_switch.h
r405 r407 1 1 /* 2 * hal_switch.h - TSARarchitecture context switch function2 * hal_switch.h - Generic architecture context switch function 3 3 * 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 6 7 * 7 * This file is part of ALMOS- kernel.8 * This file is part of ALMOS-MKH. 8 9 * 9 * ALMOS- kernelis free software; you can redistribute it and/or modify it10 * ALMOS-MKH is free software; you can redistribute it and/or modify it 10 11 * under the terms of the GNU General Public License as published by 11 12 * the Free Software Foundation; version 2.0 of the License. 12 13 * 13 * ALMOS- kernelis distributed in the hope that it will be useful, but14 * ALMOS-MKH is distributed in the hope that it will be useful, but 14 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU … … 17 18 * 18 19 * 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, 20 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 22 */ … … 24 25 #define _HAL_SWITCH_H_ 25 26 27 struct thread_s; 28 26 29 /************************************************************************************* 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. 38 39 ************************************************************************************* 39 * @ ctx_ old : local pointer on the old threadcontext.40 * @ ctx_ne w : local pointer on the new threadcontext.40 * @ ctx_current : local pointer on current thread CPU context. 41 * @ ctx_next : local pointer on new thread CPU context. 41 42 ************************************************************************************/ 42 void hal_do_ switch( void * ctx_old,43 void * ctx_new );43 void hal_do_cpu_switch( void * ctx_old, 44 void * ctx_new ); 44 45 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 ************************************************************************************/ 63 void hal_do_cpu_save( void * ctx, 64 void * thread, 65 int offset ); 45 66 46 67 #endif /* _HAL_SWITCH_H_ */ -
trunk/hal/generic/hal_syscall.h
r405 r407 1 1 /* 2 * hal_ syscall.h - Architecture specificsyscall handler API definition.2 * hal_kernel_syscall.h - Architecture specific kernel_side syscall handler API definition. 3 3 * 4 4 * Author Alain Greiner (2016,2017) … … 22 22 */ 23 23 24 #ifndef _HAL_ SYSCALL_H_25 #define _HAL_ SYSCALL_H_24 #ifndef _HAL_KERNEL_SYSCALL_H_ 25 #define _HAL_KERNEL_SYSCALL_H_ 26 26 27 27 #include <hal_types.h> 28 28 29 29 ////////////////////////////////////////////////////////////////////////////////////////// 30 // ARchitecture specificsyscall handler API30 // Kernel-side syscall handler API 31 31 // 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. 36 35 // 37 36 // Any architecture specific implementation must implement this API. … … 44 43 45 44 /***************************************************************************************** 46 * This function implements the ALMOS-MKH syscall handler.45 * This function implements the ALMOS-MKH kernel_side syscall handler. 47 46 ***************************************************************************************** 48 47 * @ this : pointer on the calling thread. … … 53 52 54 53 55 #endif // _HAL_ SYSCALL_H_54 #endif // _HAL_KERNEL_SYSCALL_H_ -
trunk/hal/generic/hal_uspace.h
r299 r407 62 62 63 63 /***************************************************************************************** 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. 65 67 * 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 handling67 68 ***************************************************************************************** 68 69 * @ u_dst : destination buffer address in user space. … … 70 71 * @ max_size : max number of characters to be copied. 71 72 ****************************************************************************************/ 72 extern error_thal_strcpy_from_uspace( char * k_dst,73 74 73 extern void hal_strcpy_from_uspace( char * k_dst, 74 char * u_src, 75 uint32_t max_size ); 75 76 76 77 /***************************************************************************************** 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. 78 81 * 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 handling80 82 ***************************************************************************************** 81 83 * @ u_dst : destination buffer address in user space. … … 83 85 * @ max_size : max number of characters to be copied. 84 86 ****************************************************************************************/ 85 extern error_thal_strcpy_to_uspace( char * u_dst,86 87 87 extern void hal_strcpy_to_uspace( char * u_dst, 88 char * k_src, 89 uint32_t max_size ); 88 90 89 91 /***************************************************************************************** -
trunk/hal/tsar_mips32/core/hal_context.c
r406 r407 44 44 45 45 ///////////////////////////////////////////////////////////////////////////////////////// 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 // 48 52 // WARNING : check the two CONFIG_CPU_CTX_SIZE & CONFIG_FPU_CTX_SIZE configuration 49 53 // parameterss when modifying this structure. … … 85 89 uint32_t gp_28; // slot 28 86 90 uint32_t sp_29; // slot 29 87 uint32_t fp_30; // slot 3091 uint32_t s8_30; // slot 30 88 92 uint32_t ra_31; // slot 31 89 93 … … 108 112 109 113 ///////////////////////////////////////////////////////////////////////////////////////// 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 ////////////////////////////////////////////////// 119 error_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 117 141 // CP0 : c0_sr / c0_th / c0_epc 118 142 // CP2 : c2_ptpr / c2_mode 119 /////////////////////////////////////////////////// //////////////////////////////////////143 /////////////////////////////////////////////////// 120 144 error_t hal_cpu_context_create( thread_t * thread ) 121 145 { 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 144 154 if( thread->type == THREAD_USER ) 145 155 { 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; 149 164 } 150 else 165 else // kernel thread 151 166 { 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; 155 174 } 156 175 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" 176 context_dmsg("\n[DBG] %s : thread %x in process %x\n" 172 177 " - a0 = %x\n" 173 178 " - sp = %x\n" 174 " - fp = %x\n"175 179 " - ra = %x\n" 176 180 " - sr = %x\n" … … 180 184 " - mode = %x\n", 181 185 __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, 183 187 context->c0_sr, context->c0_th, context->c0_epc, 184 188 context->c2_ptpr, context->c2_mode ); … … 201 205 ctx->c2_ptpr , ctx->c2_mode ); 202 206 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() 257 208 258 209 ///////////////////////////////////////////////// … … 268 219 269 220 270 /////////////////////////////////////////////////// 271 error_t hal_fpu_context_create( thread_t * thread ) 272 { 221 222 223 224 ////////////////////////////////////////////////// 225 error_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 273 231 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 uzone279 232 req.type = KMEM_FPU_CTX; 280 233 req.flags = AF_KERNEL | AF_ZERO; 281 234 282 235 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; 288 240 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 ////////////////////////////////////////// 245 void 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 308 252 hal_fpu_context_t * src_context = src->fpu_context; 253 hal_fpu_context_t * dst_context = dst->fpu_context; 309 254 310 255 // copy CPU context from src to dst 311 256 memcpy( dst_context , src_context , sizeof(hal_fpu_context_t) ); 312 257 313 return 0;314 258 } // end hal_fpu_context_copy() 315 259 … … 413 357 } // end hal_cpu_context_restore() 414 358 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 49 49 uint32_t impl ) 50 50 { 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 ); 59 54 } 60 55 … … 67 62 uint32_t impl ) 68 63 { 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" ); 73 65 74 66 soclib_pic_init( pic ); … … 81 73 pic->ext.pic.bind_irq = &soclib_pic_bind_irq; 82 74 pic->ext.pic.send_ipi = &soclib_pic_send_ipi; 75 pic->ext.pic.ack_ipi = &soclib_pic_ack_ipi; 83 76 pic->ext.pic.extend_init = &soclib_pic_extend_init; 84 77 } … … 92 85 uint32_t impl ) 93 86 { 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" ); 98 88 99 89 soclib_iob_init( iob ); … … 138 128 uint32_t impl ) 139 129 { 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 ); 148 133 } 149 134 … … 156 141 uint32_t impl ) 157 142 { 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 ); 166 146 } 167 147 … … 174 154 uint32_t impl ) 175 155 { 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 ); 184 159 } 185 160 -
trunk/hal/tsar_mips32/core/hal_exception.c
r406 r407 58 58 59 59 ////////////////////////////////////////////////////////////////////////////////////////// 60 // This enum defines the mask values ifor an MMU exception code reported by the mips32.60 // This enum defines the mask values for an MMU exception code reported by the mips32. 61 61 ////////////////////////////////////////////////////////////////////////////////////////// 62 62 63 63 typedef enum 64 64 { 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, 69 82 } 70 83 mmu_exception_subtype_t; … … 148 161 process = this->process; 149 162 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 153 163 // get relevant values from MMU 154 164 hal_get_mmu_excp( &mmu_ins_excp_code, … … 157 167 &mmu_dat_bad_vaddr ); 158 168 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 163 169 // get exception code and faulty vaddr, depending on IBE/DBE 164 170 if( is_ins ) … … 173 179 } 174 180 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 205 excp_dmsg("\n[DBG] %s : core[%x,%d] / page-fault handled for vaddr = %x\n", 206 __FUNCTION__ , local_cxy , this->core->lid , bad_vaddr ); 203 207 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 240 excp_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 } 236 269 } // end hal_mmu_exception() 237 270 … … 242 275 // @ this : pointer on faulty thread descriptor. 243 276 // @ regs_tbl : pointer on register array. 244 // @ return always EXCP_NON_FATAL277 // @ error : EXCP_USER_ERROR or EXCP_KERNEL_PANIC 245 278 ////////////////////////////////////////////////////////////////////////////////////////// 246 279 static void hal_exception_dump( thread_t * this, 247 reg_t * regs_tbl ) 280 reg_t * regs_tbl, 281 error_t error ) 248 282 { 249 283 uint32_t save_sr; 284 core_t * core = this->core; 250 285 251 286 // get pointers on TXT0 chdev 252 xptr_t txt0_xp = chdev_dir.txt [0];287 xptr_t txt0_xp = chdev_dir.txt_tx[0]; 253 288 cxy_t txt0_cxy = GET_CXY( txt0_xp ); 254 289 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); … … 260 295 remote_spinlock_lock_busy( lock_xp , &save_sr ); 261 296 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 } 265 302 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 } 268 307 269 308 nolock_printk(" thread type = %s / trdid = %x / pid %x / core[%x,%d]\n" … … 272 311 this->core->lid, this->local_locks, this->remote_locks, this->blocked ); 273 312 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]); 279 318 280 319 nolock_printk("a2_6 %X a3_7 %X t0_8 %X t1_9 %X t2_10 %X\n", … … 284 323 regs_tbl[UZ_T3],regs_tbl[UZ_T4],regs_tbl[UZ_T5],regs_tbl[UZ_T6],regs_tbl[UZ_T7]); 285 324 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 289 325 nolock_printk("s0_16 %X s1_17 %X s2_18 %X s3_19 %X s4_20 %X\n", 290 326 regs_tbl[UZ_S0],regs_tbl[UZ_S1],regs_tbl[UZ_S2],regs_tbl[UZ_S3],regs_tbl[UZ_S4]); 291 327 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]); 294 333 295 334 // release the lock … … 311 350 excCode = (regs_tbl[UZ_CR] >> 2) & 0xF; 312 351 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() ); 352 excp_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, 354 this->process->pid, excCode, (uint32_t)hal_get_cycle() ); 315 355 316 356 switch(excCode) … … 355 395 if( error == EXCP_USER_ERROR ) // user error => kill user process 356 396 { 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 ); 359 402 } 360 403 else if( error == EXCP_KERNEL_PANIC ) // kernel error => kernel panic 361 404 { 362 hal_exception_dump( this , regs_tbl );405 hal_exception_dump( this , regs_tbl , error ); 363 406 hal_core_sleep(); 364 407 } 365 408 366 excp_dmsg("\n[DMSG] %s : exit forthread %x in process %x / cycle %d\n",367 __FUNCTION__ , this->trdid , this->process->pid, hal_time_stamp() );409 excp_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() ); 368 411 369 412 } // end hal_do_exception() -
trunk/hal/tsar_mips32/core/hal_gpt.c
r406 r407 135 135 uint32_t attr; 136 136 137 gpt_dmsg("\n[DMSG] %s : core[%x,%d] enter\n",138 137 gpt_dmsg("\n[DBG] %s : core[%x,%d] enter\n", 138 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid ); 139 139 140 140 // check page size … … 157 157 // initialize generic page table descriptor 158 158 page_xp = XPTR( local_cxy , page ); 159 160 159 gpt->ptr = GET_PTR( ppm_page2base( page_xp ) ); 161 160 gpt->ppn = ppm_page2ppn( page_xp ); 162 gpt->page = GET_PTR( page_xp );163 161 164 162 // identity map the kentry_vseg (must exist for all processes) … … 167 165 vpn < (CONFIG_VMM_KENTRY_BASE + CONFIG_VMM_KENTRY_SIZE); vpn++ ) 168 166 { 169 gpt_dmsg("\n[DMSG] %s : identity map vpn %d\n", __FUNCTION__ , vpn ); 167 168 gpt_dmsg("\n[DBG] %s : identity map vpn %d\n", __FUNCTION__ , vpn ); 170 169 171 170 error = hal_gpt_set_pte( gpt, … … 181 180 } 182 181 183 gpt_dmsg("\n[DMSG] %s : core[%x,%d] exit\n",184 182 gpt_dmsg("\n[DBG] %s : core[%x,%d] exit\n", 183 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid ); 185 184 186 185 return 0; … … 271 270 } // end hal_gpt_destroy() 272 271 273 //////////////////////////////// 274 void hal_gpt_ print( gpt_t * gpt,275 pid_t pid ) 276 { 272 /////////////////////////////////////////// 273 void hal_gpt_display( process_t * process ) 274 { 275 gpt_t * gpt; 277 276 uint32_t ix1; 278 277 uint32_t ix2; … … 285 284 vpn_t vpn; 286 285 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 288 292 pt1 = (uint32_t *)gpt->ptr; 289 293 290 294 printk("\n***** Generic Page Table for process %x : &gpt = %x / &pt1 = %x\n\n", 291 p id , gpt , pt1 );295 process->pid , gpt , pt1 ); 292 296 293 297 // scan the PT1 … … 324 328 } 325 329 } 326 } // end hal_gpt_ print()330 } // end hal_gpt_display() 327 331 328 332 … … 351 355 uint32_t tsar_attr; // PTE attributes for TSAR MMU 352 356 353 gpt_dmsg("\n[D MSG] %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", 354 358 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , ppn , attr ); 355 359 … … 364 368 tsar_attr = gpt2tsar( attr ); 365 369 366 gpt_dmsg("\n[D MSG] %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", 367 371 __FUNCTION__, local_cxy , CURRENT_THREAD->core->lid , vpn , pt1 , tsar_attr ); 368 372 … … 396 400 pte1 = *pte1_ptr; 397 401 398 gpt_dmsg("\n[D MSG] %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", 399 403 __FUNCTION__, local_cxy , CURRENT_THREAD->core->lid , vpn , pte1 ); 400 404 … … 438 442 pt2 = (uint32_t *)GET_PTR( ppm_ppn2base( pt2_ppn ) ); 439 443 440 gpt_dmsg("\n[D MSG] %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", 441 445 __FUNCTION__, local_cxy , CURRENT_THREAD->core->lid , vpn , pte1 , pt2 ); 442 446 … … 450 454 hal_fence(); 451 455 452 gpt_dmsg("\n[D MSG] %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", 453 457 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , 454 458 pt2[2 * ix2] , pt2[2 * ix2 + 1] ); … … 727 731 error_t hal_gpt_copy( gpt_t * dst_gpt, 728 732 gpt_t * src_gpt, 733 vpn_t vpn_base, 734 vpn_t vpn_size, 729 735 bool_t cow ) 730 736 { 737 vpn_t vpn; // current vpn 738 731 739 uint32_t ix1; // index in PT1 732 740 uint32_t ix2; // index in PT2 … … 737 745 uint32_t * src_pt2; // local pointer on PT2 for SRC_GPT 738 746 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 740 752 uint32_t pte2_attr; 741 753 uint32_t pte2_ppn; 742 uint32_t pte2_writable;743 754 744 755 page_t * page; … … 748 759 ppn_t dst_pt2_ppn; 749 760 750 // get pointers on PT1 for src_gpt & dst_gpt 761 gpt_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 751 773 src_pt1 = (uint32_t *)src_gpt->ptr; 752 774 dst_pt1 = (uint32_t *)dst_gpt->ptr; 753 775 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 858 gpt_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 /////////////////////////////////////// 866 bool_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 754 915 // scan the SRC_PT1 755 916 for( ix1 = 0 ; ix1 < 2048 ; ix1++ ) … … 834 995 } // end hal_gpt_copy() 835 996 997 */ -
trunk/hal/tsar_mips32/core/hal_interrupt.c
r406 r407 33 33 reg_t * regs_tbl ) 34 34 { 35 irq_dmsg("\n[DMSG] %s : enter / core[%x,%d] / cycle %d\n",36 __FUNCTION__ , local_cxy , this->core->lid , hal_time_stamp() );37 35 38 // access local ICU to call the relevant ISR 36 irq_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 39 41 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 43 irq_dmsg("\n[DBG] %s : core[%x,%d] exit at cycle %d\n", 44 __FUNCTION__ , local_cxy , this->core->lid , hal_time_stamp() ); 45 43 46 } -
trunk/hal/tsar_mips32/core/hal_kentry.S
r406 r407 189 189 mtc0 $3, $12 # set new sr 190 190 191 # signal that core enters kernel192 la $1, cluster_core_kernel_enter193 jalr $1194 nop195 196 191 #--------------------------------------------------------------------------------------- 197 192 # This code call the relevant Interrupt / Exception / Syscall handler, … … 241 236 # ----------------------------------------------------------------------------------- 242 237 kentry_exit: 243 244 # signal that core exit kernel245 la $1, cluster_core_kernel_exit246 jalr $1247 nop248 238 249 239 # restore registers from uzone -
trunk/hal/tsar_mips32/core/hal_kentry.h
r406 r407 41 41 42 42 #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 */ 75 75 #define UZ_LO 33 76 76 #define UZ_HI 34 -
trunk/hal/tsar_mips32/core/hal_ppm.c
r315 r407 45 45 // kmem memory allocator in the local cluster. This array starts in first free page 46 46 // 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 point49 // fot Interrupts, Exceptions and Syscalls, has to be redefined.50 47 ////////////////////////////////////////////////////////////////////////////////////////// 51 48 … … 124 121 } // end hal_ppm_init() 125 122 126 ////////////////////////////////////////127 void hal_core_init( boot_info_t * info )128 {129 // get relevant info from boot_info structure130 reg_t kentry_base = info->kentry_base;131 123 132 // set CP0_EBASE register133 hal_set_ebase( kentry_base );134 135 } // end hal_core_init()136 137 -
trunk/hal/tsar_mips32/core/hal_special.c
r406 r407 31 31 32 32 struct thread_s; 33 34 /////////////////////////////////35 void hal_set_ebase( reg_t base )36 {37 asm volatile ("mtc0 %0, $15, 1" : : "r" (base));38 }39 33 40 34 ////////////////////////// … … 200 194 void hal_fence() 201 195 { 202 asm volatile 203 ( "sync \n":: ); 196 asm volatile ("sync"); 204 197 } 205 198 … … 213 206 void hal_core_sleep() 214 207 { 215 asm volatile 216 ("wait \n"::); 208 asm volatile ("wait"); 217 209 } 218 210 … … 221 213 { 222 214 asm volatile 223 ( " 1:\n"215 ( ".set noreorder \n" 224 216 "or $27, %0, $0 \n" 217 "1: \n" 225 218 "addi $27, $27, -1 \n" 219 "nop \n" 226 220 "bne $27, $0, 1b \n" 227 221 "nop \n" 228 : : "r" (delay) : "$27" ); 222 ".set reorder \n" 223 : : "r" (delay>>2) : "$27" ); 229 224 } 230 225 -
trunk/hal/tsar_mips32/core/hal_switch.S
r406 r407 22 22 */ 23 23 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: 26 34 # - register $4 contains a pointer on the old thread context. 27 35 # - 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 #--------------------------------------------------------------------------------- 37 hal_do_cpu_switch: 41 38 42 39 move $26, $4 /* $26 <= ctx_old */ … … 133 130 mthi $27 /* restore hi from slot 26 */ 134 131 lw $27, 27*4($26) 135 mtlo $27 /* resto te lo from slot 27 */132 mtlo $27 /* restore lo from slot 27 */ 136 133 137 134 lw $28, 28*4($26) 138 135 lw $29, 29*4($26) 139 136 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) 143 140 mtc2 $27, $0 /* restore c2_ptpr from slot 32 */ 144 141 145 lw $27, 35*4($26) /* $27 <= c0_th */142 lw $27, 35*4($26) 146 143 mtc0 $27, $4, 2 /* restore c0_th from slot 35 */ 147 144 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) 150 147 151 148 mtc2 $27, $1 /* restore c2_mode from slot 33 */ … … 155 152 nop 156 153 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 #--------------------------------------------------------------------------------- 160 hal_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 157 227 .set reorder 158 228 .set at 159 229 160 .end hal_do_switch161 -
trunk/hal/tsar_mips32/core/hal_syscall.c
r406 r407 26 26 #include <do_syscall.h> 27 27 #include <thread.h> 28 #include <printk.h> 28 29 #include <hal_kentry.h> 29 30 … … 33 34 reg_t * regs_tbl ) 34 35 { 36 37 #if(CONFIG_SYSCALL_DEBUG & 0x1) 38 printk("\n[DBG] %s : core[%x,%d] enter at cycle %d\n", 39 __FUNCTION__ , local_cxy , this->core->lid , hal_time_stamp() ); 40 #endif 41 35 42 register reg_t arg0; 36 43 register reg_t arg1; … … 58 65 regs_tbl[UZ_V1] = this->errno; 59 66 regs_tbl[UZ_EPC] += 4; 67 68 #if(CONFIG_SYSCALL_DEBUG & 0x1) 69 printk("\n[DBG] %s : core[%x,%d] exit at cycle %d\n", 70 __FUNCTION__ , local_cxy , this->core->lid , hal_time_stamp() ); 71 #endif 72 60 73 } -
trunk/hal/tsar_mips32/core/hal_types.h
r315 r407 48 48 typedef signed long long int int64_t; 49 49 typedef unsigned long long int uint64_t; 50 51 /***************************************************************************52 * Pthread related types53 **************************************************************************/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;65 50 66 51 /*************************************************************************** -
trunk/hal/tsar_mips32/core/hal_uspace.c
r315 r407 45 45 hal_disable_irq( &save_sr ); 46 46 47 47 48 for( i = 0 ; i < wsize ; i++ ) // transfer one word per iteration 48 49 { … … 129 130 } // end hal_copy_to_uspace() 130 131 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 ////////////////////////////////////////////// 133 void hal_strcpy_from_uspace( char * k_dst, 134 char * u_src, 135 uint32_t size ) 136 { 137 uint32_t save_sr; 138 141 139 uint32_t src = (uint32_t)u_src; 142 140 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 ) 163 145 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" 174 164 "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 180 172 } // hal_strcpy_from_uspace() 181 173 182 174 //////////////////////////////////////////// 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; 175 void hal_strcpy_to_uspace( char * u_dst, 176 char * k_src, 177 uint32_t size ) 178 { 179 uint32_t save_sr; 180 191 181 uint32_t src = (uint32_t)k_src; 192 182 uint32_t dst = (uint32_t)u_dst; … … 194 184 hal_disable_irq( &save_sr ); 195 185 196 // loop on characters while non NUL186 // loop on characters while ( (character != NUL) and (count < size) ) 197 187 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" 208 206 "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 214 214 } // hal_strcpy_to_uspace() 215 215 … … 218 218 { 219 219 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; 222 223 223 224 hal_disable_irq( &save_sr ); 224 225 225 226 asm volatile( 226 " ori $15, %0, 0 \n" /* $15 <= count */227 ".set noreorder \n" 227 228 "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 */ 233 232 "1: \n" 234 "lb $1 3, 0(%0) \n" /* read char from kernel space*/233 "lb $12, 0($13) \n" /* read char from user space */ 235 234 "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" ); 241 242 242 243 hal_restore_irq( save_sr ); -
trunk/hal/tsar_mips32/drivers/soclib_bdv.c
r296 r407 104 104 105 105 // 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 106 108 107 if( cmd_type == IOC_SYNC_READ ) //polling policy109 if( cmd_type == IOC_SYNC_READ ) // status polling policy 108 110 { 109 111 uint32_t status; … … 131 133 { 132 134 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 134 138 } 135 139 -
trunk/hal/tsar_mips32/drivers/soclib_dma.c
r296 r407 91 91 // Block and deschedule server thread 92 92 thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR ); 93 sched_yield( NULL);93 sched_yield(); 94 94 95 95 } // soclib_dma_cmd() -
trunk/hal/tsar_mips32/drivers/soclib_hba.c
r296 r407 197 197 else // retry if asynchronous access. 198 198 { 199 sched_yield( NULL);199 sched_yield(); 200 200 } 201 201 } … … 240 240 { 241 241 thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR ); 242 sched_yield( NULL);242 sched_yield(); 243 243 } 244 244 -
trunk/hal/tsar_mips32/drivers/soclib_pic.c
r406 r407 43 43 extern lapic_input_t lapic_input; // defined in dev_pic.h / allocated in kernel_init.c 44 44 45 46 45 47 ////////////////////////////////////////////////////////////////////////////////////// 46 48 // SOCLIB PIC private functions … … 127 129 &pti_status ); 128 130 129 irq_dmsg("\n[D MSG] %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", 130 132 __FUNCTION__ , local_cxy , core->lid , wti_status , hwi_status , pti_status ); 131 133 … … 140 142 assert( (index == core->lid) , __FUNCTION__ , "illegal IPI index" ); 141 143 142 irq_dmsg("\n[D MSG] %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", 143 145 __FUNCTION__ , local_cxy , core->lid , hal_time_stamp() ); 144 146 … … 168 170 else // call relevant ISR 169 171 { 170 irq_dmsg("\n[D MSG] %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", 171 173 __FUNCTION__ , local_cxy , core->lid , index , hal_time_stamp() ); 172 174 … … 196 198 else // call relevant ISR 197 199 { 198 irq_dmsg("\n[D MSG] %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", 199 201 __FUNCTION__ , local_cxy , core->lid , index , hal_time_stamp() ); 200 202 … … 208 210 index = pti_status - 1; 209 211 210 irq_dmsg("\n[D MSG] %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", 211 213 __FUNCTION__ , core->lid , local_cxy , index , hal_time_stamp() ); 212 214 … … 248 250 uint32_t * iopic_seg_ptr = (uint32_t *)GET_PTR( pic->base ); 249 251 250 // reset the IOPIC component registers : maskall input IRQs252 // reset the IOPIC component registers : disable all input IRQs 251 253 for( i = 0 ; i < CONFIG_MAX_EXTERNAL_IRQS ; i++ ) 252 254 { … … 364 366 { 365 367 // 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; 372 375 else assert( false , __FUNCTION__ , "illegal device functionnal type\n"); 373 376 … … 385 388 uint32_t lsb_wdata = (uint32_t)wti_xp; 386 389 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 ); 389 392 hal_remote_sw( lsb_xp , lsb_wdata ); 390 393 hal_remote_sw( msb_xp , msb_wdata ); 391 394 392 // unmaskIRQ in IOPIC393 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 ); 394 397 395 398 // update the WTI interrupt vector for core[lid] 396 399 core_t * core = &LOCAL_CLUSTER->core_tbl[lid]; 397 400 ((soclib_pic_core_t *)core->pic_extend)->wti_vector[wti_id] = src_chdev; 401 402 pic_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 398 405 } 399 406 else if( (func == DEV_FUNC_DMA) || (func == DEV_FUNC_MMC) ) // internal IRQ => HWI … … 411 418 core_t * core = &LOCAL_CLUSTER->core_tbl[lid]; 412 419 ((soclib_pic_core_t *)core->pic_extend)->wti_vector[hwi_id] = src_chdev; 420 421 pic_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 413 424 } 414 425 else … … 494 505 495 506 // 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; 497 508 base[(XCU_PTI_PER << 5) | lid] = cycles; 498 509 … … 525 536 } 526 537 527 528 538 ///////////////////////// 539 void 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 1 1 /* 2 * soclib_pic. c- soclib PIC driver definition.2 * soclib_pic.h - soclib PIC driver definition. 3 3 * 4 4 * Author Alain Greiner (2016,2017) … … 90 90 #define SOCLIB_MAX_PTI 16 91 91 92 #define SOCLIB_CYCLES_PER_MS 1000 // for a SystemC virtual prototype92 #define SOCLIB_CYCLES_PER_MS 60 // SystemC virtual prototype at 60 KHz 93 93 94 94 /****************************************************************************************** … … 238 238 239 239 /****************************************************************************************** 240 * This function activates the WTI[lid] in the local cluster, where helid is the calling240 * This function activates the WTI[lid] in the local cluster, where lid is the calling 241 241 * core local index. 242 242 *****************************************************************************************/ … … 252 252 void soclib_pic_send_ipi( cxy_t cxy, 253 253 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 *****************************************************************************************/ 259 void soclib_pic_ack_ipi(); 254 260 255 261 -
trunk/hal/tsar_mips32/drivers/soclib_tty.c
r296 r407 27 27 #include <remote_spinlock.h> 28 28 #include <thread.h> 29 #include <printk.h> 29 30 #include <hal_special.h> 31 32 #if CONFIG_READ_DEBUG 33 extern uint32_t enter_tty_cmd; 34 extern uint32_t exit_tty_cmd; 35 36 extern uint32_t enter_tty_isr; 37 extern uint32_t exit_tty_isr; 38 #endif 30 39 31 40 /////////////////////////////////////// 32 41 void soclib_tty_init( chdev_t * chdev ) 33 42 { 43 xptr_t reg_xp; 44 34 45 chdev->cmd = &soclib_tty_cmd; 35 46 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; 39 52 40 53 // get SOCLIB_TTY device cluster and local pointer … … 42 55 uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp ); 43 56 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 ); 46 64 } 47 65 … … 49 67 void __attribute__ ((noinline)) soclib_tty_cmd( xptr_t th_xp ) 50 68 { 69 70 #if CONFIG_READ_DEBUG 71 enter_tty_cmd = hal_time_stamp(); 72 #endif 73 74 txt_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 51 77 // get client thread cluster and local pointer 52 78 cxy_t th_cxy = GET_CXY( th_xp ); … … 57 83 xptr_t dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) ); 58 84 85 assert( (type == TXT_READ) || (type == TXT_WRITE) , __FUNCTION__, "illegal command type"); 86 59 87 // get TXT device cluster and local pointer 60 88 cxy_t dev_cxy = GET_CXY( dev_xp ); … … 72 100 uint32_t * base = tty_ptr + TTY_SPAN * channel; 73 101 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 110 txt_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 117 txt_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 121 exit_tty_cmd = hal_time_stamp(); 122 #endif 123 124 } // end soclib_tty_cmd() 125 126 ///////////////////////////////////////////////////////////// 127 void __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++ ) 75 154 { 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 ); 85 165 } 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() 130 167 131 168 … … 135 172 uint32_t type; // command type 136 173 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 138 178 uint32_t status; // TTY terminal status 139 179 char byte; // read byte 140 180 uint32_t i; 181 182 #if CONFIG_READ_DEBUG 183 enter_tty_isr = hal_time_stamp(); 184 #endif 141 185 142 186 // get extended pointer on client thread … … 153 197 buf_xp = hal_remote_lwd( XPTR( client_cxy , &client_ptr->txt_cmd.buf_xp ) ); 154 198 199 txt_dmsg("\n[DBG] %s : core[%x,%d] enter / cycle %d\n", 200 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid , hal_time_stamp() ); 201 155 202 // get SOCLIB_TTY peripheral cluster and local pointer 156 203 cxy_t tty_cxy = GET_CXY( chdev->base ); … … 160 207 uint32_t * base = tty_ptr + TTY_SPAN * chdev->channel; 161 208 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 162 214 if( type == TXT_READ ) // read one single character 163 215 { 164 // get TTY_STATUS _REG165 status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ));166 167 if( status & TTY_STATUS_RX_FULL ) // TTY_RX full => transferone byte168 { 169 // get a byte from TTY_READ _REG, and acknowledge RX_IRQ170 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 ); 171 223 172 224 // write it to command buffer 173 225 hal_remote_sb( buf_xp , byte ); 174 175 // update TTY_WRITE_REG if echo mode176 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 else185 {186 hal_remote_sw( XPTR( tty_cxy , base + TTY_WRITE_REG ) , byte );187 }188 }189 226 } 190 227 else // buffer empty => exit ISR for retry … … 192 229 return; 193 230 } 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 ); 194 235 } 195 else if( type == TXT_WRITE ) // write a string236 else if( type == TXT_WRITE ) // write all characters in string 196 237 { 197 238 // loop on characters 198 239 for( i = 0 ; i < count ; i++ ) 199 240 { 200 // get TTY_STATUS _REG201 status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ));202 203 if( (status & TTY_STATUS_TX_FULL) == 0 ) // TTY_TX empty => transferone byte241 // 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 204 245 { 205 246 // get one byte from command buffer 206 247 byte = (char)hal_remote_lb( buf_xp + i ); 207 248 208 // write byte to TTY_WRITE _REG, and acknowledge TX_IRQ209 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 ); 210 251 } 211 252 else // TTY_TX full => update command arguments and exit ISR for retry … … 216 257 } 217 258 } 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 ); 218 263 } 219 264 220 265 // The I/O operation completed when we reach this point 221 222 // mask both TTY_RX_IRQ and TTY_TX_IRQ223 hal_remote_sw( XPTR( tty_cxy , base + TTY_CONFIG_REG ) , 0 );224 266 225 267 // set I/O operation status in command … … 227 269 228 270 // 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 ); 230 272 231 273 // unblock client thread 232 274 thread_unblock( client_xp , THREAD_BLOCKED_IO ); 233 275 276 hal_fence(); 277 278 txt_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 282 exit_tty_isr = hal_time_stamp(); 283 #endif 284 234 285 } // end soclib_tty_isr() 235 286 -
trunk/hal/tsar_mips32/drivers/soclib_tty.h
r75 r407 38 38 ***************************************************************************************/ 39 39 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 44 45 45 #define TTY_SPAN 4// number of registers per channel46 #define TTY_SPAN 8 // number of registers per channel 46 47 47 48 /**************************************************************************************** … … 51 52 #define TTY_STATUS_RX_FULL 1 // TTY_READ_REG full if 1 52 53 #define TTY_STATUS_TX_FULL 2 // TTY_WRITE_REG full if 1 53 54 /****************************************************************************************55 * masks for TTY_CONFIG_REG56 ***************************************************************************************/57 58 #define TTY_CONFIG_RX_ENABLE 1 // TTY_RX IRQ enabled if 159 #define TTY_CONFIG_TX_ENABLE 2 // TTY_TX IRQ enabled if 160 54 61 55 /**************************************************************************************** … … 68 62 69 63 /**************************************************************************************** 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 * **************************************************************************************** 79 70 * @ thread_xp : extended pointer on client thread descriptor. 80 71 ***************************************************************************************/ 81 72 void 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 ***************************************************************************************/ 82 void soclib_tty_aux( void * args ); 82 83 83 84 /**************************************************************************************** -
trunk/hal/x86_64/core/hal_ppm.c
r307 r407 115 115 } 116 116 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 59 59 typedef uint64_t vaddr_t; // XXX 60 60 typedef uint64_t pt_entry_t; // XXX 61 62 /***************************************************************************63 * Pthread related types64 **************************************************************************/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;76 61 77 62 /*************************************************************************** -
trunk/hal/x86_64/core/hal_uspace.c
r299 r407 45 45 } 46 46 47 error_thal_strcpy_to_uspace(char *u_dst, char *k_src, uint32_t max_size)47 void hal_strcpy_to_uspace(char *u_dst, char *k_src, uint32_t max_size) 48 48 { 49 49 x86_panic((char *)__func__); … … 51 51 } 52 52 53 error_thal_strcpy_from_uspace(char *k_dst, char *u_src, uint32_t max_size)53 void hal_strcpy_from_uspace(char *k_dst, char *u_src, uint32_t max_size) 54 54 { 55 55 x86_panic((char *)__func__);
Note: See TracChangeset
for help on using the changeset viewer.