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

Last change on this file since 255 was 255, checked in by meunier, 11 years ago
  • Added a syscall and some user functions to manipulate the Simulation Helper
  • Changed the the way the Vseg -> Pseg mapping is made during the boot to better utilize the address space (+ adaptation of the algorithm in memo)
  • Fixed a bug in boot_init (vobj_init): the vobj initialization could only be made for the first application (ptpr was not changed)
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.
[255]8// It defines the syscall_vector[], as well as the
[158]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////////////////////////////////////////////////////////////////////////////
[255]23const void * _syscall_vector[64] = 
[253]24{
[228]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 */
[232]33    &_heap_info,           /* 0x08 */
[238]34    &_local_task_id,       /* 0x09 */
35    &_global_task_id,      /* 0x0A */ 
[253]36    &_fb_cma_init,         /* 0x0B */
37    &_fb_cma_write,        /* 0x0C */
38    &_fb_cma_stop,         /* 0x0D */
[228]39    &_exit,                /* 0x0E */
40    &_procs_number,        /* 0x0F */
41    &_fb_sync_write,       /* 0x10 */
42    &_fb_sync_read,        /* 0x11 */
[253]43    &_fb_dma_write,        /* 0x12 */
44    &_fb_dma_read,         /* 0x13 */
45    &_fb_dma_completed,    /* 0x14 */
[228]46    &_ioc_write,           /* 0x15 */
47    &_ioc_read,            /* 0x16 */
48    &_ioc_completed,       /* 0x17 */
[237]49    &_ioc_get_block_size,  /* 0x18 */
[253]50    &_ctx_switch,          /* 0x19 */
[228]51    &_vobj_get_vbase,      /* 0x1A */
[253]52    &_nic_cma_rx_init,     /* 0x1B */
53    &_nic_cma_tx_init,     /* 0x1C */
54    &_nic_cma_stop,        /* 0x1D */
55    &_nic_sync_read,       /* 0x1E */
56    &_nic_sync_write,      /* 0x1F */
[255]57    &_sim_helper_access,   /* 0x20 */
[158]58};
59
60//////////////////////////////////////////////////////////////////////////////
61// function executed in case of undefined syscall
62//////////////////////////////////////////////////////////////////////////////
[228]63void _sys_ukn() {
64    unsigned int epc;
65    asm volatile("mfc0 %0, $14" : "=r" (epc));
[158]66
67    _puts("\n\n!!! Undefined System Call !!!\n");
68    _puts("\nEPC = ");
[228]69    _putx(epc);
[158]70    _exit();
71}
[228]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();
[238]80    unsigned int task_id = _get_context_slot(CTX_LTID_ID);
[189]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
[238]94    _set_context_slot(CTX_RUN_ID, 0);
[228]95
[199]96    // deschedule
[231]97    _context_switch();
[158]98} 
[228]99
[158]100//////////////////////////////////////////////////////////////////////////////
101// _procid()
102// Access CP0 and returns current processor's identifier.
103// Max number or processors is 1024.
104//////////////////////////////////////////////////////////////////////////////
[238]105unsigned int _procid() 
106{
[158]107    unsigned int ret;
[228]108    asm volatile("mfc0 %0, $15, 1" : "=r" (ret));
[165]109    return (ret & 0xFFF);
[158]110}
[228]111
[158]112//////////////////////////////////////////////////////////////////////////////
113// _proctime()
114// Access CP0 and returns current processor's elapsed clock cycles since boot.
115//////////////////////////////////////////////////////////////////////////////
[238]116unsigned int _proctime() 
117{
[158]118    unsigned int ret;
[228]119    asm volatile("mfc0 %0, $9" : "=r" (ret));
[158]120    return ret;
121}
[228]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//////////////////////////////////////////////////////////////////////////////
[238]128unsigned int _procs_number(unsigned int  cluster_id, 
129                           unsigned int* buffer) 
130{
[228]131    mapping_header_t * header  = (mapping_header_t *) &seg_mapping_base;
132    mapping_cluster_t * cluster = _get_cluster_base(header);
[158]133
[228]134    if (cluster_id < header->clusters) {
[158]135        *buffer = cluster[cluster_id].procs;
136        return 0;
137    }
[228]138    else {
139        return 1;
[158]140    }
141}
[161]142
[238]143/////////////////////////////////////////////////////////////////////////////
144// _local_task_id()
145// Returns current task local index.
146/////////////////////////////////////////////////////////////////////////////
147unsigned int _local_task_id()
148{
149    return _get_context_slot(CTX_LTID_ID);
150}
[158]151
[238]152/////////////////////////////////////////////////////////////////////////////
153// _global_task_id()
154// Returns current task global index.
155/////////////////////////////////////////////////////////////////////////////
156unsigned int _global_task_id()
157{
158    return _get_context_slot(CTX_GTID_ID);
159}
160
161/////////////////////////////////////////////////////////////////////////////
162// _get_vobj()
163// This function writes in res_vobj a pointer on a vobj
164// identified by the (vspace_name / vobj_name ) couple.
165// The vobj_type argument is here only for the purpose of checking .
166// returns 0: success, else: failed.
167/////////////////////////////////////////////////////////////////////////////
168int _get_vobj( char*             vspace_name, 
169               char*             vobj_name, 
170               unsigned int      vobj_type, 
171               mapping_vobj_t**  res_vobj ) 
172{
[228]173    mapping_header_t * header = (mapping_header_t *) &seg_mapping_base;
174    mapping_vspace_t * vspace = _get_vspace_base(header);
[238]175    mapping_vobj_t * vobj     = _get_vobj_base(header);
[158]176
[228]177    unsigned int vspace_id;
178    unsigned int vobj_id;
179
[158]180    // scan vspaces
[238]181    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
182    {
183        if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) 
184        {
[160]185            // scan vobjs
[228]186            for (vobj_id = vspace[vspace_id].vobj_offset; 
[165]187                 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 
[238]188                 vobj_id++) 
189            {
190                if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) 
191                {
192                    if (vobj[vobj_id].type != vobj_type) 
193                    {
[228]194                        _get_lock(&_tty_put_lock);
195                        _puts("*** Error in _get_obj: wrong type\n");
196                        _release_lock(&_tty_put_lock);
[230]197                        return -1; // wrong type
[228]198                    }
[215]199                    *res_vobj = &vobj[vobj_id];
[158]200                    return 0;
201                }
202            } 
203        }
[163]204    } 
[228]205    _get_lock(&_tty_put_lock);
206    _puts("*** Error in _get_obj: object not found\n");
207    _release_lock(&_tty_put_lock);
[215]208
[228]209    return -2; //not found
[158]210}
[228]211
[215]212/////////////////////////////////////////////////////////////////////////////
213// _vobj_get_vbase()
214// This function writes in vobj_vaddr the virtual base address of a vobj
215// identified by the (vspace_name / vobj_name ) couple.
216// The vobj_type argument is here only for the purpose of checking .
217// returns 0: success, else: failed.
218/////////////////////////////////////////////////////////////////////////////
[238]219unsigned int _vobj_get_vbase( char*         vspace_name,
220                              char*         vobj_name,
221                              unsigned int  vobj_type,
222                              unsigned int* vobj_vaddr ) 
223{
224    mapping_vobj_t* res_vobj;
225    unsigned int    ret;
226    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) 
227    {
[215]228        return ret;
229    }
230    *vobj_vaddr = res_vobj->vaddr;
231    return 0;
232}
233
234/////////////////////////////////////////////////////////////////////////////
235// _vobj_get_length()
236// This function writes in vobj_length the virtual base address of a vobj
237// identified by the (vspace_name / vobj_name ) couple.
238// The vobj_type argument is here only for the purpose of checking .
239// returns 0: success, else: failed.
240/////////////////////////////////////////////////////////////////////////////
[238]241unsigned int _vobj_get_length( char*         vspace_name, 
242                               char*         vobj_name,
243                               unsigned int  vobj_type, 
244                               unsigned int* vobj_length ) 
245{
[228]246    mapping_vobj_t * res_vobj;
[215]247    unsigned int ret;
[238]248    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) 
249    {
[215]250        return ret;
251    }
252    *vobj_length = res_vobj->length;
253    return 0;
254}
[228]255
256
257////////////////////////////////////////////////////////////////
258// _context_switch()
259// This functions masks interruptions before calling _ctx_switch
260// (They are usually masked when we receive a isr_switch interrupt
[238]261// because we execute ISRs with interrupt masked)
[228]262////////////////////////////////////////////////////////////////
[238]263void _context_switch() 
264{
[231]265    _it_disable();
[228]266    _ctx_switch();
267}
268
269
270// Local Variables:
271// tab-width: 4
272// c-basic-offset: 4
273// c-file-offsets:((innamespace . 0)(inline-open . 0))
274// indent-tabs-mode: nil
275// End:
276// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
277
Note: See TracBrowser for help on using the repository browser.