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

Last change on this file since 250 was 238, checked in by alain, 11 years ago

Major evolution to support physical addresses larger than 32 bits.
The map.xml format has been modified: the vsegs associated to schedulers
are now explicitely defined and mapped in the page tables.

File size: 9.5 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////////////////////////////////////////////////////////////////////////////
[228]21//    Initialize the syscall vector with syscall handlers
[158]22////////////////////////////////////////////////////////////////////////////
[228]23const void * _syscall_vector[32] = {
24    &_procid,              /* 0x00 */
25    &_proctime,            /* 0x01 */
26    &_tty_write,           /* 0x02 */
27    &_tty_read,            /* 0x03 */
28    &_timer_start,         /* 0x04 */
29    &_timer_stop,          /* 0x05 */
30    &_gcd_write,           /* 0x06 */
31    &_gcd_read,            /* 0x07 */
[232]32    &_heap_info,           /* 0x08 */
[238]33    &_local_task_id,       /* 0x09 */
34    &_global_task_id,      /* 0x0A */ 
[228]35    &_sys_ukn,             /* 0x0B */
36    &_sys_ukn,             /* 0x0C */
37    &_context_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 */
[237]48    &_ioc_get_block_size,  /* 0x18 */
[228]49    &_sys_ukn,             /* 0x19 */
50    &_vobj_get_vbase,      /* 0x1A */
51    &_nic_write,           /* 0x1B */
52    &_nic_read,            /* 0x1C */
53    &_nic_completed,       /* 0x1D */
54    &_sys_ukn,             /* 0x1E */
55    &_sys_ukn,             /* 0x1F */
[158]56};
57
58//////////////////////////////////////////////////////////////////////////////
59// function executed in case of undefined syscall
60//////////////////////////////////////////////////////////////////////////////
[228]61void _sys_ukn() {
62    unsigned int epc;
63    asm volatile("mfc0 %0, $14" : "=r" (epc));
[158]64
65    _puts("\n\n!!! Undefined System Call !!!\n");
66    _puts("\nEPC = ");
[228]67    _putx(epc);
[158]68    _exit();
69}
[228]70
[158]71////////////////////////////////////////////////////////////////////////////
72// _exit()
73// Task suicide... after printing a death message.
74////////////////////////////////////////////////////////////////////////////
[228]75void _exit() {
76    unsigned int date = _proctime();
[158]77    unsigned int proc_id = _procid();
[238]78    unsigned int task_id = _get_context_slot(CTX_LTID_ID);
[189]79
[228]80    // print death message
[189]81    _get_lock(&_tty_put_lock);
[199]82    _puts("\n[GIET] Exit task ");
[228]83    _putd(task_id);
[158]84    _puts(" on processor ");
[228]85    _putd(proc_id);
[167]86    _puts(" at cycle ");
[228]87    _putd(date);
[165]88    _puts("\n\n");
[189]89    _release_lock(&_tty_put_lock);
[228]90
[199]91    // goes to sleeping state
[238]92    _set_context_slot(CTX_RUN_ID, 0);
[228]93
[199]94    // deschedule
[231]95    _context_switch();
[158]96} 
[228]97
[158]98//////////////////////////////////////////////////////////////////////////////
99// _procid()
100// Access CP0 and returns current processor's identifier.
101// Max number or processors is 1024.
102//////////////////////////////////////////////////////////////////////////////
[238]103unsigned int _procid() 
104{
[158]105    unsigned int ret;
[228]106    asm volatile("mfc0 %0, $15, 1" : "=r" (ret));
[165]107    return (ret & 0xFFF);
[158]108}
[228]109
[158]110//////////////////////////////////////////////////////////////////////////////
111// _proctime()
112// Access CP0 and returns current processor's elapsed clock cycles since boot.
113//////////////////////////////////////////////////////////////////////////////
[238]114unsigned int _proctime() 
115{
[158]116    unsigned int ret;
[228]117    asm volatile("mfc0 %0, $9" : "=r" (ret));
[158]118    return ret;
119}
[228]120
[158]121//////////////////////////////////////////////////////////////////////////////
122// _procnumber()
123// returns in buffer argument the number of processors in the cluster
124// specified by the cluster_id argument.
125//////////////////////////////////////////////////////////////////////////////
[238]126unsigned int _procs_number(unsigned int  cluster_id, 
127                           unsigned int* buffer) 
128{
[228]129    mapping_header_t * header  = (mapping_header_t *) &seg_mapping_base;
130    mapping_cluster_t * cluster = _get_cluster_base(header);
[158]131
[228]132    if (cluster_id < header->clusters) {
[158]133        *buffer = cluster[cluster_id].procs;
134        return 0;
135    }
[228]136    else {
137        return 1;
[158]138    }
139}
[161]140
[238]141/////////////////////////////////////////////////////////////////////////////
142// _local_task_id()
143// Returns current task local index.
144/////////////////////////////////////////////////////////////////////////////
145unsigned int _local_task_id()
146{
147    return _get_context_slot(CTX_LTID_ID);
148}
[158]149
[238]150/////////////////////////////////////////////////////////////////////////////
151// _global_task_id()
152// Returns current task global index.
153/////////////////////////////////////////////////////////////////////////////
154unsigned int _global_task_id()
155{
156    return _get_context_slot(CTX_GTID_ID);
157}
158
159/////////////////////////////////////////////////////////////////////////////
160// _get_vobj()
161// This function writes in res_vobj a pointer on a vobj
162// identified by the (vspace_name / vobj_name ) couple.
163// The vobj_type argument is here only for the purpose of checking .
164// returns 0: success, else: failed.
165/////////////////////////////////////////////////////////////////////////////
166int _get_vobj( char*             vspace_name, 
167               char*             vobj_name, 
168               unsigned int      vobj_type, 
169               mapping_vobj_t**  res_vobj ) 
170{
[228]171    mapping_header_t * header = (mapping_header_t *) &seg_mapping_base;
172    mapping_vspace_t * vspace = _get_vspace_base(header);
[238]173    mapping_vobj_t * vobj     = _get_vobj_base(header);
[158]174
[228]175    unsigned int vspace_id;
176    unsigned int vobj_id;
177
[158]178    // scan vspaces
[238]179    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
180    {
181        if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) 
182        {
[160]183            // scan vobjs
[228]184            for (vobj_id = vspace[vspace_id].vobj_offset; 
[165]185                 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 
[238]186                 vobj_id++) 
187            {
188                if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) 
189                {
190                    if (vobj[vobj_id].type != vobj_type) 
191                    {
[228]192                        _get_lock(&_tty_put_lock);
193                        _puts("*** Error in _get_obj: wrong type\n");
194                        _release_lock(&_tty_put_lock);
[230]195                        return -1; // wrong type
[228]196                    }
[215]197                    *res_vobj = &vobj[vobj_id];
[158]198                    return 0;
199                }
200            } 
201        }
[163]202    } 
[228]203    _get_lock(&_tty_put_lock);
204    _puts("*** Error in _get_obj: object not found\n");
205    _release_lock(&_tty_put_lock);
[215]206
[228]207    return -2; //not found
[158]208}
[228]209
[215]210/////////////////////////////////////////////////////////////////////////////
211// _vobj_get_vbase()
212// This function writes in vobj_vaddr the virtual base address of a vobj
213// identified by the (vspace_name / vobj_name ) couple.
214// The vobj_type argument is here only for the purpose of checking .
215// returns 0: success, else: failed.
216/////////////////////////////////////////////////////////////////////////////
[238]217unsigned int _vobj_get_vbase( char*         vspace_name,
218                              char*         vobj_name,
219                              unsigned int  vobj_type,
220                              unsigned int* vobj_vaddr ) 
221{
222    mapping_vobj_t* res_vobj;
223    unsigned int    ret;
224    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) 
225    {
[215]226        return ret;
227    }
228    *vobj_vaddr = res_vobj->vaddr;
229    return 0;
230}
231
232/////////////////////////////////////////////////////////////////////////////
233// _vobj_get_length()
234// This function writes in vobj_length the virtual base address of a vobj
235// identified by the (vspace_name / vobj_name ) couple.
236// The vobj_type argument is here only for the purpose of checking .
237// returns 0: success, else: failed.
238/////////////////////////////////////////////////////////////////////////////
[238]239unsigned int _vobj_get_length( char*         vspace_name, 
240                               char*         vobj_name,
241                               unsigned int  vobj_type, 
242                               unsigned int* vobj_length ) 
243{
[228]244    mapping_vobj_t * res_vobj;
[215]245    unsigned int ret;
[238]246    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) 
247    {
[215]248        return ret;
249    }
250    *vobj_length = res_vobj->length;
251    return 0;
252}
[228]253
254
255////////////////////////////////////////////////////////////////
256// _context_switch()
257// This functions masks interruptions before calling _ctx_switch
258// (They are usually masked when we receive a isr_switch interrupt
[238]259// because we execute ISRs with interrupt masked)
[228]260////////////////////////////////////////////////////////////////
[238]261void _context_switch() 
262{
[231]263    _it_disable();
[228]264    _ctx_switch();
265}
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.