- Timestamp:
- Apr 10, 2019, 10:09:39 AM (6 years ago)
- Location:
- trunk/hal
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/generic/hal_context.h
r457 r625 2 2 * hal_context.h - Generic Thread Context Access API definition. 3 3 * 4 * Author Alain Greiner (2016 )4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 31 31 // and hal_fpu_context_t, defined in hal_context.c file, that are accessed with generic 32 32 // void* pointers stored in the thread descriptor. 33 // - the "hal_c ontext_t" struct is used forthe CPU registers values at context switch.34 // - the "hal_fpu_context_t" struct is used for the FPU registers when required.33 // - the "hal_cpu_context_t" struct saves the CPU registers values at context switch. 34 // - the "hal_fpu_context_t" struct saves the FPU registers values at FPU switch. 35 35 ////////////////////////////////////////////////////////////////////////////////////////// 36 36 … … 56 56 57 57 /**************************************************************************************** 58 * This function is used to implement the fork() system call. 59 * 1) It saves in a remote (child) thread CPU context the current CPU registers values. 60 * Three slots are not simple copies of the parent registers values : 61 * - the thread pointer is set to the child thread local pointer. 62 * - the stack pointer is set to parrent SP + (child_base - parent_base). 63 * - the status register is set to kernel mode with IRQ disabled. 64 * 2) It copies the content of the calling (parent) thread kernel_stack, 65 * to the remote (child) thread kernel_stack. 58 * This function is called the sys_fork() function to complete the fork mechanism. 59 * It is called by th local parent thread to initialize the CPU context of the remote 60 * child thread, identified by the <thread_xp> argument. 61 * It makes three actions: 62 * 1) It copies the current values of the CPU registers of the core running the parent 63 * thread to the remote child CPU context. 64 * 2) It patches four slots of this remote child CPU context: 65 * - the c0_th slot is set to the child thread descriptor pointer. 66 * - the sp_29 slot is set to the child kernel stack pointer. 67 * - the c0_sr slot is set to kernel mode with IRQ disabled. 68 * - the c2_ptpr slot is set to the child process GPT value. 69 * 3) It copies the content of the parent thread kernel_stack, to the child thread 70 * kernel_stack, because the COW mechanism is not available on architectures where 71 * the data MMU is de-activated in kernel mode. 66 72 **************************************************************************************** 67 * @ thread_xp : extended pointer on the remotethread descriptor.73 * @ thread_xp : extended pointer on the child thread descriptor. 68 74 ***************************************************************************************/ 69 75 void hal_cpu_context_fork( xptr_t thread_xp ); -
trunk/hal/generic/hal_gpt.h
r624 r625 167 167 168 168 /**************************************************************************************** 169 * This function is used to implement the "fork" system call: It copies one GPT entry 170 * identified by the <vpn> argument, from a remote <src_gpt_xp> to a local <dst_gpt>. 169 * This function is used to implement the "fork" system call: It copies a remote 170 * source PTE, identified by the <src_gpt_xp> and <src_vpn> arguments, to a local 171 * destination PTE, identified by the <dst_gpt> and <dst_vpn> arguments. 171 172 * It does nothing if the source PTE is not MAPPED and SMALL. 172 173 * It optionnally activates the "Copy on Write" mechanism: when the <cow> argument is 173 174 * true: the GPT_WRITABLE flag is reset, and the GPT_COW flag is set. 174 * A new second level PT2 (s) is allocated fordestination GPT if required.175 * A new second level PT2 is allocated for the destination GPT if required. 175 176 * It returns in the <ppn> and <mapped> arguments the PPN value for the copied PTE, 176 177 * and a boolean indicating if the PTE is mapped and small, and was actually copied. 177 178 **************************************************************************************** 178 * @ dst_gpt : [in] local pointer on the local destination GPT. 179 * @ src_gpt_xp : [in] extended pointer on the remote source GPT. 180 * @ vpn_base : [in] vpn defining the PTE to be copied. 179 * @ dst_gpt : [in] local pointer on local destination GPT. 180 * @ dst_vpn : [in] vpn defining the PTE in the desination GPT. 181 * @ src_gpt_xp : [in] extended pointer on remote source GPT. 182 * @ src_vpn : [in] vpn defining the PTE in the source GPT. 181 183 * @ cow : [in] activate the COPY-On-Write mechanism if true. 182 184 * @ ppn : [out] PPN value (only if mapped is true). … … 185 187 ***************************************************************************************/ 186 188 error_t hal_gpt_pte_copy( gpt_t * dst_gpt, 189 vpn_t dst_vpn, 187 190 xptr_t src_gpt_xp, 188 vpn_t vpn,191 vpn_t src_vpn, 189 192 bool_t cow, 190 193 ppn_t * ppn, -
trunk/hal/generic/hal_special.h
r624 r625 101 101 * This function returns the current value of stack pointer from core register. 102 102 ****************************************************************************************/ 103 uint32_t hal_get_sp( void ); 104 105 /***************************************************************************************** 106 * This function returns the current value of the return adddress from core register. 107 ****************************************************************************************/ 108 uint32_t hal_get_ra( void ); 109 110 /***************************************************************************************** 111 * This function registers a new value in the core stack pointer and returns previous one. 112 ****************************************************************************************/ 113 inline uint32_t hal_set_sp( void * new_val ); 103 reg_t hal_get_sp( void ); 114 104 115 105 /***************************************************************************************** 116 106 * This function returns the faulty address in case of address exception. 117 107 ****************************************************************************************/ 118 uint32_t hal_get_bad_vaddr( void );108 reg_t hal_get_bad_vaddr( void ); 119 109 120 110 /***************************************************************************************** -
trunk/hal/generic/hal_vmm.h
r623 r625 59 59 error_t hal_vmm_kernel_update( struct process_s * process ); 60 60 61 /**************************************************************************************** 62 * Depending on the hardware architecture, this function displays the current state 63 * of the VMM of the process identified by the <process> argument. 64 * It displays all valit GPT entries when the <mapping> argument is true. 65 **************************************************************************************** 66 * @ process : local pointer on user process descriptor. 67 * @ return 0 if success / return ENOMEM if failure. 68 ***************************************************************************************/ 69 void hal_vmm_display( struct process_s * process, 70 bool_t mapping ); 71 72 73 61 74 #endif /* HAL_VMM_H_ */ -
trunk/hal/tsar_mips32/core/hal_context.c
r570 r625 152 152 { 153 153 context->a0_04 = (uint32_t)thread->entry_args; 154 context->sp_29 = (uint32_t)thread->u _stack_base + (uint32_t)thread->u_stack_size- 8;154 context->sp_29 = (uint32_t)thread->user_stack_vseg->max - 8; 155 155 context->ra_31 = (uint32_t)&hal_kentry_eret; 156 156 context->c0_epc = (uint32_t)thread->entry_func; … … 175 175 void hal_cpu_context_fork( xptr_t child_xp ) 176 176 { 177 // allocate a local CPU context in kernel stack178 // It is initialized from local parent context179 // and from child specific values, and is copied in 180 // in the remote child context using a remote_memcpy()177 // get pointer on calling thread 178 thread_t * this = CURRENT_THREAD; 179 180 // allocate a local CPU context in parent kernel stack 181 181 hal_cpu_context_t context; 182 182 183 // get local parent thread local pointer 183 // get local parent thread cluster and local pointer 184 cxy_t parent_cxy = local_cxy; 184 185 thread_t * parent_ptr = CURRENT_THREAD; 185 186 … … 188 189 thread_t * child_ptr = GET_PTR( child_xp ); 189 190 190 // get remote child cpu_context local pointer191 // get local pointer on remote child cpu context 191 192 char * child_context_ptr = hal_remote_lpt( XPTR(child_cxy , &child_ptr->cpu_context) ); 192 193 193 194 // get local pointer on remote child process 194 process_t * process = (process_t *)hal_remote_lpt( XPTR(child_cxy , &child_ptr->process) );195 process_t * process = hal_remote_lpt( XPTR(child_cxy , &child_ptr->process) ); 195 196 196 197 // get ppn of remote child process page table 197 uint32_t pt_ppn = hal_remote_l32( XPTR(child_cxy , &process->vmm.gpt.ppn) ); 198 199 // save CPU registers in local CPU context 198 uint32_t pt_ppn = hal_remote_l32( XPTR(child_cxy , &process->vmm.gpt.ppn) ); 199 200 // get local pointer on parent uzone from parent thread descriptor 201 uint32_t * parent_uzone = parent_ptr->uzone_current; 202 203 // compute local pointer on child uzone 204 uint32_t * child_uzone = (uint32_t *)( (intptr_t)parent_uzone + 205 (intptr_t)child_ptr - 206 (intptr_t)parent_ptr ); 207 208 // update the uzone pointer in child thread descriptor 209 hal_remote_spt( XPTR( child_cxy , &child_ptr->uzone_current ) , child_uzone ); 210 211 #if DEBUG_HAL_CONTEXT 212 uint32_t cycle = (uint32_t)hal_get_cycles(); 213 if( DEBUG_HAL_CONTEXT < cycle ) 214 printk("\n[%s] thread[%x,%x] parent_uzone %x / child_uzone %x / cycle %d\n", 215 __FUNCTION__, this->process->pid, this->trdid, parent_uzone, child_uzone, cycle ); 216 #endif 217 218 // copy parent kernel stack to child thread descriptor 219 // (this includes the uzone, that is allocated in the kernel stack) 220 char * parent_ksp = (char *)hal_get_sp(); 221 char * child_ksp = (char *)((intptr_t)parent_ksp + 222 (intptr_t)child_ptr - 223 (intptr_t)parent_ptr ); 224 225 uint32_t size = (uint32_t)parent_ptr + CONFIG_THREAD_DESC_SIZE - (uint32_t)parent_ksp; 226 227 hal_remote_memcpy( XPTR( child_cxy , child_ksp ), 228 XPTR( local_cxy , parent_ksp ), 229 size ); 230 231 #if DEBUG_HAL_CONTEXT 232 cycle = (uint32_t)hal_get_cycles(); 233 printk("\n[%s] thread[%x,%x] copied kstack from parent %x to child %x / cycle %d\n", 234 __FUNCTION__, this->process->pid, this->trdid, parent_ptr, child_ptr, cycle ); 235 #endif 236 237 // patch the user stack pointer slot in the child uzone[UZ_SP] 238 // because parent and child use the same offset to access the user stack, 239 // but parent and child do not have the same user stack base address. 240 uint32_t parent_us_base = parent_ptr->user_stack_vseg->min; 241 vseg_t * child_us_vseg = hal_remote_lpt( XPTR( child_cxy , &child_ptr->user_stack_vseg ) ); 242 uint32_t child_us_base = hal_remote_l32( XPTR( child_cxy , &child_us_vseg->min ) ); 243 uint32_t parent_usp = parent_uzone[UZ_SP]; 244 uint32_t child_usp = parent_usp + child_us_base - parent_us_base; 245 246 hal_remote_s32( XPTR( child_cxy , &child_uzone[UZ_SP] ) , child_usp ); 247 248 #if DEBUG_HAL_CONTEXT 249 cycle = (uint32_t)hal_get_cycles(); 250 printk("\n[%s] thread[%x,%x] parent_usp %x / child_usp %x / cycle %d\n", 251 __FUNCTION__, this->process->pid, this->trdid, parent_usp, child_usp, cycle ); 252 #endif 253 254 // save current values of CPU registers to local CPU context 200 255 hal_do_cpu_save( &context ); 201 256 202 // From this point, both parent and child threads execute the following code. 203 // They can be distinguished by the CURRENT_THREAD value, and child will only 204 // execute it when it is unblocked by parent, after return to sys_fork(). 205 // - parent thread copies user stack, and patch sp_29 / c0_th / C0_sr / c2_ptpr 206 // - child thread does nothing 207 208 thread_t * current = CURRENT_THREAD; 209 210 if( current == parent_ptr ) // current == parent thread 257 // From this point, both parent and child can execute the following code, 258 // but child thread will only execute it after being unblocked by parent thread. 259 // They can be distinguished by the (CURRENT_THREAD,local_cxy) values, 260 // and we must re-initialise the calling thread pointer from c0_th register 261 262 this = CURRENT_THREAD; 263 264 if( (this == parent_ptr) && (local_cxy == parent_cxy) ) // parent thread 211 265 { 212 // get parent and child stack pointers 213 char * parent_sp = (char *)context.sp_29; 214 char * child_sp = (char *)((intptr_t)parent_sp + 215 (intptr_t)child_ptr - 216 (intptr_t)parent_ptr ); 217 218 // patch kernel_stack pointer, current thread, and status slots 219 context.sp_29 = (uint32_t)child_sp; 266 // patch 4 slots in the local CPU context: the sp_29 / c0_th / C0_sr / c2_ptpr 267 // slots are not identical in parent and child 268 context.sp_29 = context.sp_29 + (intptr_t)child_ptr - (intptr_t)parent_ptr; 220 269 context.c0_th = (uint32_t)child_ptr; 221 270 context.c0_sr = SR_SYS_MODE; 222 271 context.c2_ptpr = pt_ppn >> 1; 223 272 224 // copy local context to remote child context)273 // copy this patched context to remote child context 225 274 hal_remote_memcpy( XPTR( child_cxy , child_context_ptr ), 226 275 XPTR( local_cxy , &context ) , 227 276 sizeof( hal_cpu_context_t ) ); 228 229 // copy kernel stack content from local parent thread to remote child thread 230 uint32_t size = (uint32_t)parent_ptr + CONFIG_THREAD_DESC_SIZE - (uint32_t)parent_sp; 231 hal_remote_memcpy( XPTR( child_cxy , child_sp ), 232 XPTR( local_cxy , parent_sp ), 233 size ); 277 #if DEBUG_HAL_CONTEXT 278 cycle = (uint32_t)hal_get_cycles(); 279 printk("\n[%s] thread[%x,%x] copied CPU context to child / cycle %d\n", 280 __FUNCTION__, this->process->pid, this->trdid, cycle ); 281 #endif 282 283 // parent thread unblock child thread 284 thread_unblock( XPTR( child_cxy , child_ptr ) , THREAD_BLOCKED_GLOBAL ); 285 286 #if DEBUG_HAL_CONTEXT 287 cycle = (uint32_t)hal_get_cycles(); 288 printk("\n[%s] thread[%x,%x] unblocked child thread / cycle %d\n", 289 __FUNCTION__, this->process->pid, this->trdid, cycle ); 290 #endif 291 234 292 } 235 else // current == child thread 236 { 237 assert( (current == child_ptr) , "current = %x / child = %x\n"); 238 } 293 239 294 } // end hal_cpu_context_fork() 240 295 … … 285 340 void hal_cpu_context_destroy( thread_t * thread ) 286 341 { 287 kmem_req_t req; 288 289 req.type = KMEM_CPU_CTX; 290 req.ptr = thread->cpu_context; 291 kmem_free( &req ); 342 kmem_req_t req; 343 344 hal_cpu_context_t * ctx = thread->cpu_context; 345 346 // release CPU context if required 347 if( ctx != NULL ) 348 { 349 req.type = KMEM_CPU_CTX; 350 req.ptr = ctx; 351 kmem_free( &req ); 352 } 292 353 293 354 } // end hal_cpu_context_destroy() … … 348 409 kmem_req_t req; 349 410 350 req.type = KMEM_FPU_CTX; 351 req.ptr = thread->fpu_context; 352 kmem_free( &req ); 411 hal_fpu_context_t * context = thread->fpu_context; 412 413 // release FPU context if required 414 if( context != NULL ) 415 { 416 req.type = KMEM_FPU_CTX; 417 req.ptr = context; 418 kmem_free( &req ); 419 } 353 420 354 421 } // end hal_fpu_context_destroy() -
trunk/hal/tsar_mips32/core/hal_exception.c
r619 r625 189 189 if( CURRENT_THREAD->type != THREAD_USER ) 190 190 { 191 printk("\n[ KERNELPANIC] in %s : illegal thread type %s\n",191 printk("\n[PANIC] in %s : illegal thread type %s\n", 192 192 __FUNCTION__, thread_type_str(CURRENT_THREAD->type) ); 193 193 … … 250 250 else if( error == EXCP_USER_ERROR ) // illegal vaddr 251 251 { 252 printk("\n[ USERERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"252 printk("\n[ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n" 253 253 " %s : epc %x / badvaddr %x / is_ins %d\n", 254 254 __FUNCTION__, this->process->pid, this->trdid, local_cxy, … … 260 260 else // error == EXCP_KERNEL_PANIC 261 261 { 262 printk("\n[ KERNELPANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"262 printk("\n[PANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n" 263 263 " %s : epc %x / badvaddr %x / is_ins %d\n", 264 264 __FUNCTION__, this->process->pid, this->trdid, local_cxy, … … 272 272 case MMU_READ_PRIVILEGE_VIOLATION: // illegal 273 273 { 274 printk("\n[ USERERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"274 printk("\n[ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n" 275 275 " %s : epc %x / badvaddr %x / is_ins %d\n", 276 276 __FUNCTION__, this->process->pid, this->trdid, local_cxy, … … 299 299 else if( error == EXCP_USER_ERROR ) // illegal write access 300 300 { 301 printk("\n[ USERERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"301 printk("\n[ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n" 302 302 " %s : epc %x / badvaddr %x / is_ins %d\n", 303 303 __FUNCTION__, this->process->pid, this->trdid, local_cxy, … … 309 309 else // error == EXCP_KERNEL_PANIC 310 310 { 311 printk("\n[ KERNELPANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"311 printk("\n[PANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n" 312 312 " %s : epc %x / badvaddr %x / is_ins %d\n", 313 313 __FUNCTION__, this->process->pid, this->trdid, local_cxy, … … 320 320 case MMU_READ_EXEC_VIOLATION: // user error 321 321 { 322 printk("\n[ USERERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"322 printk("\n[ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n" 323 323 " %s : epc %x / badvaddr %x / is_ins %d\n", 324 324 __FUNCTION__, this->process->pid, this->trdid, local_cxy, … … 330 330 default: // this is a kernel error 331 331 { 332 printk("\n[ KERNELPANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"332 printk("\n[PANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n" 333 333 " %s : epc %x / badvaddr %x / is_ins %d\n", 334 334 __FUNCTION__, this->process->pid, this->trdid, local_cxy, … … 346 346 ////////////////////////////////////////////////////////////////////////////////////////// 347 347 // @ this : pointer on faulty thread descriptor. 348 // @ error : EXCP_USER_ERROR or EXCP_KERNEL_PANIC 349 ////////////////////////////////////////////////////////////////////////////////////////// 350 static void hal_exception_dump( thread_t * this, 351 error_t error ) 348 ////////////////////////////////////////////////////////////////////////////////////////// 349 static void hal_exception_dump( thread_t * this ) 352 350 { 353 351 core_t * core = this->core; … … 366 364 remote_busylock_acquire( lock_xp ); 367 365 368 if( error == EXCP_USER_ERROR ) 369 { 370 nolock_printk("\n=== USER ERROR / thread(%x,%x) / core[%d] / cycle %d ===\n", 371 process->pid, this->trdid, core->lid, (uint32_t)hal_get_cycles() ); 372 } 373 else 374 { 375 nolock_printk("\n=== KERNEL PANIC / thread(%x,%x) / core[%d] / cycle %d ===\n", 376 process->pid, this->trdid, core->lid, (uint32_t)hal_get_cycles() ); 377 } 366 nolock_printk("\n=== thread(%x,%x) / core[%d] / cycle %d ===\n", 367 process->pid, this->trdid, core->lid, (uint32_t)hal_get_cycles() ); 378 368 379 369 nolock_printk("busylocks = %d / blocked_vector = %X / flags = %X\n\n", … … 507 497 if( error == EXCP_USER_ERROR ) // user error => kill user process 508 498 { 509 hal_exception_dump( this , error);499 hal_exception_dump( this ); 510 500 511 501 sys_exit( EXIT_FAILURE ); … … 513 503 else if( error == EXCP_KERNEL_PANIC ) // kernel error => kernel panic 514 504 { 515 hal_exception_dump( this , error);505 hal_exception_dump( this ); 516 506 517 507 hal_core_sleep(); -
trunk/hal/tsar_mips32/core/hal_gpt.c
r624 r625 823 823 /////////////////////////////////////////// 824 824 error_t hal_gpt_pte_copy( gpt_t * dst_gpt, 825 vpn_t dst_vpn, 825 826 xptr_t src_gpt_xp, 826 vpn_t vpn,827 vpn_t src_vpn, 827 828 bool_t cow, 828 829 ppn_t * ppn, 829 830 bool_t * mapped ) 830 831 { 831 uint32_t ix1; // index in PT1 832 uint32_t ix2; // index in PT2 832 uint32_t src_ix1; // index in SRC PT1 833 uint32_t src_ix2; // index in SRC PT2 834 835 uint32_t dst_ix1; // index in DST PT1 836 uint32_t dst_ix2; // index in DST PT2 833 837 834 838 cxy_t src_cxy; // SRC GPT cluster … … 862 866 thread_t * this = CURRENT_THREAD; 863 867 if( DEBUG_HAL_GPT_COPY < cycle ) 864 printk("\n[%s] : thread[%x,%x] enter / vpn %x /src_cxy %x / dst_cxy %x / cycle %d\n",865 __FUNCTION__, this->process->pid, this->trdid, vpn,src_cxy, local_cxy, cycle );868 printk("\n[%s] : thread[%x,%x] enter / src_cxy %x / dst_cxy %x / cycle %d\n", 869 __FUNCTION__, this->process->pid, this->trdid, src_cxy, local_cxy, cycle ); 866 870 #endif 867 871 … … 878 882 assert( (dst_pt1 != NULL) , "dst_pt1 does not exist\n"); 879 883 880 ix1 = TSAR_MMU_IX1_FROM_VPN( vpn ); 881 ix2 = TSAR_MMU_IX2_FROM_VPN( vpn ); 884 // compute SRC indexes 885 src_ix1 = TSAR_MMU_IX1_FROM_VPN( src_vpn ); 886 src_ix2 = TSAR_MMU_IX2_FROM_VPN( src_vpn ); 887 888 // compute DST indexes 889 dst_ix1 = TSAR_MMU_IX1_FROM_VPN( dst_vpn ); 890 dst_ix2 = TSAR_MMU_IX2_FROM_VPN( dst_vpn ); 882 891 883 892 // get src_pte1 884 src_pte1 = hal_remote_l32( XPTR( src_cxy , &src_pt1[ ix1] ) );893 src_pte1 = hal_remote_l32( XPTR( src_cxy , &src_pt1[src_ix1] ) ); 885 894 886 895 // do nothing if src_pte1 not MAPPED or not SMALL … … 888 897 { 889 898 // get dst_pt1 entry 890 dst_pte1 = dst_pt1[ ix1];899 dst_pte1 = dst_pt1[dst_ix1]; 891 900 892 901 // map dst_pte1 if required … … 915 924 916 925 // register it in DST_GPT 917 dst_pt1[ ix1] = dst_pte1;926 dst_pt1[dst_ix1] = dst_pte1; 918 927 } 919 928 … … 927 936 928 937 // get attr and ppn from SRC_PT2 929 src_pte2_attr = hal_remote_l32( XPTR( src_cxy , &src_pt2[2 * ix2] ) );930 src_pte2_ppn = hal_remote_l32( XPTR( src_cxy , &src_pt2[2 * ix2 + 1] ) );938 src_pte2_attr = hal_remote_l32( XPTR( src_cxy , &src_pt2[2 * src_ix2] ) ); 939 src_pte2_ppn = hal_remote_l32( XPTR( src_cxy , &src_pt2[2 * src_ix2 + 1] ) ); 931 940 932 941 // do nothing if src_pte2 not MAPPED … … 934 943 { 935 944 // set PPN in DST PTE2 936 dst_pt2[2 *ix2+1] = src_pte2_ppn;945 dst_pt2[2 * dst_ix2 + 1] = src_pte2_ppn; 937 946 938 947 // set attributes in DST PTE2 939 948 if( cow && (src_pte2_attr & TSAR_MMU_WRITABLE) ) 940 949 { 941 dst_pt2[2 *ix2] = (src_pte2_attr | TSAR_MMU_COW) & (~TSAR_MMU_WRITABLE);950 dst_pt2[2 * dst_ix2] = (src_pte2_attr | TSAR_MMU_COW) & (~TSAR_MMU_WRITABLE); 942 951 } 943 952 else 944 953 { 945 dst_pt2[2 *ix2] = src_pte2_attr;954 dst_pt2[2 * dst_ix2] = src_pte2_attr; 946 955 } 947 956 … … 953 962 cycle = (uint32_t)hal_get_cycles; 954 963 if( DEBUG_HAL_GPT_COPY < cycle ) 955 printk("\n[%s] : thread[%x,%x] exit / copy done for vpn %x / cycle %d\n",956 __FUNCTION__, this->process->pid, this->trdid, vpn, cycle );964 printk("\n[%s] : thread[%x,%x] exit / copy done for src_vpn %x / dst_vpn %x / cycle %d\n", 965 __FUNCTION__, this->process->pid, this->trdid, src_vpn, dst_vpn, cycle ); 957 966 #endif 958 967 … … 970 979 cycle = (uint32_t)hal_get_cycles; 971 980 if( DEBUG_HAL_GPT_COPY < cycle ) 972 printk("\n[%s] : thread[%x,%x] exit / nothing done for vpn %x/ cycle %d\n",973 __FUNCTION__, this->process->pid, this->trdid, vpn,cycle );981 printk("\n[%s] : thread[%x,%x] exit / nothing done / cycle %d\n", 982 __FUNCTION__, this->process->pid, this->trdid, cycle ); 974 983 #endif 975 984 -
trunk/hal/tsar_mips32/core/hal_kentry.S
r438 r625 4 4 * AUthors Ghassan Almaless (2007,2008,2009,2010,2011,2012) 5 5 * Mohamed Lamine Karaoui (2015) 6 * Alain Greiner (201 7)6 * Alain Greiner (2016,2017,2018,2019) 7 7 * 8 8 * Copyright (c) UPMC Sorbonne Universites … … 87 87 #------------------------------------------------------------------------------------ 88 88 # Kernel Entry point for Interrupt / Exception / Syscall 89 # The c2_dext and c2_iext CP2 registersmust have been previously set90 # to "local_cxy", because the kernel run with MMU desactivated.89 # The c2_dext CP2 register must have been previously set 90 # to "local_cxy", because the kernel run with data MMU desactivated. 91 91 #------------------------------------------------------------------------------------ 92 92 … … 96 96 andi $26, $26, 0x10 # test User Mode bit 97 97 beq $26, $0, kernel_mode # jump if core already in kernel 98 ori $27, $0, 0x 3 # $27 <= code forMMU OFF98 ori $27, $0, 0xB # $27 <= code data MMU OFF 99 99 100 100 #------------------------------------------------------------------------------------ … … 102 102 # to handle a syscall, an interrupt, or an user exception. 103 103 # - save current c2_mode in $26. 104 # - set MMU OFF.104 # - set data MMU OFF. 105 105 # - copy user stack pointer in $27 to be saved in uzone. 106 # - set kernel stack pointer in $29 == top_kernel_stack(this).106 # - set kernel stack pointer in $29 (kernel stack empty at firts entry). 107 107 108 108 user_mode: 109 109 110 110 mfc2 $26, $1 # $26 <= c2_mode 111 mtc2 $27, $1 # set MMU OFF111 mtc2 $27, $1 # set data MMU OFF 112 112 move $27, $29 # $27 <= user stack pointer 113 113 mfc0 $29, $4, 2 # get pointer on thread descriptor from c0_th … … 121 121 # after a syscall, to handle an interrupt, or to handle a non-fatal exception. 122 122 # - save current c2_mode in $26. 123 # - set MMU OFF.123 # - set data MMU OFF. 124 124 # - copy current kernel stack pointer in $27. 125 125 … … 127 127 128 128 mfc2 $26, $1 # $26 <= c2_mode 129 mtc2 $27, $1 # set MMU OFF129 mtc2 $27, $1 # set data MMU OFF 130 130 move $27, $29 # $27 <= current kernel stack pointer 131 131 … … 133 133 # This code is executed in both modes (user or kernel): 134 134 # The assumptions are: 135 # - c2_mode contains the MMU OFF value.135 # - c2_mode contains the data MMU OFF value. 136 136 # - $26 contains the previous c2_mode value. 137 137 # - $27 contains the previous sp value (can be usp or ksp). … … 139 139 # We execute the following actions: 140 140 # - decrement $29 to allocate an uzone in kernel stack 141 # - save relevantGPR, CP0 and CP2 registers to uzone.142 # - set the SR in kernel mode: IRQ disabled, clear exl.141 # - save GPR, CP0 and CP2 registers to uzone. 142 # - set the SR in kernel mode: IRQ disabled, clear EXL. 143 143 144 144 unified_mode: … … 195 195 sw $26, (UZ_MODE*4)($29) # save previous c2_mode (can be user or kernel) 196 196 197 mfc0 $3, $12 197 mfc0 $3, $12 # $3 <= c0_sr 198 198 srl $3, $3, 5 199 199 sll $3, $3, 5 # reset 5 LSB bits … … 216 216 nop 217 217 move $4, $2 218 jal putd 219 nop 220 la $4, msg_crlf 221 jal puts 222 nop 223 # display saved CR value 224 la $4, msg_cr 225 jal puts 226 nop 227 lw $4, (UZ_CR*4)($29) 218 228 jal putx 219 229 nop … … 286 296 287 297 #------------------------------------------------------------------------------------ 288 # This code handle the uzone pointers stack, and calls the relevant298 # This code handle the two-slots uzone pointers stack, and calls the relevant 289 299 # Interrupt / Exception / Syscall handler, depending on XCODE in CP0_CR. 290 300 # Both the hal_do_syscall() and the hal_do_exception() functions use … … 338 348 # - All registers saved in the uzone are restored, using the pointer on uzone, 339 349 # that is contained in $29. 340 # - The " uzone" field in thread descriptor, that has beeen modified at kernel entry341 # is restored from value contained in the uzone[UZ_SP] slot.350 # - The "current_uzone" pointer in thread descriptor, that has beeen modified at 351 # kernel entry is restored from value contained in the uzone[UZ_SP] slot. 342 352 # ----------------------------------------------------------------------------------- 343 353 … … 365 375 nop 366 376 move $4, $2 377 jal putd 378 nop 379 la $4, msg_crlf 380 jal puts 381 nop 382 # display saved CR value 383 la $4, msg_cr 384 jal puts 385 nop 386 lw $4, (UZ_CR*4)($29) 367 387 jal putx 368 388 nop … … 479 499 480 500 lw $26, (UZ_MODE*4)($27) 481 mtc2 $26, $1 # restore CP2_MODEfrom uzone501 mtc2 $26, $1 # restore c2_mode from uzone 482 502 483 503 # ----------------------------------------------------------------------------------- … … 494 514 .section .kdata 495 515 516 msg_cr: 517 .align 2 518 .asciiz "- UZ_CR = " 496 519 msg_sp: 497 520 .align 2 -
trunk/hal/tsar_mips32/core/hal_kentry.h
r481 r625 1 1 /* 2 * hal_kentry.h - MIPS32 registers mnemonics2 * hal_kentry.h - uzone definition 3 3 * 4 * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless 5 * Copyright (c) 2011,2012 UPMC Sorbonne Universites 4 * Author Alain Greiner (2016,2017,2018,2019) 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 … … 28 29 // a fixed size array of 32 bits integers, used by the kentry function to save/restore 29 30 // the MIPS32 CPU registers, at each exception / interruption / syscall. 30 // It also defines several initial values for the SR register.31 31 // 32 32 // This file is included in the hal_kentry.S, hal_syscall.c, hal_exception.c, … … 36 36 37 37 /**************************************************************************************** 38 * This structure defines the cpu_uzone dynamically allocated in the kernel stack 39 * by the hal_kentry assembly code for the TSAR_MIPS32 architecture. 38 * This structure defines the "uzone" dynamically allocated in the kernel stack 39 * by the hal_kentry assembly code to save the MIPS32 registers each time a core 40 * enters the kernel to handle an interrupt, exception, or syscall. 41 * These define are specific for the TSAR_MIPS32 architecture. 42 * 40 43 * WARNING : It is replicated in hal_kentry.S file. 41 44 ***************************************************************************************/ … … 87 90 * The hal_kentry_enter() function is the unique kernel entry point in case of 88 91 * exception, interrupt, or syscall for the TSAR_MIPS32 architecture. 89 * It can be executed by a core in user mode (in case of exception or syscall), 90 * or by a core already in kernel mode (in case of interrupt). 91 * 92 * It can be executed by a core in user mode or by a core already in kernel mode 93 * (in case of interrupt or non fatal exception). 92 94 * In both cases it allocates an "uzone" space in the kernel stack to save the 93 95 * CPU registers values, desactivates the MMU, and calls the relevant handler … … 95 97 * 96 98 * After handler execution, it restores the CPU context from the uzone and jumps 97 * to address contained in EPC calling hal_kentry_eret()99 * to address contained in EPC calling the hal_kentry_eret() function. 98 100 ************************************************************************************/ 99 101 void hal_kentry_enter( void ); … … 101 103 /************************************************************************************* 102 104 * The hal_kentry_eret() function contains only the assembly "eret" instruction, 103 * that reset the EXL bit in the c0_sr register, and jump to the address105 * that reset the EXL bit in the c0_sr register, and jumps to the address 104 106 * contained in the c0_epc register. 105 107 * ************************************************************************************/ -
trunk/hal/tsar_mips32/core/hal_remote.c
r610 r625 381 381 uint32_t scxy = (uint32_t)GET_CXY( src ); 382 382 383 /*384 if( local_cxy == 1 )385 printk("\n@@@ %s : scxy %x / sptr %x / dcxy %x / dptr %x\n",386 __FUNCTION__, scxy, sptr, dcxy, dptr );387 */388 383 hal_disable_irq( &save_sr ); 389 384 -
trunk/hal/tsar_mips32/core/hal_special.c
r624 r625 40 40 extern cxy_t local_cxy; 41 41 extern void hal_kentry_enter( void ); 42 43 //////////////////////////////////////////////////////////////////////////////// 44 // For the TSAR architecture, this function registers the address of the 45 // hal_kentry_enter() function in the MIPS32 cp0_ebase register. 46 //////////////////////////////////////////////////////////////////////////////// 47 void hal_set_kentry( void ) 48 { 49 uint32_t kentry = (uint32_t)(&hal_kentry_enter); 50 51 asm volatile("mtc0 %0, $15, 1" : : "r" (kentry) ); 52 } 42 53 43 54 ///////////////////////////////////////////////////////////////////////////////// … … 48 59 void hal_mmu_init( gpt_t * gpt ) 49 60 { 50 51 // set PT1 base address in mmu_ptpr register 61 // set PT1 base address in cp2_ptpr register 52 62 uint32_t ptpr = (((uint32_t)gpt->ptr) >> 13) | (local_cxy << 19); 53 63 asm volatile ( "mtc2 %0, $0 \n" : : "r" (ptpr) ); 54 64 55 // set ITLB | ICACHE | DCACHE bits in mmu_mode register65 // set ITLB | ICACHE | DCACHE bits in cp2_mode register 56 66 asm volatile ( "ori $26, $0, 0xB \n" 57 67 "mtc2 $26, $1 \n" ); … … 59 69 60 70 //////////////////////////////////////////////////////////////////////////////// 61 // For the TSAR architecture, this function registers the address of the 62 // hal_kentry_enter() function in the MIPS32 cp0_ebase register. 63 //////////////////////////////////////////////////////////////////////////////// 64 void hal_set_kentry( void ) 65 { 66 uint32_t kentry = (uint32_t)(&hal_kentry_enter); 67 68 asm volatile("mtc0 %0, $15, 1" : : "r" (kentry) ); 69 } 70 71 //////////////////////////////// 71 // For the TSAR architecture, this function returns the current value 72 // of the 32 bits c0_sr register 73 //////////////////////////////////////////////////////////////////////////////// 74 inline reg_t hal_get_sr( void ) 75 { 76 reg_t sr; 77 78 asm volatile ("mfc0 %0, $12" : "=&r" (sr)); 79 80 return sr; 81 } 82 83 //////////////////////////////////////////////////////////////////////////////// 84 // For the TSAR architecture, this function returns the 10 LSB bits 85 // of the 32 bits c0_ebase register : Y (4 bits) | Y (4 bits) | LID (2 bits) 86 //////////////////////////////////////////////////////////////////////////////// 72 87 inline gid_t hal_get_gid( void ) 73 88 { … … 79 94 } 80 95 81 /////////////////////////////////// 96 //////////////////////////////////////////////////////////////////////////////// 97 // For the TSAR architecture, this function returns the current value 98 // of the 32 bits c0_count cycle counter. 99 //////////////////////////////////////////////////////////////////////////////// 82 100 inline reg_t hal_time_stamp( void ) 83 101 { … … 87 105 88 106 return count; 89 }90 91 ///////////////////////////////92 inline reg_t hal_get_sr( void )93 {94 reg_t sr;95 96 asm volatile ("mfc0 %0, $12" : "=&r" (sr));97 98 return sr;99 107 } 100 108 … … 131 139 } 132 140 133 /////////////////////////////////////////////////////// 141 //////////////////////////////////////////////////////////////////////////////// 142 // For the TSAR architecture, this function returns the current value 143 // of the 32 bits c0_th register. 144 //////////////////////////////////////////////////////////////////////////////// 134 145 inline struct thread_s * hal_get_current_thread( void ) 135 146 { … … 141 152 } 142 153 143 /////////////////////////////////////////////////////// 154 //////////////////////////////////////////////////////////////////////////////// 155 // For the TSAR architecture, this function set a new value 156 // to the 32 bits c0_th register. 157 //////////////////////////////////////////////////////////////////////////////// 144 158 void hal_set_current_thread( struct thread_s * thread ) 145 159 { … … 182 196 } 183 197 184 /////////////////////////// 185 uint32_t hal_get_sp( void ) 198 //////////////////////////////////////////////////////////////////////////////// 199 // For the TSAR architecture, this function returns the current value 200 // of the 32 bits sp_29 register. 201 //////////////////////////////////////////////////////////////////////////////// 202 reg_t hal_get_sp( void ) 186 203 { 187 204 register uint32_t sp; … … 190 207 191 208 return sp; 192 }193 194 /////////////////////////////////////195 uint32_t hal_set_sp( void * new_val )196 {197 register uint32_t sp;198 199 asm volatile200 ( "or %0, $0, $29 \n"201 "or $29, $0, %1 \n"202 : "=&r" (sp) : "r" (new_val) );203 204 return sp;205 }206 207 ///////////////////////////208 uint32_t hal_get_ra( void )209 {210 register uint32_t ra;211 212 asm volatile ("or %0, $0, $31" : "=&r" (ra));213 214 return ra;215 209 } 216 210 -
trunk/hal/tsar_mips32/core/hal_switch.S
r457 r625 2 2 * hal_witch.S - CPU context switch function for TSAR-MIPS32 3 3 * 4 * Author Alain Greiner (2016 )4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites -
trunk/hal/tsar_mips32/core/hal_syscall.c
r481 r625 29 29 #include <hal_kentry.h> 30 30 31 ///////////////////// 31 /////////////////////////// 32 32 void hal_do_syscall( void ) 33 33 { … … 63 63 service_num ); 64 64 65 // get pointer on exit_thread uzone, because 66 // exit_thread can be different from enter_thread65 // get pointer on exit_thread uzone, because exit thread 66 // can be different from enter_thread for a fork syscall 67 67 this = CURRENT_THREAD; 68 68 exit_uzone = (uint32_t *)this->uzone_current; -
trunk/hal/tsar_mips32/core/hal_uspace.c
r610 r625 249 249 ".set noreorder \n" 250 250 "move $13, %1 \n" /* $13 <= str */ 251 "mfc2 $15, $1 \n" /* $15 <= DTLB and ITLB off*/251 "mfc2 $15, $1 \n" /* $15 <= MMU_MODE (DTLB off) */ 252 252 "ori $14, $15, 0x4 \n" /* $14 <= mode DTLB on */ 253 253 "1: \n" 254 254 "mtc2 $14, $1 \n" /* set DTLB on */ 255 "lb $12, 0($13) \n" /* read char from user space*/255 "lb $12, 0($13) \n" /* $12 <= one byte from u_space */ 256 256 "mtc2 $15, $1 \n" /* set DTLB off */ 257 257 "addi $13, $13, 1 \n" /* increment address */ -
trunk/hal/tsar_mips32/core/hal_vmm.c
r624 r625 48 48 // This function is called by the process_zero_init() function during kernel_init. 49 49 // It initializes the VMM of the kernel proces_zero (containing all kernel threads) 50 // in the local cluster: it registers one "kcode" vseg in kernel VSL, and registers51 // one big page in slot[0] of kernel GPT.50 // in the local cluster: For TSAR, it registers one "kcode" vseg in kernel VSL, 51 // and registers one big page in slot[0] of kernel GPT. 52 52 ////////////////////////////////////////////////////////////////////////////////////////// 53 53 error_t hal_vmm_kernel_init( boot_info_t * info ) … … 119 119 return 0; 120 120 121 } // end hal_ kernel_vmm_init()122 123 ////////////////////////////////////////////////////////////////////////////////////////// 124 // This function is called by the vmm_init() function to update the VMM of an user125 // process identified by the <process> argument.126 // It registers in the user VSL the "kcode" vseg, registered inthe local kernel VSL,127 // and register in the user GPT the big page[0] mapped inthe local kernel GPT.121 } // end hal_vmm_kernel_init() 122 123 ////////////////////////////////////////////////////////////////////////////////////////// 124 // This function registers in the VMM of an user process identified by the <process> 125 // argument all required kernel vsegs. 126 // For TSAR, it registers in the user VSL the "kcode" vseg, from the local kernel VSL, 127 // and register in the user GPT the big page[0] from the local kernel GPT. 128 128 ////////////////////////////////////////////////////////////////////////////////////////// 129 129 error_t hal_vmm_kernel_update( process_t * process ) 130 130 { 131 error_t error;131 error_t error; 132 132 uint32_t attr; 133 133 uint32_t ppn; 134 134 135 // get cluster identifier 136 cxy_t cxy = local_cxy; 137 135 138 #if DEBUG_HAL_VMM 136 139 thread_t * this = CURRENT_THREAD; 137 140 printk("\n[%s] thread[%x,%x] enter in cluster %x \n", 138 __FUNCTION__, this->process->pid, this->trdid, local_cxy ); 141 __FUNCTION__, this->process->pid, this->trdid, cxy ); 142 hal_vmm_display( &process_zero , true ); 139 143 hal_vmm_display( process , true ); 140 hal_vmm_display( &process_zero , true ); 141 #endif 142 143 // get cluster identifier 144 cxy_t cxy = local_cxy; 145 146 // get extended pointer on kernel GPT 144 #endif 145 146 // get extended pointer on local kernel GPT 147 147 xptr_t k_gpt_xp = XPTR( cxy , &process_zero.vmm.gpt ); 148 148 … … 212 212 bool_t mapping ) 213 213 { 214 // get pointer on process VMM 214 215 vmm_t * vmm = &process->vmm; 215 gpt_t * gpt = &vmm->gpt;216 216 217 217 // get pointers on TXT0 chdev … … 220 220 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); 221 221 222 // get extended pointer on remote TXT0lock223 xptr_t lock_xp = XPTR( txt0_cxy, &txt0_ptr->wait_lock );224 225 // get locks protecting the VSL and the GPT226 remote_rwlock_rd_acquire( XPTR( local_cxy , &vmm->vsegs_lock ) ); 227 remote_rwlock_rd_acquire( XPTR( local_cxy , &vmm->gpt_lock ) );228 229 // get TXT0 lock 230 remote_busylock_acquire( lock_xp );231 232 nolock_printk("\n***** VSL and GPT for process %x in cluster %x\n",233 process->pid , local_cxy);234 235 // scan the list of vsegs236 xptr_t root_xp = XPTR( local_cxy , &vmm->vsegs_root);237 xptr_t iter_xp; 238 xptr_t vseg_xp;239 vseg_t * vseg;240 XLIST_FOREACH( root_xp , iter_xp )241 {242 vseg_xp = XLIST_ELEMENT( iter_xp , vseg_t , xlist );243 vseg = GET_PTR( vseg_xp );244 245 nolock_printk(" - %s : base = %X / size = %X / npages = %d\n",246 vseg_t ype_str( vseg->type ) , vseg->min , vseg->max - vseg->min , vseg->vpn_size );247 248 if( mapping)222 // build extended pointers on TXT0 lock, GPT lock and VSL lock 223 xptr_t txt_lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock ); 224 xptr_t vsl_lock_xp = XPTR( local_cxy , &vmm->vsl_lock ); 225 xptr_t gpt_lock_xp = XPTR( local_cxy , &vmm->gpt_lock ); 226 227 // get root of vsegs list 228 xptr_t root_xp = XPTR( local_cxy , &vmm->vsegs_root ); 229 230 // get the locks protecting TXT0, VSL, and GPT 231 remote_rwlock_rd_acquire( vsl_lock_xp ); 232 remote_rwlock_rd_acquire( gpt_lock_xp ); 233 remote_busylock_acquire( txt_lock_xp ); 234 235 nolock_printk("\n***** VSL and GPT for process %x in cluster %x / PT1 = %x\n", 236 process->pid , local_cxy , vmm->gpt.ptr ); 237 238 if( xlist_is_empty( root_xp ) ) 239 { 240 nolock_printk(" ... no vsegs registered\n"); 241 } 242 else // scan the list of vsegs 243 { 244 xptr_t iter_xp; 245 xptr_t vseg_xp; 246 vseg_t * vseg; 247 248 XLIST_FOREACH( root_xp , iter_xp ) 249 249 { 250 vpn_t vpn = vseg->vpn_base; 251 vpn_t vpn_max = vpn + vseg->vpn_size; 252 ppn_t ppn; 253 uint32_t attr; 254 255 while( vpn < vpn_max ) 250 vseg_xp = XLIST_ELEMENT( iter_xp , vseg_t , xlist ); 251 vseg = GET_PTR( vseg_xp ); 252 253 nolock_printk(" - %s : base = %X / size = %X / npages = %d\n", 254 vseg_type_str(vseg->type), vseg->min, vseg->max - vseg->min, vseg->vpn_size ); 255 256 if( mapping ) 256 257 { 257 hal_gpt_get_pte( XPTR( local_cxy , gpt ) , vpn , &attr , &ppn ); 258 259 if( attr & GPT_MAPPED ) 258 vpn_t vpn = vseg->vpn_base; 259 vpn_t vpn_max = vpn + vseg->vpn_size; 260 ppn_t ppn; 261 uint32_t attr; 262 263 while( vpn < vpn_max ) // scan the PTEs 260 264 { 261 if( attr & GPT_SMALL ) 265 hal_gpt_get_pte( XPTR( local_cxy , &vmm->gpt ) , vpn , &attr , &ppn ); 266 267 if( attr & GPT_MAPPED ) 262 268 { 263 nolock_printk(" . SMALL : vpn = %X / attr = %X / ppn = %X\n", 264 vpn , attr , ppn ); 265 vpn++; 269 if( attr & GPT_SMALL ) 270 { 271 nolock_printk(" . SMALL : vpn = %X / attr = %X / ppn = %X\n", 272 vpn , attr , ppn ); 273 vpn++; 274 } 275 else 276 { 277 nolock_printk(" . BIG : vpn = %X / attr = %X / ppn = %X\n", 278 vpn , attr , ppn ); 279 vpn += 512; 280 } 266 281 } 267 282 else 268 283 { 269 nolock_printk(" . BIG : vpn = %X / attr = %X / ppn = %X\n", 270 vpn , attr , ppn ); 271 vpn += 512; 284 vpn++; 272 285 } 273 }274 else275 {276 vpn++;277 286 } 278 287 } … … 280 289 } 281 290 282 // release TXT0 lock 283 remote_busylock_release( lock_xp ); 284 285 // release the VSK and GPT locks 286 remote_rwlock_rd_release( XPTR( local_cxy , &vmm->vsegs_lock ) ); 287 remote_rwlock_rd_release( XPTR( local_cxy , &vmm->gpt_lock ) ); 291 // release locks 292 remote_busylock_release( txt_lock_xp ); 293 remote_rwlock_rd_release( gpt_lock_xp ); 294 remote_rwlock_rd_release( vsl_lock_xp ); 288 295 289 296 } // hal_vmm_display() -
trunk/hal/tsar_mips32/drivers/soclib_tty.c
r619 r625 346 346 owner_pid = hal_remote_l32( XPTR( owner_cxy , &owner_ptr->pid ) ); 347 347 348 // block TXT owner process only if it is not the INIT process 349 if( owner_pid != 1 ) 350 { 351 // get parent process descriptor pointers 352 parent_xp = hal_remote_l64( XPTR( owner_cxy , &owner_ptr->parent_xp ) ); 353 parent_cxy = GET_CXY( parent_xp ); 354 parent_ptr = GET_PTR( parent_xp ); 355 356 // get pointers on the parent process main thread 357 parent_main_ptr = hal_remote_lpt(XPTR(parent_cxy,&parent_ptr->th_tbl[0])); 358 parent_main_xp = XPTR( parent_cxy , parent_main_ptr ); 359 360 // transfer TXT ownership 361 process_txt_transfer_ownership( owner_xp ); 362 363 // block all threads in all clusters, but the main thread 364 process_sigaction( owner_pid , BLOCK_ALL_THREADS ); 365 366 // block the main thread 367 xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] ); 368 thread_block( main_xp , THREAD_BLOCKED_GLOBAL ); 369 370 // atomically update owner process termination state 371 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 372 PROCESS_TERM_STOP ); 373 374 // unblock the parent process main thread 375 thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT ); 376 377 return; 378 } 348 // TXT owner cannot be the INIT process 349 assert( (owner_pid != 1) , "INIT process cannot be the TXT owner" ); 350 351 // get parent process descriptor pointers 352 parent_xp = hal_remote_l64( XPTR( owner_cxy , &owner_ptr->parent_xp ) ); 353 parent_cxy = GET_CXY( parent_xp ); 354 parent_ptr = GET_PTR( parent_xp ); 355 356 // get pointers on the parent process main thread 357 parent_main_ptr = hal_remote_lpt(XPTR(parent_cxy,&parent_ptr->th_tbl[0])); 358 parent_main_xp = XPTR( parent_cxy , parent_main_ptr ); 359 360 // transfer TXT ownership 361 process_txt_transfer_ownership( owner_xp ); 362 363 // mark for block all threads in all clusters, but the main 364 process_sigaction( owner_pid , BLOCK_ALL_THREADS ); 365 366 // block the main thread 367 xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] ); 368 thread_block( main_xp , THREAD_BLOCKED_GLOBAL ); 369 370 // atomically update owner process termination state 371 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 372 PROCESS_TERM_STOP ); 373 374 // unblock the parent process main thread 375 thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT ); 376 377 return; 379 378 } 380 379 … … 390 389 owner_xp = process_txt_get_owner( channel ); 391 390 392 // check process exist 393 assert( (owner_xp != XPTR_NULL) , 394 "TXT owner process not found\n" ); 391 // check process exist 392 assert( (owner_xp != XPTR_NULL) , "TXT owner process not found\n" ); 395 393 396 394 // get relevant infos on TXT owner process … … 399 397 owner_pid = hal_remote_l32( XPTR( owner_cxy , &owner_ptr->pid ) ); 400 398 401 // kill TXT owner process only if it is not the INIT process 402 if( owner_pid != 1 ) 403 { 404 // get parent process descriptor pointers 405 parent_xp = hal_remote_l64( XPTR( owner_cxy , &owner_ptr->parent_xp ) ); 406 parent_cxy = GET_CXY( parent_xp ); 407 parent_ptr = GET_PTR( parent_xp ); 408 409 // get pointers on the parent process main thread 410 parent_main_ptr = hal_remote_lpt(XPTR(parent_cxy,&parent_ptr->th_tbl[0])); 411 parent_main_xp = XPTR( parent_cxy , parent_main_ptr ); 412 413 // remove process from TXT list 414 process_txt_detach( owner_xp ); 415 416 // mark for delete all thread in all clusters, but the main 417 process_sigaction( owner_pid , DELETE_ALL_THREADS ); 399 // TXT owner cannot be the INIT process 400 assert( (owner_pid != 1) , "INIT process cannot be the TXT owner" ); 401 402 #if DEBUG_HAL_TXT_RX 403 if( DEBUG_HAL_TXT_RX < rx_cycle ) 404 printk("\n[%s] TXT%d owner is process %x\n", 405 __FUNCTION__, channel, owner_pid ); 406 #endif 407 // get parent process descriptor pointers 408 parent_xp = hal_remote_l64( XPTR( owner_cxy , &owner_ptr->parent_xp ) ); 409 parent_cxy = GET_CXY( parent_xp ); 410 parent_ptr = GET_PTR( parent_xp ); 411 412 // get pointers on the parent process main thread 413 parent_main_ptr = hal_remote_lpt(XPTR(parent_cxy,&parent_ptr->th_tbl[0])); 414 parent_main_xp = XPTR( parent_cxy , parent_main_ptr ); 415 416 // transfer TXT ownership 417 process_txt_transfer_ownership( owner_xp ); 418 419 // remove process from TXT list 420 // process_txt_detach( owner_xp ); 421 422 // mark for delete all thread in all clusters, but the main 423 process_sigaction( owner_pid , DELETE_ALL_THREADS ); 418 424 419 // block main thread 420 xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] ); 421 thread_block( main_xp , THREAD_BLOCKED_GLOBAL ); 422 423 // atomically update owner process termination state 424 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 425 PROCESS_TERM_KILL ); 426 427 // unblock the parent process main thread 428 thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT ); 429 430 return; 431 } 425 #if DEBUG_HAL_TXT_RX 426 if( DEBUG_HAL_TXT_RX < rx_cycle ) 427 printk("\n[%s] marked for delete all threads of process but main\n", 428 __FUNCTION__, owner_pid ); 429 #endif 430 // block main thread 431 xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] ); 432 thread_block( main_xp , THREAD_BLOCKED_GLOBAL ); 433 434 #if DEBUG_HAL_TXT_RX 435 if( DEBUG_HAL_TXT_RX < rx_cycle ) 436 printk("\n[%s] blocked process %x main thread\n", 437 __FUNCTION__, owner_pid ); 438 #endif 439 440 // atomically update owner process termination state 441 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 442 PROCESS_TERM_KILL ); 443 444 // unblock the parent process main thread 445 thread_unblock( parent_main_xp , THREAD_BLOCKED_WAIT ); 446 447 #if DEBUG_HAL_TXT_RX 448 if( DEBUG_HAL_TXT_RX < rx_cycle ) 449 printk("\n[%s] unblocked parent process %x main thread\n", 450 __FUNCTION__, hal_remote_l32( XPTR( parent_cxy , &parent_ptr->pid) ) ); 451 #endif 452 return; 432 453 } 433 454
Note: See TracChangeset
for help on using the changeset viewer.