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

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

Added support for memspaces and const.
Added an interrupt masking to the "giet_context_switch" syscall
Corrected two bugs in boot/boot_init.c (one minor and one regarding barriers initialization)
Reformatted the code in all files.

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