source: trunk/hal/tsar_mips32/core/hal_context.c @ 407

Last change on this file since 407 was 407, checked in by alain, 6 years ago

First implementation of fork/exec.

File size: 11.6 KB
RevLine 
[1]1/*
2 * hal_context.c - implementation of Thread Context API for TSAR-MIPS32
3 *
4 * Author  Alain Greiner    (2016)
5 *
6 * Copyright (c)  UPMC Sorbonne Universites
7 *
8 * This file is part of ALMOS-MKH.
9 *
10 * ALMOS-MKH.is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
14 * ALMOS-MKH.is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ALMOS-MKH.; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#include <hal_types.h>
[317]25#include <hal_switch.h>
[1]26#include <memcpy.h>
27#include <thread.h>
28#include <string.h>
29#include <process.h>
[8]30#include <printk.h>
[1]31#include <vmm.h>
32#include <core.h>
33#include <cluster.h>
34#include <hal_context.h>
[406]35#include <hal_kentry.h>
[1]36
[151]37/////////////////////////////////////////////////////////////////////////////////////////
38//       Define various SR values for TSAR-MIPS32
39/////////////////////////////////////////////////////////////////////////////////////////
40
[406]41#define SR_USR_MODE       0x0000FC13
42#define SR_USR_MODE_FPU   0x2000FC13
43#define SR_SYS_MODE       0x0000FC00
[151]44
45/////////////////////////////////////////////////////////////////////////////////////////
[407]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//
[406]52// WARNING : check the two CONFIG_CPU_CTX_SIZE & CONFIG_FPU_CTX_SIZE configuration
53//           parameterss when modifying this structure.
[151]54/////////////////////////////////////////////////////////////////////////////////////////
55
56typedef struct hal_cpu_context_s
57{
[296]58    uint32_t c0_epc;     // slot 0
59    uint32_t at_01;      // slot 1
60    uint32_t v0_02;      // slot 2
61    uint32_t v1_03;      // slot 3
62    uint32_t a0_04;      // slot 4
63    uint32_t a1_05;      // slot 5
64    uint32_t a2_06;      // slot 6
65    uint32_t a3_07;      // slot 7
66
67    uint32_t t0_08;      // slot 8
68    uint32_t t1_09;      // slot 9
69    uint32_t t2_10;      // slot 10
70    uint32_t t3_11;      // slot 11
71    uint32_t t4_12;      // slot 12
72    uint32_t t5_13;      // slot 13
73    uint32_t t6_14;      // slot 14
74    uint32_t t7_15;      // slot 15
75
76        uint32_t s0_16;      // slot 16
77        uint32_t s1_17;      // slot 17
78        uint32_t s2_18;      // slot 18
79        uint32_t s3_19;      // slot 19
80        uint32_t s4_20;      // slot 20
81        uint32_t s5_21;      // slot 21
82        uint32_t s6_22;      // slot 22
83        uint32_t s7_23;      // slot 23
84
85    uint32_t t8_24;      // slot 24
[406]86    uint32_t t9_25;      // slot 25
[296]87    uint32_t hi_26;      // slot 26
88    uint32_t lo_27;      // slot 27
89    uint32_t gp_28;      // slot 28
90        uint32_t sp_29;      // slot 29
[407]91        uint32_t s8_30;      // slot 30
[296]92        uint32_t ra_31;      // slot 31
93
94        uint32_t c2_ptpr;    // slot 32
95        uint32_t c2_mode;    // slot 33
96
97        uint32_t c0_sr;      // slot 34
98        uint32_t c0_th;      // slot 35
[151]99} 
100hal_cpu_context_t;
101
102/////////////////////////////////////////////////////////////////////////////////////////
103// This structure defines the fpu_context for TSAR MIPS32.
104/////////////////////////////////////////////////////////////////////////////////////////
105
106typedef struct hal_fpu_context_s
107{
108        uint32_t   fpu_regs[32];     
109}
110hal_fpu_context_t;
111
[296]112
113/////////////////////////////////////////////////////////////////////////////////////////
[407]114//        CPU context related functions
[296]115/////////////////////////////////////////////////////////////////////////////////////////
116
[407]117
118//////////////////////////////////////////////////
119error_t hal_cpu_context_alloc( thread_t * thread )
[1]120{
[406]121    assert( (sizeof(hal_cpu_context_t) <= CONFIG_CPU_CTX_SIZE) , __FUNCTION__ ,
[407]122    "illegal CPU context size" );
[406]123
[1]124    // allocate memory for cpu_context
[407]125    kmem_req_t  req;
[8]126    req.type   = KMEM_CPU_CTX;
[1]127    req.flags  = AF_KERNEL | AF_ZERO;
128
129    hal_cpu_context_t * context = (hal_cpu_context_t *)kmem_alloc( &req );
[407]130    if( context == NULL ) return -1;
[1]131
[407]132    // link to thread
133    thread->cpu_context = (void *)context;
134    return 0;
[1]135
[407]136}   // end hal_cpu_context_alloc()
137
138///////////////////////////////////////////////////
139// The following context slots are initialised :
140// GPR : a0_04 / sp_29 / ra_31
141// CP0 : c0_sr / c0_th / c0_epc
142// CP2 : c2_ptpr / c2_mode
143///////////////////////////////////////////////////
144error_t hal_cpu_context_create( thread_t * thread )
145{
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
[1]154    if( thread->type == THREAD_USER )
155    {
[407]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;
[1]164    }
[407]165    else  // kernel thread
[1]166    {
[407]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;
[1]174    }
175
[407]176context_dmsg("\n[DBG] %s : thread %x in process %x\n"
[406]177                 " - a0   = %x\n"
178                 " - sp   = %x\n"
179                 " - ra   = %x\n"
180                 " - sr   = %x\n"
181                 " - th   = %x\n"   
182                 " - epc  = %x\n"   
183                 " - ptpr = %x\n"   
184                 " - mode = %x\n", 
185                 __FUNCTION__ , thread->trdid , thread->process->pid,
[407]186                 context->a0_04, context->sp_29, context->ra_31,
[406]187                 context->c0_sr, context->c0_th, context->c0_epc,
188                 context->c2_ptpr, context->c2_mode );
189    return 0;
[8]190
[1]191}  // end hal_cpu_context_create()
192
[296]193/////////////////////////////////////////////////
194void hal_cpu_context_display( thread_t * thread )
195{
196    hal_cpu_context_t * ctx = (hal_cpu_context_t *)thread->cpu_context;
197
[406]198    printk("\n***** CPU context for thread %x in process %x / cycle %d\n" 
[296]199           " gp_28   = %X    sp_29   = %X    ra_31   = %X\n" 
200           " c0_sr   = %X    c0_epc  = %X    c0_th = %X\n"
201           " c2_ptpr = %X    c2_mode = %X\n",
[406]202           thread->trdid, thread->process->pid, hal_time_stamp(),
[296]203           ctx->gp_28   , ctx->sp_29   , ctx->ra_31,
204           ctx->c0_sr   , ctx->c0_epc  , ctx->c0_th,
205           ctx->c2_ptpr , ctx->c2_mode );
206
[407]207}  // end hal_cpu_context_display()
[317]208
[1]209/////////////////////////////////////////////////
210void hal_cpu_context_destroy( thread_t * thread )
211{
212    kmem_req_t  req;
213
[8]214    req.type = KMEM_CPU_CTX;
[1]215    req.ptr  = thread->cpu_context;
216    kmem_free( &req );
217
218}  // end hal_cpu_context_destroy()
219
[317]220
[407]221
222
223
224//////////////////////////////////////////////////
225error_t hal_fpu_context_alloc( thread_t * thread )
[1]226{
[406]227    assert( (sizeof(hal_fpu_context_t) <= CONFIG_FPU_CTX_SIZE) , __FUNCTION__ ,
[407]228    "illegal CPU context size" );
[406]229
[407]230    // allocate memory for fpu_context
231    kmem_req_t  req;
[8]232    req.type   = KMEM_FPU_CTX;
[1]233    req.flags  = AF_KERNEL | AF_ZERO;
234
235    hal_fpu_context_t * context = (hal_fpu_context_t *)kmem_alloc( &req );
[407]236    if( context == NULL ) return -1;
[1]237
[407]238    // link to thread
239    thread->fpu_context = (void *)context;
[1]240    return 0;
241
[407]242}   // end hal_fpu_context_alloc()
243
244//////////////////////////////////////////
245void hal_fpu_context_copy( thread_t * dst,
246                           thread_t * src )
[1]247{
[407]248    assert( (src != NULL) , __FUNCTION__ , "src thread pointer is NULL\n"); 
249    assert( (dst != NULL) , __FUNCTION__ , "dst thread pointer is NULL\n"); 
[1]250
[407]251    // get fpu context pointers
[1]252    hal_fpu_context_t * src_context = src->fpu_context;
[407]253    hal_fpu_context_t * dst_context = dst->fpu_context;
[1]254
255    // copy CPU context from src to dst
256    memcpy( dst_context , src_context , sizeof(hal_fpu_context_t) );
257
258}  // end hal_fpu_context_copy()
259
260/////////////////////////////////////////////////
261void hal_fpu_context_destroy( thread_t * thread )
262{
263    kmem_req_t  req;
264
[8]265    req.type = KMEM_FPU_CTX;
[1]266    req.ptr  = thread->fpu_context;
267    kmem_free( &req );
268
269}  // end hal_fpu_context_destroy()
270
271//////////////////////////////////////////////
272void hal_fpu_context_save( thread_t * thread )
273{
274    uint32_t ctx = (uint32_t)thread->fpu_context;
275
276    asm volatile(
277    ".set noreorder           \n"
278    "swc1    $f0,    0*4(%0)  \n"   
279    "swc1    $f1,    1*4(%0)  \n"   
280    "swc1    $f2,    2*4(%0)  \n"   
281    "swc1    $f3,    3*4(%0)  \n"   
282    "swc1    $f4,    4*4(%0)  \n"   
283    "swc1    $f5,    5*4(%0)  \n"   
284    "swc1    $f6,    6*4(%0)  \n"   
285    "swc1    $f7,    7*4(%0)  \n"   
286    "swc1    $f8,    8*4(%0)  \n"   
287    "swc1    $f9,    9*4(%0)  \n"   
288    "swc1    $f10,  10*4(%0)  \n"   
289    "swc1    $f11,  11*4(%0)  \n"   
290    "swc1    $f12,  12*4(%0)  \n"   
291    "swc1    $f13,  13*4(%0)  \n"   
292    "swc1    $f14,  14*4(%0)  \n"   
293    "swc1    $f15,  15*4(%0)  \n"   
294    "swc1    $f16,  16*4(%0)  \n"   
295    "swc1    $f17,  17*4(%0)  \n"   
296    "swc1    $f18,  18*4(%0)  \n"   
297    "swc1    $f19,  19*4(%0)  \n"   
298    "swc1    $f20,  20*4(%0)  \n"   
299    "swc1    $f21,  21*4(%0)  \n"   
300    "swc1    $f22,  22*4(%0)  \n"   
301    "swc1    $f23,  23*4(%0)  \n"   
302    "swc1    $f24,  24*4(%0)  \n"   
303    "swc1    $f25,  25*4(%0)  \n"   
304    "swc1    $f26,  26*4(%0)  \n"   
305    "swc1    $f27,  27*4(%0)  \n"   
306    "swc1    $f28,  28*4(%0)  \n"   
307    "swc1    $f29,  29*4(%0)  \n"   
308    "swc1    $f30,  30*4(%0)  \n"   
309    "swc1    $f31,  31*4(%0)  \n"   
310    ".set reorder             \n"
311    : : "r"(ctx) );
312
313}  // end hal_cpu_context_save()
314
315/////////////////////////////////////////////////
316void hal_fpu_context_restore( thread_t * thread )
317{
318    uint32_t ctx = (uint32_t)thread->fpu_context;
319
320    asm volatile(
321    ".set noreorder           \n"
322    "lwc1    $f0,    0*4(%0)  \n"   
323    "lwc1    $f1,    1*4(%0)  \n"   
324    "lwc1    $f2,    2*4(%0)  \n"   
325    "lwc1    $f3,    3*4(%0)  \n"   
326    "lwc1    $f4,    4*4(%0)  \n"   
327    "lwc1    $f5,    5*4(%0)  \n"   
328    "lwc1    $f6,    6*4(%0)  \n"   
329    "lwc1    $f7,    7*4(%0)  \n"   
330    "lwc1    $f8,    8*4(%0)  \n"   
331    "lwc1    $f9,    9*4(%0)  \n"   
332    "lwc1    $f10,  10*4(%0)  \n"   
333    "lwc1    $f11,  11*4(%0)  \n"   
334    "lwc1    $f12,  12*4(%0)  \n"   
335    "lwc1    $f13,  13*4(%0)  \n"   
336    "lwc1    $f14,  14*4(%0)  \n"   
337    "lwc1    $f15,  15*4(%0)  \n"   
338    "lwc1    $f16,  16*4(%0)  \n"   
339    "lwc1    $f17,  17*4(%0)  \n"   
340    "lwc1    $f18,  18*4(%0)  \n"   
341    "lwc1    $f19,  19*4(%0)  \n"   
342    "lwc1    $f20,  20*4(%0)  \n"   
343    "lwc1    $f21,  21*4(%0)  \n"   
344    "lwc1    $f22,  22*4(%0)  \n"   
345    "lwc1    $f23,  23*4(%0)  \n"   
346    "lwc1    $f24,  24*4(%0)  \n"   
347    "lwc1    $f25,  25*4(%0)  \n"   
348    "lwc1    $f26,  26*4(%0)  \n"   
349    "lwc1    $f27,  27*4(%0)  \n"   
350    "lwc1    $f28,  28*4(%0)  \n"   
351    "lwc1    $f29,  29*4(%0)  \n"   
352    "lwc1    $f30,  30*4(%0)  \n"   
353    "lwc1    $f31,  31*4(%0)  \n"   
354    ".set reorder             \n"
355    : : "r"(ctx) );
356
357} // end hal_cpu_context_restore()
358
359
Note: See TracBrowser for help on using the repository browser.