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

Last change on this file since 355 was 322, checked in by alain, 10 years ago

Various small modifs to comply with the genmap tool.

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