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

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

First implementation of fork/exec.

File size: 11.6 KB
Line 
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>
25#include <hal_switch.h>
26#include <memcpy.h>
27#include <thread.h>
28#include <string.h>
29#include <process.h>
30#include <printk.h>
31#include <vmm.h>
32#include <core.h>
33#include <cluster.h>
34#include <hal_context.h>
35#include <hal_kentry.h>
36
37/////////////////////////////////////////////////////////////////////////////////////////
38//       Define various SR values for TSAR-MIPS32
39/////////////////////////////////////////////////////////////////////////////////////////
40
41#define SR_USR_MODE       0x0000FC13
42#define SR_USR_MODE_FPU   0x2000FC13
43#define SR_SYS_MODE       0x0000FC00
44
45/////////////////////////////////////////////////////////////////////////////////////////
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//
52// WARNING : check the two CONFIG_CPU_CTX_SIZE & CONFIG_FPU_CTX_SIZE configuration
53//           parameterss when modifying this structure.
54/////////////////////////////////////////////////////////////////////////////////////////
55
56typedef struct hal_cpu_context_s
57{
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
86    uint32_t t9_25;      // slot 25
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
91        uint32_t s8_30;      // slot 30
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
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
112
113/////////////////////////////////////////////////////////////////////////////////////////
114//        CPU context related functions
115/////////////////////////////////////////////////////////////////////////////////////////
116
117
118//////////////////////////////////////////////////
119error_t hal_cpu_context_alloc( thread_t * thread )
120{
121    assert( (sizeof(hal_cpu_context_t) <= CONFIG_CPU_CTX_SIZE) , __FUNCTION__ ,
122    "illegal CPU context size" );
123
124    // allocate memory for cpu_context
125    kmem_req_t  req;
126    req.type   = KMEM_CPU_CTX;
127    req.flags  = AF_KERNEL | AF_ZERO;
128
129    hal_cpu_context_t * context = (hal_cpu_context_t *)kmem_alloc( &req );
130    if( context == NULL ) return -1;
131
132    // link to thread
133    thread->cpu_context = (void *)context;
134    return 0;
135
136}   // end hal_cpu_context_alloc()
137
138///////////////////////////////////////////////////
139// The following context slots are initialised :
140// GPR : a0_04 / sp_29 / ra_31
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
154    if( thread->type == THREAD_USER )
155    {
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;
164    }
165    else  // kernel thread
166    {
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;
174    }
175
176context_dmsg("\n[DBG] %s : thread %x in process %x\n"
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,
186                 context->a0_04, context->sp_29, context->ra_31,
187                 context->c0_sr, context->c0_th, context->c0_epc,
188                 context->c2_ptpr, context->c2_mode );
189    return 0;
190
191}  // end hal_cpu_context_create()
192
193/////////////////////////////////////////////////
194void hal_cpu_context_display( thread_t * thread )
195{
196    hal_cpu_context_t * ctx = (hal_cpu_context_t *)thread->cpu_context;
197
198    printk("\n***** CPU context for thread %x in process %x / cycle %d\n" 
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",
202           thread->trdid, thread->process->pid, hal_time_stamp(),
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
207}  // end hal_cpu_context_display()
208
209/////////////////////////////////////////////////
210void hal_cpu_context_destroy( thread_t * thread )
211{
212    kmem_req_t  req;
213
214    req.type = KMEM_CPU_CTX;
215    req.ptr  = thread->cpu_context;
216    kmem_free( &req );
217
218}  // end hal_cpu_context_destroy()
219
220
221
222
223
224//////////////////////////////////////////////////
225error_t hal_fpu_context_alloc( thread_t * thread )
226{
227    assert( (sizeof(hal_fpu_context_t) <= CONFIG_FPU_CTX_SIZE) , __FUNCTION__ ,
228    "illegal CPU context size" );
229
230    // allocate memory for fpu_context
231    kmem_req_t  req;
232    req.type   = KMEM_FPU_CTX;
233    req.flags  = AF_KERNEL | AF_ZERO;
234
235    hal_fpu_context_t * context = (hal_fpu_context_t *)kmem_alloc( &req );
236    if( context == NULL ) return -1;
237
238    // link to thread
239    thread->fpu_context = (void *)context;
240    return 0;
241
242}   // end hal_fpu_context_alloc()
243
244//////////////////////////////////////////
245void hal_fpu_context_copy( thread_t * dst,
246                           thread_t * src )
247{
248    assert( (src != NULL) , __FUNCTION__ , "src thread pointer is NULL\n"); 
249    assert( (dst != NULL) , __FUNCTION__ , "dst thread pointer is NULL\n"); 
250
251    // get fpu context pointers
252    hal_fpu_context_t * src_context = src->fpu_context;
253    hal_fpu_context_t * dst_context = dst->fpu_context;
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
265    req.type = KMEM_FPU_CTX;
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.