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

Last change on this file since 306 was 301, checked in by cfuguet, 11 years ago

Bugfix for interrupt masking and demasking.

  • Property svn:executable set to *
File size: 9.6 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 */
[294]37    &_tty_get_lock,        /* 0x06 */
38    &_tty_release_lock,    /* 0x07 */
[258]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 */
[294]51    &_sys_ukn,             /* 0x13 */
[258]52    &_sys_ukn,             /* 0x14 */
53    &_sys_ukn,             /* 0x15 */ 
54    &_sys_ukn,             /* 0x16 */
55    &_sys_ukn,             /* 0x17 */
56    &_sys_ukn,             /* 0x18 */   
[301]57    &_context_switch,      /* 0x19 */
[258]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{
[294]105    _printf("\n\n[GIET ERROR] Undefined System Call / EPC = %x\n", _get_epc() );
[258]106    _exit();
107}
108
109////////////////////////////////////////////////////////////////////////////
110// Task suicide... after printing a death message.
111////////////////////////////////////////////////////////////////////////////
[294]112void _task_exit( char* string ) 
[258]113{
[294]114    unsigned int date       = _get_proctime();
115    unsigned int proc_id    = _get_procid();
116    unsigned int cluster_xy = proc_id / NB_PROCS_MAX;
117    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
118    unsigned int x          = cluster_xy >> Y_WIDTH;
119    unsigned int lpid       = proc_id % NB_PROCS_MAX;
120    unsigned int task_id    = _get_context_slot(CTX_LTID_ID);
[258]121
122    // print death message
[294]123    _printf("\n[GIET] Exit task %d on processor[%d,%d,%d] at cycle %d"
124            "\n       Cause : %s\n\n",
125            task_id, x, y, lpid, date, string );
[258]126
127    // goes to sleeping state
128    _set_context_slot(CTX_RUN_ID, 0);
129
130    // deschedule
131    _context_switch();
132} 
133
134//////////////////////////////////////////////////////////////////////////////
135// returns in buffer argument the number of processors in the cluster
136// specified by the cluster_id argument.
137//////////////////////////////////////////////////////////////////////////////
138unsigned int _procs_number(unsigned int  cluster_id, 
139                           unsigned int* buffer) 
140{
141    mapping_header_t * header  = (mapping_header_t *) &seg_boot_mapping_base;
142    mapping_cluster_t * cluster = _get_cluster_base(header);
143
[263]144    if ( cluster_id < X_SIZE * Y_SIZE ) 
145    {
[258]146        *buffer = cluster[cluster_id].procs;
147        return 0;
148    }
[263]149    else 
150    {
[258]151        return 1;
152    }
153}
154
155/////////////////////////////////////////////////////////////////////////////
156// Returns current task local index.
157/////////////////////////////////////////////////////////////////////////////
158unsigned int _local_task_id()
159{
160    return _get_context_slot(CTX_LTID_ID);
161}
162
163/////////////////////////////////////////////////////////////////////////////
164// Returns current task global index.
165/////////////////////////////////////////////////////////////////////////////
166unsigned int _global_task_id()
167{
168    return _get_context_slot(CTX_GTID_ID);
169}
170
171/////////////////////////////////////////////////////////////////////////////
[267]172// Returns current thread index.
173/////////////////////////////////////////////////////////////////////////////
174unsigned int _thread_id()
175{
176    return _get_context_slot(CTX_TRDID_ID);
177}
178
179/////////////////////////////////////////////////////////////////////////////
[258]180// This function writes in res_vobj a pointer on a vobj
181// identified by the (vspace_name / vobj_name ) couple.
[294]182// returns 0 if success, >0 if not found
[258]183/////////////////////////////////////////////////////////////////////////////
184int _get_vobj( char*             vspace_name, 
185               char*             vobj_name, 
186               mapping_vobj_t**  res_vobj ) 
187{
188    mapping_header_t * header = (mapping_header_t *) &seg_boot_mapping_base;
189    mapping_vspace_t * vspace = _get_vspace_base(header);
190    mapping_vobj_t * vobj     = _get_vobj_base(header);
191
192    unsigned int vspace_id;
193    unsigned int vobj_id;
194
195    // scan vspaces
196    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
197    {
198        if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) 
199        {
200            // scan vobjs
201            for (vobj_id = vspace[vspace_id].vobj_offset; 
202                 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 
203                 vobj_id++) 
204            {
205                if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) 
206                {
207                    *res_vobj = &vobj[vobj_id];
208                    return 0;
209                }
210            } 
211        }
212    } 
[294]213    return 1;    //not found
[258]214}
215
216/////////////////////////////////////////////////////////////////////////////
217// This function writes in vobj_vaddr the virtual base address of a vobj
218// identified by the (vspace_name / vobj_name ) couple.
[294]219// returns 0 if success, >0 if not found
[258]220/////////////////////////////////////////////////////////////////////////////
221unsigned int _vobj_get_vbase( char*         vspace_name,
222                              char*         vobj_name,
[294]223                              unsigned int* vobj_vbase ) 
[258]224{
225    mapping_vobj_t* res_vobj;
226    unsigned int    ret;
[294]227    if ((ret = _get_vobj(vspace_name, vobj_name, &res_vobj))) 
[258]228    {
229        return ret;
230    }
[294]231    *vobj_vbase = res_vobj->vaddr;
[258]232    return 0;
233}
234
235/////////////////////////////////////////////////////////////////////////////
[294]236// This function writes in vobj_length the length of a vobj
[258]237// identified by the (vspace_name / vobj_name ) couple.
[294]238// returns 0 if success, >0 if not found
[258]239/////////////////////////////////////////////////////////////////////////////
240unsigned int _vobj_get_length( char*         vspace_name, 
241                               char*         vobj_name,
242                               unsigned int* vobj_length ) 
243{
244    mapping_vobj_t * res_vobj;
245    unsigned int ret;
[294]246    if ((ret = _get_vobj(vspace_name, vobj_name, &res_vobj))) 
[258]247    {
248        return ret;
249    }
250    *vobj_length = res_vobj->length;
251    return 0;
252}
253
[294]254////////////////////////////////////////////////////////////////////////////
255// This sysrem function deschedule the requestint task.
256// It mask interrupts before calling the _ctx_switch, and restore it
257// when the task is rescheduled.
258////////////////////////////////////////////////////////////////////////////
[258]259void _context_switch() 
260{
[294]261    unsigned int save_sr;
262
263    _it_disable( &save_sr );
[258]264    _ctx_switch();
[294]265    _it_restore( &save_sr );
[258]266}
267
268// Local Variables:
269// tab-width: 4
270// c-basic-offset: 4
271// c-file-offsets:((innamespace . 0)(inline-open . 0))
272// indent-tabs-mode: nil
273// End:
274// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
275
Note: See TracBrowser for help on using the repository browser.