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

Last change on this file since 261 was 260, checked in by devigne, 11 years ago

Add a new syscall : giet_fat_fstat, allowing to a user application to know the
size (in sectors) of an open file.

  • Property svn:executable set to *
File size: 10.1 KB
Line 
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 */
50    &_sys_ukn,             /* 0x12 */
51    &_sys_ukn,             /* 0x13 */
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 */
69    &_fat_fstat,           /* 0x24 */
70    &_fat_close,           /* 0x25 */
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
155    if (cluster_id < header->clusters) {
156        *buffer = cluster[cluster_id].procs;
157        return 0;
158    }
159    else {
160        return 1;
161    }
162}
163
164/////////////////////////////////////////////////////////////////////////////
165// _local_task_id()
166// Returns current task local index.
167/////////////////////////////////////////////////////////////////////////////
168unsigned int _local_task_id()
169{
170    return _get_context_slot(CTX_LTID_ID);
171}
172
173/////////////////////////////////////////////////////////////////////////////
174// _global_task_id()
175// Returns current task global index.
176/////////////////////////////////////////////////////////////////////////////
177unsigned int _global_task_id()
178{
179    return _get_context_slot(CTX_GTID_ID);
180}
181
182/////////////////////////////////////////////////////////////////////////////
183// _get_vobj()
184// This function writes in res_vobj a pointer on a vobj
185// identified by the (vspace_name / vobj_name ) couple.
186// The vobj_type argument is here only for the purpose of checking .
187// returns 0: success, else: failed.
188/////////////////////////////////////////////////////////////////////////////
189int _get_vobj( char*             vspace_name, 
190               char*             vobj_name, 
191               unsigned int      vobj_type, 
192               mapping_vobj_t**  res_vobj ) 
193{
194    mapping_header_t * header = (mapping_header_t *) &seg_boot_mapping_base;
195    mapping_vspace_t * vspace = _get_vspace_base(header);
196    mapping_vobj_t * vobj     = _get_vobj_base(header);
197
198    unsigned int vspace_id;
199    unsigned int vobj_id;
200
201    // scan vspaces
202    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
203    {
204        if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) 
205        {
206            // scan vobjs
207            for (vobj_id = vspace[vspace_id].vobj_offset; 
208                 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 
209                 vobj_id++) 
210            {
211                if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) 
212                {
213                    if (vobj[vobj_id].type != vobj_type) 
214                    {
215                        _tty_get_lock( 0 );
216                        _puts("*** Error in _get_obj: wrong type\n");
217                        _tty_release_lock( 0 );
218                        return -1; // wrong type
219                    }
220                    *res_vobj = &vobj[vobj_id];
221                    return 0;
222                }
223            } 
224        }
225    } 
226    _tty_get_lock( 0 );
227    _puts("*** Error in _get_obj: object not found\n");
228    _tty_release_lock( 0 );
229
230    return -2; //not found
231}
232
233/////////////////////////////////////////////////////////////////////////////
234// _vobj_get_vbase()
235// This function writes in vobj_vaddr the virtual base address of a vobj
236// identified by the (vspace_name / vobj_name ) couple.
237// The vobj_type argument is here only for the purpose of checking .
238// returns 0: success, else: failed.
239/////////////////////////////////////////////////////////////////////////////
240unsigned int _vobj_get_vbase( char*         vspace_name,
241                              char*         vobj_name,
242                              unsigned int  vobj_type,
243                              unsigned int* vobj_vaddr ) 
244{
245    mapping_vobj_t* res_vobj;
246    unsigned int    ret;
247    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) 
248    {
249        return ret;
250    }
251    *vobj_vaddr = res_vobj->vaddr;
252    return 0;
253}
254
255/////////////////////////////////////////////////////////////////////////////
256// _vobj_get_length()
257// This function writes in vobj_length the virtual base address of a vobj
258// identified by the (vspace_name / vobj_name ) couple.
259// The vobj_type argument is here only for the purpose of checking .
260// returns 0: success, else: failed.
261/////////////////////////////////////////////////////////////////////////////
262unsigned int _vobj_get_length( char*         vspace_name, 
263                               char*         vobj_name,
264                               unsigned int  vobj_type, 
265                               unsigned int* vobj_length ) 
266{
267    mapping_vobj_t * res_vobj;
268    unsigned int ret;
269    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) 
270    {
271        return ret;
272    }
273    *vobj_length = res_vobj->length;
274    return 0;
275}
276
277
278////////////////////////////////////////////////////////////////
279// _context_switch()
280// This functions masks interruptions before calling _ctx_switch
281// (They are usually masked when we receive a isr_switch interrupt
282// because we execute ISRs with interrupt masked)
283////////////////////////////////////////////////////////////////
284void _context_switch() 
285{
286    _it_disable();
287    _ctx_switch();
288}
289
290
291// Local Variables:
292// tab-width: 4
293// c-basic-offset: 4
294// c-file-offsets:((innamespace . 0)(inline-open . 0))
295// indent-tabs-mode: nil
296// End:
297// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
298
Note: See TracBrowser for help on using the repository browser.