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

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

Correction d'un bug lors du boot pour les alignements
Modification de l'appel SRL pour les CONST

File size: 8.2 KB
Line 
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 <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 */
28    &_timer_start,         /* 0x04 */
29    &_timer_stop,          /* 0x05 */
30    &_gcd_write,           /* 0x06 */
31    &_gcd_read,            /* 0x07 */
32    &_sys_ukn,             /* 0x08 */
33    &_get_current_task_id, /* 0x09 */
34    &_sys_ukn,             /* 0x0A */
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 */
56};
57
58//////////////////////////////////////////////////////////////////////////////
59// function executed in case of undefined syscall
60//////////////////////////////////////////////////////////////////////////////
61void _sys_ukn() {
62    unsigned int epc;
63    asm volatile("mfc0 %0, $14" : "=r" (epc));
64
65    _puts("\n\n!!! Undefined System Call !!!\n");
66    _puts("\nEPC = ");
67    _putx(epc);
68    _exit();
69}
70
71
72////////////////////////////////////////////////////////////////////////////
73// _exit()
74// Task suicide... after printing a death message.
75////////////////////////////////////////////////////////////////////////////
76void _exit() {
77    unsigned int date = _proctime();
78    unsigned int proc_id = _procid();
79    unsigned int task_id = _get_current_task_id();
80
81    // print death message
82    _get_lock(&_tty_put_lock);
83    _puts("\n[GIET] Exit task ");
84    _putd(task_id);
85    _puts(" on processor ");
86    _putd(proc_id);
87    _puts(" at cycle ");
88    _putd(date);
89    _puts("\n\n");
90    _release_lock(&_tty_put_lock);
91
92    // goes to sleeping state
93    _set_context_slot( task_id, CTX_RUN_ID, 0);
94
95    // deschedule
96    _ctx_switch();
97} 
98
99
100//////////////////////////////////////////////////////////////////////////////
101// _procid()
102// Access CP0 and returns current processor's identifier.
103// Max number or processors is 1024.
104//////////////////////////////////////////////////////////////////////////////
105unsigned int _procid() {
106    unsigned int ret;
107    asm volatile("mfc0 %0, $15, 1" : "=r" (ret));
108    return (ret & 0xFFF);
109}
110
111
112//////////////////////////////////////////////////////////////////////////////
113// _proctime()
114// Access CP0 and returns current processor's elapsed clock cycles since boot.
115//////////////////////////////////////////////////////////////////////////////
116unsigned int _proctime() {
117    unsigned int ret;
118    asm volatile("mfc0 %0, $9" : "=r" (ret));
119    return ret;
120}
121
122
123//////////////////////////////////////////////////////////////////////////////
124// _procnumber()
125// returns in buffer argument the number of processors in the cluster
126// specified by the cluster_id argument.
127//////////////////////////////////////////////////////////////////////////////
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);
131
132    if (cluster_id < header->clusters) {
133        *buffer = cluster[cluster_id].procs;
134        return 0;
135    }
136    else {
137        return 1;
138    }
139}
140
141
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);
146
147    unsigned int vspace_id;
148    unsigned int vobj_id;
149
150    // scan vspaces
151    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) {
152        if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) {
153            // scan vobjs
154            for (vobj_id = vspace[vspace_id].vobj_offset; 
155                 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 
156                 vobj_id++) {
157
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);
163                        return -1; // wrong type
164                    }
165                    *res_vobj = &vobj[vobj_id];
166                    return 0;
167                }
168            } 
169        }
170    } 
171    _get_lock(&_tty_put_lock);
172    _puts("*** Error in _get_obj: object not found\n");
173    _release_lock(&_tty_put_lock);
174
175    return -2; //not found
176}
177
178
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/////////////////////////////////////////////////////////////////////////////
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;
192    unsigned int ret;
193    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) {
194        return ret;
195    }
196
197    *vobj_vaddr = res_vobj->vaddr;
198    return 0;
199}
200
201
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/////////////////////////////////////////////////////////////////////////////
209unsigned int _vobj_get_length(
210        char * vspace_name, 
211        char * vobj_name,
212        unsigned int vobj_type, 
213        unsigned int * vobj_length) {
214
215    mapping_vobj_t * res_vobj;
216    unsigned int ret;
217    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) {
218        return ret;
219    }
220
221    *vobj_length = res_vobj->length;
222
223    return 0;
224}
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() {
234    _it_mask();
235    _ctx_switch();
236    _it_restore();
237}
238
239
240// Local Variables:
241// tab-width: 4
242// c-basic-offset: 4
243// c-file-offsets:((innamespace . 0)(inline-open . 0))
244// indent-tabs-mode: nil
245// End:
246// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
247
Note: See TracBrowser for help on using the repository browser.