Changeset 407 for trunk/hal/tsar_mips32/core/hal_context.c
- Timestamp:
- Nov 7, 2017, 3:08:12 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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
Note: See TracChangeset
for help on using the changeset viewer.