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

Last change on this file since 397 was 396, checked in by alain, 10 years ago

Housekeeping

  • Property svn:executable set to *
File size: 10.8 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 <vmem.h>
23#include <hard_config.h>
24#include <giet_config.h>
25#include <mapping_info.h>
26
27#if !defined(SEG_BOOT_MAPPING_BASE)
28# error: You must define SEG_BOOT_MAPPING_BASE in the hard_config.h file
29#endif
30
31////////////////////////////////////////////////////////////////////////////
32//    Initialize the syscall vector with syscall handlers
33// Note: This array must be synchronised with the define in file stdio.h
34////////////////////////////////////////////////////////////////////////////
35const void * _syscall_vector[64] = 
36{
37    &_get_procid,          /* 0x00 */
38    &_get_proctime,        /* 0x01 */
39    &_tty_write,           /* 0x02 */
40    &_tty_read,            /* 0x03 */
41    &_timer_start,         /* 0x04 */
42    &_timer_stop,          /* 0x05 */
43    &_tty_get_lock,        /* 0x06 */
44    &_tty_release_lock,    /* 0x07 */
45    &_heap_info,           /* 0x08 */
46    &_local_task_id,       /* 0x09 */
47    &_global_task_id,      /* 0x0A */ 
48    &_fb_cma_init,         /* 0x0B */
49    &_fb_cma_write,        /* 0x0C */
50    &_fb_cma_stop,         /* 0x0D */
51    &_task_exit,           /* 0x0E */
52    &_procs_number,        /* 0x0F */
53
54    &_fb_sync_write,       /* 0x10 */
55    &_fb_sync_read,        /* 0x11 */
56    &_thread_id,           /* 0x12 */
57    &_sys_ukn,             /* 0x13 */
58    &_sys_ukn,             /* 0x14 */
59    &_sys_ukn,             /* 0x15 */ 
60    &_sys_ukn,             /* 0x16 */
61    &_sys_ukn,             /* 0x17 */
62    &_sys_ukn,             /* 0x18 */   
63    &_context_switch,      /* 0x19 */
64    &_vobj_get_vbase,      /* 0x1A */
65    &_get_xy_from_ptr,     /* 0x1B */
66    &_nic_cma_start,       /* 0x1C */
67    &_nic_cma_stop,        /* 0x1D */
68    &_nic_sync_read,       /* 0x1E */
69    &_nic_sync_write,      /* 0x1F */
70
71    &_fat_user_open,       /* 0x20 */
72    &_fat_user_read,       /* 0x21 */
73    &_fat_user_write,      /* 0x22 */
74    &_fat_user_lseek,      /* 0x23 */
75    &_fat_fstat,           /* 0x24 */
76    &_fat_close,           /* 0x25 */
77    &_sys_ukn,             /* 0x26 */
78    &_sys_ukn,             /* 0x27 */
79    &_sys_ukn,             /* 0x28 */
80    &_sys_ukn,             /* 0x29 */
81    &_sys_ukn,             /* 0x2A */
82    &_sys_ukn,             /* 0x2B */
83    &_sys_ukn,             /* 0x2C */
84    &_sys_ukn,             /* 0x2D */
85    &_sys_ukn,             /* 0x2E */
86    &_sys_ukn,             /* 0x2F */
87
88    &_sys_ukn,             /* 0x30 */
89    &_sys_ukn,             /* 0x31 */
90    &_sys_ukn,             /* 0x32 */
91    &_sys_ukn,             /* 0x33 */
92    &_sys_ukn,             /* 0x34 */
93    &_sys_ukn,             /* 0x35 */ 
94    &_sys_ukn,             /* 0x36 */
95    &_sys_ukn,             /* 0x37 */
96    &_sys_ukn,             /* 0x38 */   
97    &_sys_ukn,             /* 0x39 */
98    &_sys_ukn,             /* 0x3A */
99    &_sys_ukn,             /* 0x3B */
100    &_sys_ukn,             /* 0x3C */
101    &_sys_ukn,             /* 0x3D */
102    &_sys_ukn,             /* 0x3E */
103    &_sys_ukn,             /* 0x3F */
104};
105
106//////////////////////////////////////////////////////////////////////////////
107// function executed in case of undefined syscall
108//////////////////////////////////////////////////////////////////////////////
109void _sys_ukn() 
110{
111    _printf("\n\n[GIET ERROR] Undefined System Call / EPC = %x\n", _get_epc() );
112    _exit();
113}
114
115////////////////////////////////////////////////////////////////////////////
116// Task suicide... after printing a death message.
117////////////////////////////////////////////////////////////////////////////
118void _task_exit( char* string ) 
119{
120    unsigned int date       = _get_proctime();
121    unsigned int proc_id    = _get_procid();
122    unsigned int cluster_xy = proc_id / NB_PROCS_MAX;
123    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
124    unsigned int x          = cluster_xy >> Y_WIDTH;
125    unsigned int lpid       = proc_id % NB_PROCS_MAX;
126    unsigned int task_id    = _get_context_slot(CTX_LTID_ID);
127
128    // print death message
129    _printf("\n[GIET] Exit task %d on processor[%d,%d,%d] at cycle %d"
130            "\n       Cause : %s\n\n",
131            task_id, x, y, lpid, date, string );
132
133    // goes to sleeping state
134    _set_context_slot(CTX_RUN_ID, 0);
135
136    // deschedule
137    _context_switch();
138} 
139
140//////////////////////////////////////////////////////////////////////////////
141// returns in buffer argument the number of processors in the cluster
142// specified by the cluster_id argument.
143//////////////////////////////////////////////////////////////////////////////
144unsigned int _procs_number(unsigned int  cluster_id, 
145                           unsigned int* buffer) 
146{
147    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
148    mapping_cluster_t * cluster = _get_cluster_base(header);
149
150    if ( cluster_id < X_SIZE * Y_SIZE ) 
151    {
152        *buffer = cluster[cluster_id].procs;
153        return 0;
154    }
155    else 
156    {
157        return 1;
158    }
159}
160
161/////////////////////////////////////////////////////////////////////////////
162// Returns current task local index.
163/////////////////////////////////////////////////////////////////////////////
164unsigned int _local_task_id()
165{
166    return _get_context_slot(CTX_LTID_ID);
167}
168
169/////////////////////////////////////////////////////////////////////////////
170// Returns current task global index.
171/////////////////////////////////////////////////////////////////////////////
172unsigned int _global_task_id()
173{
174    return _get_context_slot(CTX_GTID_ID);
175}
176
177/////////////////////////////////////////////////////////////////////////////
178// Returns current thread index.
179/////////////////////////////////////////////////////////////////////////////
180unsigned int _thread_id()
181{
182    return _get_context_slot(CTX_TRDID_ID);
183}
184
185/////////////////////////////////////////////////////////////////////////////
186// This function writes in res_vobj a pointer on a vobj
187// identified by the (vspace_name / vobj_name ) couple.
188// returns 0 if success, >0 if not found
189/////////////////////////////////////////////////////////////////////////////
190int _get_vobj( char*             vspace_name, 
191               char*             vobj_name, 
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                    *res_vobj = &vobj[vobj_id];
214                    return 0;
215                }
216            } 
217        }
218    } 
219    return 1;    //not found
220}
221
222/////////////////////////////////////////////////////////////////////////////
223// This function writes in vobj_vbase the virtual base address of a vobj
224// identified by the (vspace_name / vobj_name ) couple.
225// returns 0 if success, >0 if not found
226/////////////////////////////////////////////////////////////////////////////
227unsigned int _vobj_get_vbase( char*         vspace_name,
228                              char*         vobj_name,
229                              unsigned int* vobj_vbase ) 
230{
231    mapping_vobj_t* res_vobj;
232    unsigned int    ret;
233    if ((ret = _get_vobj(vspace_name, vobj_name, &res_vobj))) 
234    {
235        return ret;
236    }
237    *vobj_vbase = res_vobj->vaddr;
238    return 0;
239}
240
241/////////////////////////////////////////////////////////////////////////////
242// This function writes in vobj_length the length of a vobj
243// identified by the (vspace_name / vobj_name ) couple.
244// returns 0 if success, >0 if not found
245/////////////////////////////////////////////////////////////////////////////
246unsigned int _vobj_get_length( char*         vspace_name, 
247                               char*         vobj_name,
248                               unsigned int* vobj_length ) 
249{
250    mapping_vobj_t * res_vobj;
251    unsigned int ret;
252    if ((ret = _get_vobj(vspace_name, vobj_name, &res_vobj))) 
253    {
254        return ret;
255    }
256    *vobj_length = res_vobj->length;
257    return 0;
258}
259
260/////////////////////////////////////////////////////////////////////////////
261// This function returns in the (x,y) arguments the coordinates of the
262// where is mapped the ptr virtual address. It use the _get_context_slot()
263// function to get the calling task page table, and uses the _v2p_translate()
264// function to obtain the physical address.
265// returns 0 if success, > 0 if ptr not mapped in the calling task vspace.
266/////////////////////////////////////////////////////////////////////////////
267
268unsigned int _get_xy_from_ptr( void*         ptr,
269                               unsigned int* px,
270                               unsigned int* py )
271{
272    unsigned int ret;
273    unsigned int ppn;
274    unsigned int flags;
275    unsigned int vpn  = (((unsigned int)ptr)>>12);
276   
277    // get the page table pointer
278    page_table_t* pt = (page_table_t*)_get_context_slot( CTX_PTAB_ID ); 
279
280    // compute the physical address
281    if ( (ret = _v2p_translate( pt, vpn, &ppn, &flags )) )
282    {
283        return ret;
284    }
285
286    *px = (ppn>>24) & 0xF;
287    *py = (ppn>>20) & 0xF;
288    return 0;
289}
290
291////////////////////////////////////////////////////////////////////////////
292// This sysrem function deschedule the requestint task.
293// It mask interrupts before calling the _ctx_switch, and restore it
294// when the task is rescheduled.
295////////////////////////////////////////////////////////////////////////////
296void _context_switch() 
297{
298    unsigned int save_sr;
299
300    _it_disable( &save_sr );
301    _ctx_switch();
302    _it_restore( &save_sr );
303}
304
305// Local Variables:
306// tab-width: 4
307// c-basic-offset: 4
308// c-file-offsets:((innamespace . 0)(inline-open . 0))
309// indent-tabs-mode: nil
310// End:
311// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
312
Note: See TracBrowser for help on using the repository browser.