source: soft/giet_vm/giet_kernel/sys_handler.c @ 269

Last change on this file since 269 was 267, checked in by cfuguet, 11 years ago
  • Adding new task context information: THREAD INDEX.

This value can be accessed by USER applications to get the
thread index of the current task. This thread index
corresponds to the index in a vspace.

The value of this index can be forced in the vspace part
of the XML description file using the trdid field in the
task description. When this value is missing, for each
task, a value from 0 to N-1 will be assigned, where N is
the number of task in the vspace.

The user application access this value through the
giet_thread_id() function defined in the stdio library
which uses the SYSCALL_THREAD_ID to access the task
context information.

  • Supporting mono TTY platforms

When the GIET_MONO_TTY constant defined in the giet_config
file, contains a value different than 0, all tasks will
share the TTY[0]. If this is the case, in the stdio
library, the giet_tty_printf() function will take the TTY
hardware lock before writing

  • Property svn:executable set to *
File size: 10.9 KB
RevLine 
[258]1///////////////////////////////////////////////////////////////////////////////////
2// File     : sys_handler.c
3// Date     : 01/04/2012
4// Author   : alain greiner and joel porquet
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7// The sys_handler.c and sys_handler.h files are part of the GIET-VM nano-kernel.
8// It define the syscall_vector[] (at the end of this file), as well as the
9// associated syscall handlers that are not related to peripherals.
10// The syscall handlers for peripherals are defined in the drivers.c file.
11///////////////////////////////////////////////////////////////////////////////////
12
13#include <sys_handler.h>
14#include <tty_driver.h>
15#include <tim_driver.h>
16#include <ioc_driver.h>
17#include <nic_driver.h>
18#include <fbf_driver.h>
19#include <ctx_handler.h>
20#include <fat32.h>
21#include <utils.h>
22#include <giet_config.h>
23#include <mapping_info.h>
24
25////////////////////////////////////////////////////////////////////////////
26//    Initialize the syscall vector with syscall handlers
27// Note: This array must be synchronised with the define in file stdio.h
28////////////////////////////////////////////////////////////////////////////
29const void * _syscall_vector[64] = 
30{
31    &_get_procid,          /* 0x00 */
32    &_get_proctime,        /* 0x01 */
33    &_tty_write,           /* 0x02 */
34    &_tty_read,            /* 0x03 */
35    &_timer_start,         /* 0x04 */
36    &_timer_stop,          /* 0x05 */
37    &_sys_ukn,             /* 0x06 */
38    &_sys_ukn,             /* 0x07 */
39    &_heap_info,           /* 0x08 */
40    &_local_task_id,       /* 0x09 */
41    &_global_task_id,      /* 0x0A */ 
42    &_fb_cma_init,         /* 0x0B */
43    &_fb_cma_write,        /* 0x0C */
44    &_fb_cma_stop,         /* 0x0D */
45    &_task_exit,           /* 0x0E */
46    &_procs_number,        /* 0x0F */
47
48    &_fb_sync_write,       /* 0x10 */
49    &_fb_sync_read,        /* 0x11 */
[267]50    &_thread_id,           /* 0x12 */
51    &_tty_get_release_lock,/* 0x13 */
[258]52    &_sys_ukn,             /* 0x14 */
53    &_sys_ukn,             /* 0x15 */ 
54    &_sys_ukn,             /* 0x16 */
55    &_sys_ukn,             /* 0x17 */
56    &_sys_ukn,             /* 0x18 */   
57    &_ctx_switch,          /* 0x19 */
58    &_vobj_get_vbase,      /* 0x1A */
59    &_sys_ukn,             /* 0x1B */
60    &_nic_cma_start,       /* 0x1C */
61    &_nic_cma_stop,        /* 0x1D */
62    &_nic_sync_read,       /* 0x1E */
63    &_nic_sync_write,      /* 0x1F */
64
65    &_fat_user_open,       /* 0x20 */
66    &_fat_user_read,       /* 0x21 */
67    &_fat_user_write,      /* 0x22 */
68    &_fat_user_lseek,      /* 0x23 */
[260]69    &_fat_fstat,           /* 0x24 */
70    &_fat_close,           /* 0x25 */
[258]71    &_sys_ukn,             /* 0x26 */
72    &_sys_ukn,             /* 0x27 */
73    &_sys_ukn,             /* 0x28 */
74    &_sys_ukn,             /* 0x29 */
75    &_sys_ukn,             /* 0x2A */
76    &_sys_ukn,             /* 0x2B */
77    &_sys_ukn,             /* 0x2C */
78    &_sys_ukn,             /* 0x2D */
79    &_sys_ukn,             /* 0x2E */
80    &_sys_ukn,             /* 0x2F */
81
82    &_sys_ukn,             /* 0x30 */
83    &_sys_ukn,             /* 0x31 */
84    &_sys_ukn,             /* 0x32 */
85    &_sys_ukn,             /* 0x33 */
86    &_sys_ukn,             /* 0x34 */
87    &_sys_ukn,             /* 0x35 */ 
88    &_sys_ukn,             /* 0x36 */
89    &_sys_ukn,             /* 0x37 */
90    &_sys_ukn,             /* 0x38 */   
91    &_sys_ukn,             /* 0x39 */
92    &_sys_ukn,             /* 0x3A */
93    &_sys_ukn,             /* 0x3B */
94    &_sys_ukn,             /* 0x3C */
95    &_sys_ukn,             /* 0x3D */
96    &_sys_ukn,             /* 0x3E */
97    &_sys_ukn,             /* 0x3F */
98};
99
100//////////////////////////////////////////////////////////////////////////////
101// function executed in case of undefined syscall
102//////////////////////////////////////////////////////////////////////////////
103void _sys_ukn() 
104{
105    unsigned int epc;
106    asm volatile("mfc0 %0, $14" : "=r" (epc));
107
108    _tty_get_lock( 0 );
109    _puts("\n\n!!! Undefined System Call !!!\n");
110    _puts("\nEPC = ");
111    _putx(epc);
112    _tty_release_lock( 0 );
113    _exit();
114}
115
116////////////////////////////////////////////////////////////////////////////
117// _exit()
118// Task suicide... after printing a death message.
119////////////////////////////////////////////////////////////////////////////
120void _task_exit() 
121{
122    unsigned int date    = _get_proctime();
123    unsigned int proc_id = _get_procid();
124    unsigned int task_id = _get_context_slot(CTX_LTID_ID);
125
126    // print death message
127    _tty_get_lock( 0 );
128    _puts("\n[GIET] Exit task ");
129    _putd(task_id);
130    _puts(" on processor ");
131    _putd(proc_id);
132    _puts(" at cycle ");
133    _putd(date);
134    _puts("\n\n");
135    _tty_release_lock( 0 );
136
137    // goes to sleeping state
138    _set_context_slot(CTX_RUN_ID, 0);
139
140    // deschedule
141    _context_switch();
142} 
143
144//////////////////////////////////////////////////////////////////////////////
145// _procnumber()
146// returns in buffer argument the number of processors in the cluster
147// specified by the cluster_id argument.
148//////////////////////////////////////////////////////////////////////////////
149unsigned int _procs_number(unsigned int  cluster_id, 
150                           unsigned int* buffer) 
151{
152    mapping_header_t * header  = (mapping_header_t *) &seg_boot_mapping_base;
153    mapping_cluster_t * cluster = _get_cluster_base(header);
154
[263]155    if ( cluster_id < X_SIZE * Y_SIZE ) 
156    {
[258]157        *buffer = cluster[cluster_id].procs;
158        return 0;
159    }
[263]160    else 
161    {
[258]162        return 1;
163    }
164}
165
166/////////////////////////////////////////////////////////////////////////////
167// _local_task_id()
168// Returns current task local index.
169/////////////////////////////////////////////////////////////////////////////
170unsigned int _local_task_id()
171{
172    return _get_context_slot(CTX_LTID_ID);
173}
174
175/////////////////////////////////////////////////////////////////////////////
176// _global_task_id()
177// Returns current task global index.
178/////////////////////////////////////////////////////////////////////////////
179unsigned int _global_task_id()
180{
181    return _get_context_slot(CTX_GTID_ID);
182}
183
184/////////////////////////////////////////////////////////////////////////////
[267]185// _thread_id()
186// Returns current thread index.
187/////////////////////////////////////////////////////////////////////////////
188unsigned int _thread_id()
189{
190    return _get_context_slot(CTX_TRDID_ID);
191}
192
193/////////////////////////////////////////////////////////////////////////////
194// _tty_get_release_lock(int val)
195// Get or release the hardware TTY lock depending on val (0: get,1: release)
196/////////////////////////////////////////////////////////////////////////////
197int _tty_get_release_lock(unsigned int val)
198{
199    unsigned int channel = _get_context_slot(CTX_TTY_ID);
200
201    if      ( val == 0 ) _tty_get_lock(channel);
202    else if ( val == 1 ) _tty_release_lock(channel);
203    else return -1; // Wrong action
204
205    return 0;
206}
207
208/////////////////////////////////////////////////////////////////////////////
[258]209// _get_vobj()
210// This function writes in res_vobj a pointer on a vobj
211// identified by the (vspace_name / vobj_name ) couple.
212// The vobj_type argument is here only for the purpose of checking .
213// returns 0: success, else: failed.
214/////////////////////////////////////////////////////////////////////////////
215int _get_vobj( char*             vspace_name, 
216               char*             vobj_name, 
217               unsigned int      vobj_type, 
218               mapping_vobj_t**  res_vobj ) 
219{
220    mapping_header_t * header = (mapping_header_t *) &seg_boot_mapping_base;
221    mapping_vspace_t * vspace = _get_vspace_base(header);
222    mapping_vobj_t * vobj     = _get_vobj_base(header);
223
224    unsigned int vspace_id;
225    unsigned int vobj_id;
226
227    // scan vspaces
228    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
229    {
230        if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) 
231        {
232            // scan vobjs
233            for (vobj_id = vspace[vspace_id].vobj_offset; 
234                 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 
235                 vobj_id++) 
236            {
237                if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) 
238                {
239                    if (vobj[vobj_id].type != vobj_type) 
240                    {
241                        _tty_get_lock( 0 );
242                        _puts("*** Error in _get_obj: wrong type\n");
243                        _tty_release_lock( 0 );
244                        return -1; // wrong type
245                    }
246                    *res_vobj = &vobj[vobj_id];
247                    return 0;
248                }
249            } 
250        }
251    } 
252    _tty_get_lock( 0 );
253    _puts("*** Error in _get_obj: object not found\n");
254    _tty_release_lock( 0 );
255
256    return -2; //not found
257}
258
259/////////////////////////////////////////////////////////////////////////////
260// _vobj_get_vbase()
261// This function writes in vobj_vaddr the virtual base address of a vobj
262// identified by the (vspace_name / vobj_name ) couple.
263// The vobj_type argument is here only for the purpose of checking .
264// returns 0: success, else: failed.
265/////////////////////////////////////////////////////////////////////////////
266unsigned int _vobj_get_vbase( char*         vspace_name,
267                              char*         vobj_name,
268                              unsigned int  vobj_type,
269                              unsigned int* vobj_vaddr ) 
270{
271    mapping_vobj_t* res_vobj;
272    unsigned int    ret;
273    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) 
274    {
275        return ret;
276    }
277    *vobj_vaddr = res_vobj->vaddr;
278    return 0;
279}
280
281/////////////////////////////////////////////////////////////////////////////
282// _vobj_get_length()
283// This function writes in vobj_length the virtual base address of a vobj
284// identified by the (vspace_name / vobj_name ) couple.
285// The vobj_type argument is here only for the purpose of checking .
286// returns 0: success, else: failed.
287/////////////////////////////////////////////////////////////////////////////
288unsigned int _vobj_get_length( char*         vspace_name, 
289                               char*         vobj_name,
290                               unsigned int  vobj_type, 
291                               unsigned int* vobj_length ) 
292{
293    mapping_vobj_t * res_vobj;
294    unsigned int ret;
295    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) 
296    {
297        return ret;
298    }
299    *vobj_length = res_vobj->length;
300    return 0;
301}
302
303
304////////////////////////////////////////////////////////////////
305// _context_switch()
306// This functions masks interruptions before calling _ctx_switch
307// (They are usually masked when we receive a isr_switch interrupt
308// because we execute ISRs with interrupt masked)
309////////////////////////////////////////////////////////////////
310void _context_switch() 
311{
312    _it_disable();
313    _ctx_switch();
314}
315
316
317// Local Variables:
318// tab-width: 4
319// c-basic-offset: 4
320// c-file-offsets:((innamespace . 0)(inline-open . 0))
321// indent-tabs-mode: nil
322// End:
323// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
324
Note: See TracBrowser for help on using the repository browser.