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

Last change on this file since 232 was 232, checked in by meunier, 11 years ago

Ajout du malloc dans le Giet.

File size: 8.2 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 */
33    &_get_proc_task_id,    /* 0x09 */
34    &_get_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 */
48    &_sys_ukn,             /* 0x18 */
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
71
[158]72////////////////////////////////////////////////////////////////////////////
73// _exit()
74// Task suicide... after printing a death message.
75////////////////////////////////////////////////////////////////////////////
[228]76void _exit() {
77    unsigned int date = _proctime();
[158]78    unsigned int proc_id = _procid();
[232]79    unsigned int task_id = _get_proc_task_id();
[189]80
[228]81    // print death message
[189]82    _get_lock(&_tty_put_lock);
[199]83    _puts("\n[GIET] Exit task ");
[228]84    _putd(task_id);
[158]85    _puts(" on processor ");
[228]86    _putd(proc_id);
[167]87    _puts(" at cycle ");
[228]88    _putd(date);
[165]89    _puts("\n\n");
[189]90    _release_lock(&_tty_put_lock);
[228]91
[199]92    // goes to sleeping state
[228]93    _set_context_slot( task_id, CTX_RUN_ID, 0);
94
[199]95    // deschedule
[231]96    _context_switch();
[158]97} 
[228]98
99
[158]100//////////////////////////////////////////////////////////////////////////////
101// _procid()
102// Access CP0 and returns current processor's identifier.
103// Max number or processors is 1024.
104//////////////////////////////////////////////////////////////////////////////
[228]105unsigned int _procid() {
[158]106    unsigned int ret;
[228]107    asm volatile("mfc0 %0, $15, 1" : "=r" (ret));
[165]108    return (ret & 0xFFF);
[158]109}
[228]110
111
[158]112//////////////////////////////////////////////////////////////////////////////
113// _proctime()
114// Access CP0 and returns current processor's elapsed clock cycles since boot.
115//////////////////////////////////////////////////////////////////////////////
[228]116unsigned int _proctime() {
[158]117    unsigned int ret;
[228]118    asm volatile("mfc0 %0, $9" : "=r" (ret));
[158]119    return ret;
120}
[228]121
122
[158]123//////////////////////////////////////////////////////////////////////////////
124// _procnumber()
125// returns in buffer argument the number of processors in the cluster
126// specified by the cluster_id argument.
127//////////////////////////////////////////////////////////////////////////////
[228]128unsigned int _procs_number(unsigned int cluster_id, unsigned int * buffer) {
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
[158]141
[228]142int _get_vobj(char * vspace_name, char * vobj_name, unsigned int vobj_type, mapping_vobj_t ** res_vobj) {
143    mapping_header_t * header = (mapping_header_t *) &seg_mapping_base;
144    mapping_vspace_t * vspace = _get_vspace_base(header);
145    mapping_vobj_t * vobj  = _get_vobj_base(header);
[158]146
[228]147    unsigned int vspace_id;
148    unsigned int vobj_id;
149
[158]150    // scan vspaces
[228]151    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) {
152        if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) {
[160]153            // scan vobjs
[228]154            for (vobj_id = vspace[vspace_id].vobj_offset; 
[165]155                 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 
[228]156                 vobj_id++) {
[160]157
[228]158                if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) {
159                    if (vobj[vobj_id].type != vobj_type) {
160                        _get_lock(&_tty_put_lock);
161                        _puts("*** Error in _get_obj: wrong type\n");
162                        _release_lock(&_tty_put_lock);
[230]163                        return -1; // wrong type
[228]164                    }
[215]165                    *res_vobj = &vobj[vobj_id];
[158]166                    return 0;
167                }
168            } 
169        }
[163]170    } 
[228]171    _get_lock(&_tty_put_lock);
172    _puts("*** Error in _get_obj: object not found\n");
173    _release_lock(&_tty_put_lock);
[215]174
[228]175    return -2; //not found
[158]176}
[228]177
178
[215]179/////////////////////////////////////////////////////////////////////////////
180// _vobj_get_vbase()
181// This function writes in vobj_vaddr the virtual base address of a vobj
182// identified by the (vspace_name / vobj_name ) couple.
183// The vobj_type argument is here only for the purpose of checking .
184// returns 0: success, else: failed.
185/////////////////////////////////////////////////////////////////////////////
[228]186unsigned int _vobj_get_vbase(
187        char * vspace_name,
188        char * vobj_name,
189        unsigned int vobj_type,
190        unsigned int * vobj_vaddr) {
191    mapping_vobj_t * res_vobj;
[215]192    unsigned int ret;
[228]193    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) {
[215]194        return ret;
195    }
[228]196
[215]197    *vobj_vaddr = res_vobj->vaddr;
198    return 0;
199}
200
[228]201
[215]202/////////////////////////////////////////////////////////////////////////////
203// _vobj_get_length()
204// This function writes in vobj_length the virtual base address of a vobj
205// identified by the (vspace_name / vobj_name ) couple.
206// The vobj_type argument is here only for the purpose of checking .
207// returns 0: success, else: failed.
208/////////////////////////////////////////////////////////////////////////////
[228]209unsigned int _vobj_get_length(
210        char * vspace_name, 
211        char * vobj_name,
212        unsigned int vobj_type, 
213        unsigned int * vobj_length) {
[215]214
[228]215    mapping_vobj_t * res_vobj;
[215]216    unsigned int ret;
[228]217    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) {
[215]218        return ret;
219    }
[228]220
[215]221    *vobj_length = res_vobj->length;
222
223    return 0;
224}
[228]225
226
227////////////////////////////////////////////////////////////////
228// _context_switch()
229// This functions masks interruptions before calling _ctx_switch
230// (They are usually masked when we receive a isr_switch interrupt
231// because we execute isrs with interrupt masked)
232////////////////////////////////////////////////////////////////
233void _context_switch() {
[231]234    _it_disable();
[228]235    _ctx_switch();
236}
237
238
239// Local Variables:
240// tab-width: 4
241// c-basic-offset: 4
242// c-file-offsets:((innamespace . 0)(inline-open . 0))
243// indent-tabs-mode: nil
244// End:
245// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
246
Note: See TracBrowser for help on using the repository browser.