source: soft/giet_vm/giet_kernel/sys_handler.c @ 437

Last change on this file since 437 was 428, checked in by alain, 10 years ago

Introducing fixed format (X_WIDTH / Y_WIDTH / P_WIDTH) for processor index.

  • Property svn:executable set to *
File size: 11.3 KB
RevLine 
[258]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 <tty_driver.h>
15#include <tim_driver.h>
16#include <ioc_driver.h>
17#include <nic_driver.h>
18#include <fbf_driver.h>
19#include <ctx_handler.h>
20#include <fat32.h>
21#include <utils.h>
[396]22#include <vmem.h>
[322]23#include <hard_config.h>
[258]24#include <giet_config.h>
25#include <mapping_info.h>
26
[322]27#if !defined(SEG_BOOT_MAPPING_BASE)
28# error: You must define SEG_BOOT_MAPPING_BASE in the hard_config.h file
29#endif
30
[258]31////////////////////////////////////////////////////////////////////////////
32//    Initialize the syscall vector with syscall handlers
33// Note: This array must be synchronised with the define in file stdio.h
34////////////////////////////////////////////////////////////////////////////
35const void * _syscall_vector[64] = 
36{
[428]37    &_proc_xyp,            /* 0x00 */
[258]38    &_get_proctime,        /* 0x01 */
39    &_tty_write,           /* 0x02 */
40    &_tty_read,            /* 0x03 */
41    &_timer_start,         /* 0x04 */
42    &_timer_stop,          /* 0x05 */
[294]43    &_tty_get_lock,        /* 0x06 */
44    &_tty_release_lock,    /* 0x07 */
[258]45    &_heap_info,           /* 0x08 */
46    &_local_task_id,       /* 0x09 */
47    &_global_task_id,      /* 0x0A */ 
48    &_fb_cma_init,         /* 0x0B */
49    &_fb_cma_write,        /* 0x0C */
50    &_fb_cma_stop,         /* 0x0D */
51    &_task_exit,           /* 0x0E */
52    &_procs_number,        /* 0x0F */
53
54    &_fb_sync_write,       /* 0x10 */
55    &_fb_sync_read,        /* 0x11 */
[267]56    &_thread_id,           /* 0x12 */
[294]57    &_sys_ukn,             /* 0x13 */
[258]58    &_sys_ukn,             /* 0x14 */
59    &_sys_ukn,             /* 0x15 */ 
60    &_sys_ukn,             /* 0x16 */
61    &_sys_ukn,             /* 0x17 */
62    &_sys_ukn,             /* 0x18 */   
[301]63    &_context_switch,      /* 0x19 */
[258]64    &_vobj_get_vbase,      /* 0x1A */
[396]65    &_get_xy_from_ptr,     /* 0x1B */
[258]66    &_nic_cma_start,       /* 0x1C */
67    &_nic_cma_stop,        /* 0x1D */
68    &_nic_sync_read,       /* 0x1E */
69    &_nic_sync_write,      /* 0x1F */
70
71    &_fat_user_open,       /* 0x20 */
72    &_fat_user_read,       /* 0x21 */
73    &_fat_user_write,      /* 0x22 */
74    &_fat_user_lseek,      /* 0x23 */
[260]75    &_fat_fstat,           /* 0x24 */
76    &_fat_close,           /* 0x25 */
[258]77    &_sys_ukn,             /* 0x26 */
78    &_sys_ukn,             /* 0x27 */
79    &_sys_ukn,             /* 0x28 */
80    &_sys_ukn,             /* 0x29 */
81    &_sys_ukn,             /* 0x2A */
82    &_sys_ukn,             /* 0x2B */
83    &_sys_ukn,             /* 0x2C */
84    &_sys_ukn,             /* 0x2D */
85    &_sys_ukn,             /* 0x2E */
86    &_sys_ukn,             /* 0x2F */
87
88    &_sys_ukn,             /* 0x30 */
89    &_sys_ukn,             /* 0x31 */
90    &_sys_ukn,             /* 0x32 */
91    &_sys_ukn,             /* 0x33 */
92    &_sys_ukn,             /* 0x34 */
93    &_sys_ukn,             /* 0x35 */ 
94    &_sys_ukn,             /* 0x36 */
95    &_sys_ukn,             /* 0x37 */
96    &_sys_ukn,             /* 0x38 */   
97    &_sys_ukn,             /* 0x39 */
98    &_sys_ukn,             /* 0x3A */
99    &_sys_ukn,             /* 0x3B */
100    &_sys_ukn,             /* 0x3C */
101    &_sys_ukn,             /* 0x3D */
102    &_sys_ukn,             /* 0x3E */
103    &_sys_ukn,             /* 0x3F */
104};
105
106//////////////////////////////////////////////////////////////////////////////
107// function executed in case of undefined syscall
108//////////////////////////////////////////////////////////////////////////////
109void _sys_ukn() 
110{
[294]111    _printf("\n\n[GIET ERROR] Undefined System Call / EPC = %x\n", _get_epc() );
[258]112    _exit();
113}
114
[428]115//////////////////////////////////////////////////////////////////////////////
116// This function returns the processor (x,y,p) identifiers.
117//////////////////////////////////////////////////////////////////////////////
118void _proc_xyp( unsigned int* x,
119                unsigned int* y,
120                unsigned int* p )
121{
122    unsigned int gpid = _get_procid();  // global processor index from CPO register
123
124    *x = (gpid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1);
125    *y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
126    *p = gpid & ((1<<P_WIDTH)-1);
127}
[258]128////////////////////////////////////////////////////////////////////////////
129// Task suicide... after printing a death message.
130////////////////////////////////////////////////////////////////////////////
[294]131void _task_exit( char* string ) 
[258]132{
[294]133    unsigned int date       = _get_proctime();
[428]134
135    unsigned int gpid       = _get_procid();
136    unsigned int cluster_xy = gpid >> P_WIDTH;
[294]137    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
138    unsigned int x          = cluster_xy >> Y_WIDTH;
[428]139    unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
140
[294]141    unsigned int task_id    = _get_context_slot(CTX_LTID_ID);
[258]142
143    // print death message
[294]144    _printf("\n[GIET] Exit task %d on processor[%d,%d,%d] at cycle %d"
145            "\n       Cause : %s\n\n",
146            task_id, x, y, lpid, date, string );
[258]147
148    // goes to sleeping state
149    _set_context_slot(CTX_RUN_ID, 0);
150
151    // deschedule
152    _context_switch();
153} 
154
155//////////////////////////////////////////////////////////////////////////////
156// returns in buffer argument the number of processors in the cluster
157// specified by the cluster_id argument.
158//////////////////////////////////////////////////////////////////////////////
159unsigned int _procs_number(unsigned int  cluster_id, 
160                           unsigned int* buffer) 
161{
[322]162    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
[258]163    mapping_cluster_t * cluster = _get_cluster_base(header);
164
[263]165    if ( cluster_id < X_SIZE * Y_SIZE ) 
166    {
[258]167        *buffer = cluster[cluster_id].procs;
168        return 0;
169    }
[263]170    else 
171    {
[258]172        return 1;
173    }
174}
175
176/////////////////////////////////////////////////////////////////////////////
177// Returns current task local index.
178/////////////////////////////////////////////////////////////////////////////
179unsigned int _local_task_id()
180{
181    return _get_context_slot(CTX_LTID_ID);
182}
183
184/////////////////////////////////////////////////////////////////////////////
185// Returns current task global index.
186/////////////////////////////////////////////////////////////////////////////
187unsigned int _global_task_id()
188{
189    return _get_context_slot(CTX_GTID_ID);
190}
191
192/////////////////////////////////////////////////////////////////////////////
[267]193// Returns current thread index.
194/////////////////////////////////////////////////////////////////////////////
195unsigned int _thread_id()
196{
197    return _get_context_slot(CTX_TRDID_ID);
198}
199
200/////////////////////////////////////////////////////////////////////////////
[258]201// This function writes in res_vobj a pointer on a vobj
202// identified by the (vspace_name / vobj_name ) couple.
[294]203// returns 0 if success, >0 if not found
[258]204/////////////////////////////////////////////////////////////////////////////
205int _get_vobj( char*             vspace_name, 
206               char*             vobj_name, 
207               mapping_vobj_t**  res_vobj ) 
208{
[322]209    mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
[258]210    mapping_vspace_t * vspace = _get_vspace_base(header);
211    mapping_vobj_t * vobj     = _get_vobj_base(header);
212
213    unsigned int vspace_id;
214    unsigned int vobj_id;
215
216    // scan vspaces
217    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
218    {
219        if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) 
220        {
221            // scan vobjs
222            for (vobj_id = vspace[vspace_id].vobj_offset; 
223                 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 
224                 vobj_id++) 
225            {
226                if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) 
227                {
228                    *res_vobj = &vobj[vobj_id];
229                    return 0;
230                }
231            } 
232        }
233    } 
[294]234    return 1;    //not found
[258]235}
236
237/////////////////////////////////////////////////////////////////////////////
[322]238// This function writes in vobj_vbase the virtual base address of a vobj
[258]239// identified by the (vspace_name / vobj_name ) couple.
[294]240// returns 0 if success, >0 if not found
[258]241/////////////////////////////////////////////////////////////////////////////
242unsigned int _vobj_get_vbase( char*         vspace_name,
243                              char*         vobj_name,
[294]244                              unsigned int* vobj_vbase ) 
[258]245{
246    mapping_vobj_t* res_vobj;
247    unsigned int    ret;
[294]248    if ((ret = _get_vobj(vspace_name, vobj_name, &res_vobj))) 
[258]249    {
250        return ret;
251    }
[410]252    *vobj_vbase = res_vobj->vbase;
[258]253    return 0;
254}
255
256/////////////////////////////////////////////////////////////////////////////
[294]257// This function writes in vobj_length the length of a vobj
[258]258// identified by the (vspace_name / vobj_name ) couple.
[294]259// returns 0 if success, >0 if not found
[258]260/////////////////////////////////////////////////////////////////////////////
261unsigned int _vobj_get_length( char*         vspace_name, 
262                               char*         vobj_name,
263                               unsigned int* vobj_length ) 
264{
265    mapping_vobj_t * res_vobj;
266    unsigned int ret;
[294]267    if ((ret = _get_vobj(vspace_name, vobj_name, &res_vobj))) 
[258]268    {
269        return ret;
270    }
271    *vobj_length = res_vobj->length;
272    return 0;
273}
274
[396]275/////////////////////////////////////////////////////////////////////////////
276// This function returns in the (x,y) arguments the coordinates of the
277// where is mapped the ptr virtual address. It use the _get_context_slot()
278// function to get the calling task page table, and uses the _v2p_translate()
279// function to obtain the physical address.
280// returns 0 if success, > 0 if ptr not mapped in the calling task vspace.
281/////////////////////////////////////////////////////////////////////////////
282
283unsigned int _get_xy_from_ptr( void*         ptr,
284                               unsigned int* px,
285                               unsigned int* py )
286{
287    unsigned int ret;
288    unsigned int ppn;
289    unsigned int flags;
290    unsigned int vpn  = (((unsigned int)ptr)>>12);
291   
292    // get the page table pointer
293    page_table_t* pt = (page_table_t*)_get_context_slot( CTX_PTAB_ID ); 
294
295    // compute the physical address
296    if ( (ret = _v2p_translate( pt, vpn, &ppn, &flags )) )
297    {
298        return ret;
299    }
300
301    *px = (ppn>>24) & 0xF;
302    *py = (ppn>>20) & 0xF;
303    return 0;
304}
305
[294]306////////////////////////////////////////////////////////////////////////////
307// This sysrem function deschedule the requestint task.
308// It mask interrupts before calling the _ctx_switch, and restore it
309// when the task is rescheduled.
310////////////////////////////////////////////////////////////////////////////
[258]311void _context_switch() 
312{
[294]313    unsigned int save_sr;
314
315    _it_disable( &save_sr );
[258]316    _ctx_switch();
[294]317    _it_restore( &save_sr );
[258]318}
319
320// Local Variables:
321// tab-width: 4
322// c-basic-offset: 4
323// c-file-offsets:((innamespace . 0)(inline-open . 0))
324// indent-tabs-mode: nil
325// End:
326// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
327
Note: See TracBrowser for help on using the repository browser.