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

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

1/ introducing support to display images on the frame buffer
with the vci_chbuf_dma (in stdio.c and drivers.c)
2/ introducing support for mem_cache configuration segment
as the memory cache is considered as another addressable peripheral type
(in drivers.c)
3/ Introducing the new "increment" parameter in the mapping header.
This parameter define the virtual address increment for the vsegs
associated to the replicated peripherals (ICU, XICU, MDMA, TIMER, MMC).
This parameter is mandatory, and all map.xml files the "mappings"
directory have been updated.

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////////////////////////////////////////////////////////////////////////////
[253]23const void * _syscall_vector[32] = 
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 */
[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
[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();
[238]79    unsigned int task_id = _get_context_slot(CTX_LTID_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
[238]93    _set_context_slot(CTX_RUN_ID, 0);
[228]94
[199]95    // deschedule
[231]96    _context_switch();
[158]97} 
[228]98
[158]99//////////////////////////////////////////////////////////////////////////////
100// _procid()
101// Access CP0 and returns current processor's identifier.
102// Max number or processors is 1024.
103//////////////////////////////////////////////////////////////////////////////
[238]104unsigned int _procid() 
105{
[158]106    unsigned int ret;
[228]107    asm volatile("mfc0 %0, $15, 1" : "=r" (ret));
[165]108    return (ret & 0xFFF);
[158]109}
[228]110
[158]111//////////////////////////////////////////////////////////////////////////////
112// _proctime()
113// Access CP0 and returns current processor's elapsed clock cycles since boot.
114//////////////////////////////////////////////////////////////////////////////
[238]115unsigned int _proctime() 
116{
[158]117    unsigned int ret;
[228]118    asm volatile("mfc0 %0, $9" : "=r" (ret));
[158]119    return ret;
120}
[228]121
[158]122//////////////////////////////////////////////////////////////////////////////
123// _procnumber()
124// returns in buffer argument the number of processors in the cluster
125// specified by the cluster_id argument.
126//////////////////////////////////////////////////////////////////////////////
[238]127unsigned int _procs_number(unsigned int  cluster_id, 
128                           unsigned int* buffer) 
129{
[228]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
[238]142/////////////////////////////////////////////////////////////////////////////
143// _local_task_id()
144// Returns current task local index.
145/////////////////////////////////////////////////////////////////////////////
146unsigned int _local_task_id()
147{
148    return _get_context_slot(CTX_LTID_ID);
149}
[158]150
[238]151/////////////////////////////////////////////////////////////////////////////
152// _global_task_id()
153// Returns current task global index.
154/////////////////////////////////////////////////////////////////////////////
155unsigned int _global_task_id()
156{
157    return _get_context_slot(CTX_GTID_ID);
158}
159
160/////////////////////////////////////////////////////////////////////////////
161// _get_vobj()
162// This function writes in res_vobj a pointer on a vobj
163// identified by the (vspace_name / vobj_name ) couple.
164// The vobj_type argument is here only for the purpose of checking .
165// returns 0: success, else: failed.
166/////////////////////////////////////////////////////////////////////////////
167int _get_vobj( char*             vspace_name, 
168               char*             vobj_name, 
169               unsigned int      vobj_type, 
170               mapping_vobj_t**  res_vobj ) 
171{
[228]172    mapping_header_t * header = (mapping_header_t *) &seg_mapping_base;
173    mapping_vspace_t * vspace = _get_vspace_base(header);
[238]174    mapping_vobj_t * vobj     = _get_vobj_base(header);
[158]175
[228]176    unsigned int vspace_id;
177    unsigned int vobj_id;
178
[158]179    // scan vspaces
[238]180    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
181    {
182        if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) 
183        {
[160]184            // scan vobjs
[228]185            for (vobj_id = vspace[vspace_id].vobj_offset; 
[165]186                 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 
[238]187                 vobj_id++) 
188            {
189                if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) 
190                {
191                    if (vobj[vobj_id].type != vobj_type) 
192                    {
[228]193                        _get_lock(&_tty_put_lock);
194                        _puts("*** Error in _get_obj: wrong type\n");
195                        _release_lock(&_tty_put_lock);
[230]196                        return -1; // wrong type
[228]197                    }
[215]198                    *res_vobj = &vobj[vobj_id];
[158]199                    return 0;
200                }
201            } 
202        }
[163]203    } 
[228]204    _get_lock(&_tty_put_lock);
205    _puts("*** Error in _get_obj: object not found\n");
206    _release_lock(&_tty_put_lock);
[215]207
[228]208    return -2; //not found
[158]209}
[228]210
[215]211/////////////////////////////////////////////////////////////////////////////
212// _vobj_get_vbase()
213// This function writes in vobj_vaddr the virtual base address of a vobj
214// identified by the (vspace_name / vobj_name ) couple.
215// The vobj_type argument is here only for the purpose of checking .
216// returns 0: success, else: failed.
217/////////////////////////////////////////////////////////////////////////////
[238]218unsigned int _vobj_get_vbase( char*         vspace_name,
219                              char*         vobj_name,
220                              unsigned int  vobj_type,
221                              unsigned int* vobj_vaddr ) 
222{
223    mapping_vobj_t* res_vobj;
224    unsigned int    ret;
225    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) 
226    {
[215]227        return ret;
228    }
229    *vobj_vaddr = res_vobj->vaddr;
230    return 0;
231}
232
233/////////////////////////////////////////////////////////////////////////////
234// _vobj_get_length()
235// This function writes in vobj_length the virtual base address of a vobj
236// identified by the (vspace_name / vobj_name ) couple.
237// The vobj_type argument is here only for the purpose of checking .
238// returns 0: success, else: failed.
239/////////////////////////////////////////////////////////////////////////////
[238]240unsigned int _vobj_get_length( char*         vspace_name, 
241                               char*         vobj_name,
242                               unsigned int  vobj_type, 
243                               unsigned int* vobj_length ) 
244{
[228]245    mapping_vobj_t * res_vobj;
[215]246    unsigned int ret;
[238]247    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) 
248    {
[215]249        return ret;
250    }
251    *vobj_length = res_vobj->length;
252    return 0;
253}
[228]254
255
256////////////////////////////////////////////////////////////////
257// _context_switch()
258// This functions masks interruptions before calling _ctx_switch
259// (They are usually masked when we receive a isr_switch interrupt
[238]260// because we execute ISRs with interrupt masked)
[228]261////////////////////////////////////////////////////////////////
[238]262void _context_switch() 
263{
[231]264    _it_disable();
[228]265    _ctx_switch();
266}
267
268
269// Local Variables:
270// tab-width: 4
271// c-basic-offset: 4
272// c-file-offsets:((innamespace . 0)(inline-open . 0))
273// indent-tabs-mode: nil
274// End:
275// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
276
Note: See TracBrowser for help on using the repository browser.