source: soft/giet_vm/sys/sys_handler.c @ 219

Last change on this file since 219 was 218, checked in by alain, 12 years ago

Introducing support for Network controller

File size: 7.4 KB
RevLine 
[158]1///////////////////////////////////////////////////////////////////////////////////
2// File     : sys_handler.c
3// Date     : 01/04/2012
4// Author   : alain greiner and joel porquet
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
[203]7// The sys_handler.c and sys_handler.h files are part of the GIET-VM nano-kernel.
[158]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 <drivers.h>
15#include <ctx_handler.h>
16#include <common.h>
17#include <giet_config.h>
18#include <mapping_info.h>
19
20////////////////////////////////////////////////////////////////////////////
21//      Initialize the syscall vector with syscall handlers
22////////////////////////////////////////////////////////////////////////////
23const void *_syscall_vector[32] = {
24    &_procid,           /* 0x00 */
25    &_proctime,         /* 0x01 */
26    &_tty_write,        /* 0x02 */
27    &_tty_read,         /* 0x03 */
[203]28    &_timer_start,      /* 0x04 */
29    &_timer_stop,       /* 0x05 */
[158]30    &_gcd_write,        /* 0x06 */
31    &_gcd_read,         /* 0x07 */
32    &_sys_ukn,          /* 0x08 */
33    &_sys_ukn,          /* 0x09 */
[204]34    &_sys_ukn,          /* 0x0A */
[158]35    &_sys_ukn,          /* 0x0B */
36    &_sys_ukn,          /* 0x0C */
37    &_ctx_switch,       /* 0x0D */
38    &_exit,             /* 0x0E */
39    &_procs_number,     /* 0x0F */
40    &_fb_sync_write,    /* 0x10 */
41    &_fb_sync_read,     /* 0x11 */
42    &_fb_write,         /* 0x12 */
43    &_fb_read,          /* 0x13 */
44    &_fb_completed,     /* 0x14 */
45    &_ioc_write,        /* 0x15 */
46    &_ioc_read,         /* 0x16 */
47    &_ioc_completed,    /* 0x17 */
48    &_sys_ukn,          /* 0x18 */
49    &_sys_ukn,          /* 0x19 */
[160]50    &_vobj_get_vbase,   /* 0x1A */
[218]51    &_nic_write,        /* 0x1B */
52    &_nic_read,         /* 0x1C */
53    &_nic_completed,    /* 0x1D */
[158]54    &_sys_ukn,          /* 0x1E */
55    &_sys_ukn,          /* 0x1F */
56};
57
58//////////////////////////////////////////////////////////////////////////////
59// function executed in case of undefined syscall
60//////////////////////////////////////////////////////////////////////////////
61void _sys_ukn()
62{
63    unsigned int        epc;
64    asm volatile("mfc0 %0, $14" : "=r"(epc));
65
66    _puts("\n\n!!! Undefined System Call !!!\n");
67    _puts("\nEPC = ");
[207]68    _putx( epc );
[158]69    _exit();
70}
71////////////////////////////////////////////////////////////////////////////
72// _exit()
73// Task suicide... after printing a death message.
74////////////////////////////////////////////////////////////////////////////
75void _exit()
76{
[167]77    unsigned int date    = _proctime();
[158]78    unsigned int proc_id = _procid();
[189]79    unsigned int task_id = _get_current_task_id();
80
[158]81     // print death message
[189]82    _get_lock(&_tty_put_lock);
[199]83    _puts("\n[GIET] Exit task ");
84    _putd( task_id );
[158]85    _puts(" on processor ");
[199]86    _putd( proc_id );
[167]87    _puts(" at cycle ");
[199]88    _putd( date );
[165]89    _puts("\n\n");
[189]90    _release_lock(&_tty_put_lock);
91   
[199]92    // goes to sleeping state
93    _set_context_slot( task_id, CTX_RUN_ID, 0 );
94   
95    // deschedule
96    _ctx_switch();
[158]97} 
98//////////////////////////////////////////////////////////////////////////////
99// _procid()
100// Access CP0 and returns current processor's identifier.
101// Max number or processors is 1024.
102//////////////////////////////////////////////////////////////////////////////
103unsigned int _procid()
104{
105    unsigned int ret;
106    asm volatile("mfc0 %0, $15, 1" : "=r"(ret));
[165]107    return (ret & 0xFFF);
[158]108}
109//////////////////////////////////////////////////////////////////////////////
110// _proctime()
111// Access CP0 and returns current processor's elapsed clock cycles since boot.
112//////////////////////////////////////////////////////////////////////////////
113unsigned int _proctime()
114{
115    unsigned int ret;
116    asm volatile("mfc0 %0, $9" : "=r"(ret));
117    return ret;
118}
119//////////////////////////////////////////////////////////////////////////////
120// _procnumber()
121// returns in buffer argument the number of processors in the cluster
122// specified by the cluster_id argument.
123//////////////////////////////////////////////////////////////////////////////
124unsigned int _procs_number( unsigned int        cluster_id,
125                            unsigned int*       buffer)
126{
[160]127    mapping_header_t*   header  = (mapping_header_t*)&seg_mapping_base;
[158]128    mapping_cluster_t*  cluster = _get_cluster_base( header );
129
130    if ( cluster_id < header->clusters )
131    {
132        *buffer = cluster[cluster_id].procs;
133        return 0;
134    }
135    else
136    {
137         return 1;
138    }
139}
[161]140
[215]141int _get_vobj( char* vspace_name, char* vobj_name, unsigned int vobj_type, mapping_vobj_t** res_vobj)
[158]142{
[160]143    mapping_header_t* header = (mapping_header_t*)&seg_mapping_base;
[158]144    mapping_vspace_t* vspace = _get_vspace_base( header );
[160]145    mapping_vobj_t*    vobj  = _get_vobj_base( header );
[158]146
147    unsigned int    vspace_id;
[160]148    unsigned int    vobj_id;
149       
[158]150
151    // scan vspaces
152    for ( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ )
153    {
154        if ( _strncmp( vspace[vspace_id].name, vspace_name, 31) == 0 )
155        {
[160]156            // scan vobjs
[165]157            for( vobj_id = vspace[vspace_id].vobj_offset; 
158                 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 
159                 vobj_id++)
[158]160            {
[160]161
162                if ( _strncmp( vobj[vobj_id].name, vobj_name, 31) == 0 )
[158]163                {
[160]164                    if(vobj[vobj_id].type != vobj_type)
[165]165                        return -1;                                                      //wrong type
[160]166
[215]167                    *res_vobj = &vobj[vobj_id];
168
[158]169                    return 0;
170                }
171            } 
172        }
[163]173    } 
[165]174    return -2;          //not found
[215]175
[158]176}
[215]177/////////////////////////////////////////////////////////////////////////////
178// _vobj_get_vbase()
179// This function writes in vobj_vaddr the virtual base address of a vobj
180// identified by the (vspace_name / vobj_name ) couple.
181// The vobj_type argument is here only for the purpose of checking .
182// returns 0: success, else: failed.
183/////////////////////////////////////////////////////////////////////////////
184unsigned int _vobj_get_vbase( char*                     vspace_name, 
185                              char*                     vobj_name,
186                              unsigned int      vobj_type, 
187                              unsigned int* vobj_vaddr )
188{
189    mapping_vobj_t*   res_vobj;
190    unsigned int ret;
191    if( (ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj)) )
192    {
193        return ret;
194    }
195   
196    *vobj_vaddr = res_vobj->vaddr;
[158]197
[215]198    return 0;
199}
200
201/////////////////////////////////////////////////////////////////////////////
202// _vobj_get_length()
203// This function writes in vobj_length the virtual base address of a vobj
204// identified by the (vspace_name / vobj_name ) couple.
205// The vobj_type argument is here only for the purpose of checking .
206// returns 0: success, else: failed.
207/////////////////////////////////////////////////////////////////////////////
208unsigned int _vobj_get_length(char*                     vspace_name, 
209                              char*                     vobj_name,
210                              unsigned int      vobj_type, 
211                              unsigned int* vobj_length )
212{
213
214    mapping_vobj_t*   res_vobj;
215    unsigned int ret;
216    if( (ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj)) )
217    {
218        return ret;
219    }
220   
221    *vobj_length = res_vobj->length;
222
223    return 0;
224}
Note: See TracBrowser for help on using the repository browser.