Changeset 709


Ignore:
Timestamp:
Oct 1, 2015, 4:20:46 PM (9 years ago)
Author:
alain
Message:

Major release: Change the task model to implement the POSIX threads API.

  • The shell "exec" and "kill" commands can be used to activate/de-activate the applications.
  • The "pause", "resume", and "context" commands can be used to stop, restart, a single thtead or to display the thread context.

This version has been tested on the following multi-threaded applications,
that have been modified to use the POSIX threads:

  • classif
  • convol
  • transpose
  • gameoflife
  • raycast
Location:
soft/giet_vm
Files:
2 deleted
38 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/Makefile

    r701 r709  
    107107                build/libs/string.o            \
    108108                build/libs/user_barrier.o      \
    109                 build/libs/user_lock.o         \
    110                 build/libs/user_sqt_lock.o     
     109                build/libs/user_lock.o
    111110
    112111### Objects to be linked for the math library
  • soft/giet_vm/giet_boot/boot.c

    r695 r709  
    2424//    - the "map.bin" file contains the hardware architecture description,
    2525//      the set of user applications that will be mapped on the architecture,
    26 //      and the mapping directives. The mapping includes the placement of tasks
     26//      and the mapping directives. The mapping includes the placement of threads
    2727//      on processors, and the placement of virtual segments on the physical
    28 //      segments. It must be stored in the the seg_boot_mapping segment
     28//      segments. It is stored in the the seg_boot_mapping segment
    2929//      (at address SEG_BOOT_MAPPING_BASE defined in hard_config.h file).
    3030//    - the "kernel.elf" file contains the kernel binary code and data.
     
    3737//      of the software objects (vsegs) on the physical memory banks (psegs).
    3838//    The max number of vspaces (GIET_NB_VSPACE_MAX) is a configuration parameter.
    39 //    The page table are statically build in the boot phase, and they do not
    40 //    change during execution. For each application, the page tables are replicated
    41 //    in all clusters.
     39//    The page tables are statically build in the boot phase, and they do not
     40//    change during execution.
     41//    For each application, the page tables are replicated in all clusters.
    4242//    The GIET_VM uses both small pages (4 Kbytes), and big pages (2 Mbytes).
    4343//    Each page table (one page table per virtual space) is monolithic, and
     
    5050//
    5151// 3) The Giet-VM implement one private scheduler per processor.
    52 //    For each application, the tasks are statically allocated to processors
    53 //    and there is no task migration during execution.
    54 //    Each sheduler occupies 8K bytes, and contains up to 14 task contexts
    55 //    The task context [13] is reserved for the "idle" task that does nothing, and
    56 //    is launched by the scheduler when there is no other runable task.
     52//    For each application, the threads are statically allocated to processors
     53//    and there is no thread migration during execution.
     54//    Each sheduler occupies 8K bytes, and contains up to 14 thread contexts
     55//    The thread context [13] is reserved for the "idle" thread that does nothing,
     56//    and is launched by the scheduler when there is no other runable thread.
    5757///////////////////////////////////////////////////////////////////////////////////
    5858// Implementation Notes:
     
    167167unsigned int        _hba_boot_mode = 1;
    168168
     169// required for concurrent PTAB building
    169170__attribute__((section(".kdata")))
    170171spin_lock_t         _ptabs_spin_lock[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE];
     
    983984////////////////////////////////////////////////////////////////////////////////////
    984985// This function is executed in parallel by all processors P[x][y][0].
    985 // It initialises all schedulers in cluster [x][y]. The MMU must be activated.
     986// P[x][y][0] initialises all schedulers in cluster[x][y]. The MMU must be activated.
    986987// It is split in two phases separated by a synchronisation barrier.
    987 // - In Step 1, it initialises the _schedulers[x][y][l] pointers array, the
    988 //              idle_task context, the  HWI / PTI / WTI interrupt vectors,
    989 //              and the CU HWI / PTI / WTI masks.
    990 // - In Step 2, it scan all tasks in all vspaces to complete the tasks contexts,
     988// - In Step 1, it initialises the _schedulers[x][y][p] pointers array, the
     989//              idle_thread context, the  HWI / PTI / WTI interrupt vectors,
     990//              and the XCU HWI / PTI / WTI masks.
     991// - In Step 2, it scan all threads in all vspaces to complete the threads contexts,
    991992//              initialisation as specified in the mapping_info data structure,
    992993//              and set the CP0_SCHED register.
     
    9991000    mapping_vspace_t*    vspace  = _get_vspace_base(header);
    10001001    mapping_vseg_t*      vseg    = _get_vseg_base(header);
    1001     mapping_task_t*      task    = _get_task_base(header);
     1002    mapping_thread_t*    thread  = _get_thread_base(header);
    10021003    mapping_periph_t*    periph  = _get_periph_base(header);
    10031004    mapping_irq_t*       irq     = _get_irq_base(header);
     
    10071008    unsigned int         vspace_id;
    10081009    unsigned int         vseg_id;
    1009     unsigned int         task_id;
     1010    unsigned int         thread_id;
    10101011
    10111012    unsigned int         sched_vbase;          // schedulers array vbase address
     
    10261027    ////////////////////////////////////////////////////////////////////////////////
    10271028    // Step 1 : - initialize the schedulers[] array of pointers,
    1028     //          - initialize the "tasks" and "current variables.
    1029     //          - initialise the idle task context.
     1029    //          - initialize the "threads" and "current variables.
     1030    //          - initialise the idle_thread context.
    10301031    //          - initialize the HWI, PTI and WTI interrupt vectors.
    10311032    //          - initialize the XCU masks for HWI / WTI / PTI interrupts.
     
    10561057        _schedulers[x][y][lpid] = psched;
    10571058
    1058         // initialise the "tasks" and "current" variables default values
    1059         psched->tasks  = 0;
    1060         psched->current = IDLE_TASK_INDEX;
     1059        // initialise the "threads" and "current" variables default values
     1060        psched->threads = 0;
     1061        psched->current = IDLE_THREAD_INDEX;
    10611062
    10621063        // set default values for HWI / PTI / SWI vectors (valid bit = 0)
     
    10691070        }
    10701071
    1071         // initializes the idle_task context:
    1072         // - the SR slot is 0xFF03 because this task run in kernel mode.
     1072        // initializes the idle_thread context:
     1073        // - the SR slot is 0xFF03 because this thread run in kernel mode.
    10731074        // - it uses the page table of vspace[0]
    1074         // - it uses the kernel TTY terminal
     1075        // - it uses the kernel TTY0 terminal
    10751076        // - slots containing addresses (SP,RA,EPC) are initialised by kernel_init()
    1076 
    1077         psched->context[IDLE_TASK_INDEX][CTX_CR_ID]    = 0;
    1078         psched->context[IDLE_TASK_INDEX][CTX_SR_ID]    = 0xFF03;
    1079         psched->context[IDLE_TASK_INDEX][CTX_PTPR_ID]  = _ptabs_paddr[0][x][y]>>13;
    1080         psched->context[IDLE_TASK_INDEX][CTX_PTAB_ID]  = _ptabs_vaddr[0][x][y];
    1081         psched->context[IDLE_TASK_INDEX][CTX_TTY_ID]   = 0;
    1082         psched->context[IDLE_TASK_INDEX][CTX_LTID_ID]  = IDLE_TASK_INDEX;
    1083         psched->context[IDLE_TASK_INDEX][CTX_VSID_ID]  = 0;
    1084         psched->context[IDLE_TASK_INDEX][CTX_NORUN_ID] = 0;
    1085         psched->context[IDLE_TASK_INDEX][CTX_SIG_ID]   = 0;
     1077        // - It is always executable (NORUN == 0)
     1078
     1079        psched->context[IDLE_THREAD_INDEX].slot[CTX_CR_ID]    = 0;
     1080        psched->context[IDLE_THREAD_INDEX].slot[CTX_SR_ID]    = 0xFF03;
     1081        psched->context[IDLE_THREAD_INDEX].slot[CTX_PTPR_ID]  = _ptabs_paddr[0][x][y]>>13;
     1082        psched->context[IDLE_THREAD_INDEX].slot[CTX_PTAB_ID]  = _ptabs_vaddr[0][x][y];
     1083        psched->context[IDLE_THREAD_INDEX].slot[CTX_TTY_ID]   = 0;
     1084        psched->context[IDLE_THREAD_INDEX].slot[CTX_LTID_ID]  = IDLE_THREAD_INDEX;
     1085        psched->context[IDLE_THREAD_INDEX].slot[CTX_VSID_ID]  = 0;
     1086        psched->context[IDLE_THREAD_INDEX].slot[CTX_NORUN_ID] = 0;
     1087        psched->context[IDLE_THREAD_INDEX].slot[CTX_SIGS_ID]  = 0;
     1088        psched->context[IDLE_THREAD_INDEX].slot[CTX_LOCKS_ID] = 0;
    10861089    }
    10871090
     
    12131216
    12141217    ///////////////////////////////////////////////////////////////////////////////
    1215     // Step 2 : Initialise the tasks context. The context of task placed
     1218    // Step 2 : Initialise the threads context. The context of a thread placed
    12161219    //          on  processor P must be stored in the scheduler of P.
    1217     //          This require two nested loops: loop on the tasks, and loop
    1218     //          on the local processors. We complete the scheduler when the
    1219     //          required placement fit one local processor.
     1220    //          For each vspace, this require two nested loops: loop on the threads,
     1221    //          and loop on the local processors in cluster[x,y].
     1222    //          We complete the scheduler when the required placement matches
     1223    //          the local processor.
    12201224    ///////////////////////////////////////////////////////////////////////////////
    12211225
     
    12261230        _set_mmu_ptpr( (unsigned int)(_ptabs_paddr[vspace_id][x][y] >> 13) );
    12271231
    1228         // ctx_norun depends on the vspace active field
    1229         unsigned int ctx_norun = (vspace[vspace_id].active == 0);
    1230 
    1231         // loop on the tasks in vspace (task_id is the global index in mapping)
    1232         for (task_id = vspace[vspace_id].task_offset;
    1233              task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
    1234              task_id++)
    1235         {
    1236             // get the required task placement coordinates [x,y,p]
    1237             unsigned int req_x      = cluster[task[task_id].clusterid].x;
    1238             unsigned int req_y      = cluster[task[task_id].clusterid].y;
    1239             unsigned int req_p      = task[task_id].proclocid;                 
     1232        // loop on the threads in vspace (thread_id is the global index in mapping)
     1233        for (thread_id = vspace[vspace_id].thread_offset;
     1234             thread_id < (vspace[vspace_id].thread_offset + vspace[vspace_id].threads);
     1235             thread_id++)
     1236        {
     1237            // get the required thread placement coordinates [x,y,p]
     1238            unsigned int req_x      = cluster[thread[thread_id].clusterid].x;
     1239            unsigned int req_y      = cluster[thread[thread_id].clusterid].y;
     1240            unsigned int req_p      = thread[thread_id].proclocid;                 
     1241
     1242            // ctx_norun : two conditions to activate a thread
     1243            // - The vspace.active flag is set in the mapping
     1244            // - The thread.is_main flag is set in the mapping
     1245            unsigned int ctx_norun = (unsigned int)(vspace[vspace_id].active == 0) |
     1246                                     (unsigned int)(thread[thread_id].is_main == 0);
    12401247
    12411248            // ctx_ptpr : page table physical base address (shifted by 13 bit)
     
    12461253
    12471254            // ctx_entry : Get the virtual address of the memory location containing
    1248             // the task entry point : the start_vector is stored by GCC in the
    1249             // seg_data segment, and we must wait the .elf loading to get
     1255            // the thread entry point : the start_vector is stored by GCC in the
     1256            // seg_data segment, and we must wait the application.elf loading to get
    12501257            // the entry point value...
    12511258            vseg_id = vspace[vspace_id].start_vseg_id;     
    1252             unsigned int ctx_entry = vseg[vseg_id].vbase + (task[task_id].startid)*4;
     1259            unsigned int ctx_entry = vseg[vseg_id].vbase + (thread[thread_id].startid)*4;
    12531260
    12541261            // ctx_sp :  Get the vseg containing the stack
    1255             vseg_id = task[task_id].stack_vseg_id;
    1256             unsigned int ctx_sp = vseg[vseg_id].vbase + vseg[vseg_id].length;
    1257 
    1258             // get vspace thread index
    1259             unsigned int thread_id = task[task_id].trdid;
     1262            // allocate 16 slots (64 bytes) for possible arguments.
     1263            vseg_id = thread[thread_id].stack_vseg_id;
     1264            unsigned int ctx_sp = vseg[vseg_id].vbase + vseg[vseg_id].length - 64;
    12601265
    12611266            // loop on the local processors
     
    12671272                    psched = _schedulers[x][y][lpid];
    12681273
    1269                     // get local task index in scheduler
    1270                     unsigned int ltid = psched->tasks;
    1271 
    1272                     // update the "tasks" field in scheduler:
    1273                     psched->tasks   = ltid + 1;
    1274 
    1275                     // initializes the task context
    1276                     psched->context[ltid][CTX_CR_ID]     = 0;
    1277                     psched->context[ltid][CTX_SR_ID]     = GIET_SR_INIT_VALUE;
    1278                     psched->context[ltid][CTX_SP_ID]     = ctx_sp;
    1279                     psched->context[ltid][CTX_EPC_ID]    = ctx_entry;
    1280                     psched->context[ltid][CTX_ENTRY_ID]  = ctx_entry;
    1281                     psched->context[ltid][CTX_PTPR_ID]   = ctx_ptpr;
    1282                     psched->context[ltid][CTX_PTAB_ID]   = ctx_ptab;
    1283                     psched->context[ltid][CTX_LTID_ID]   = ltid;
    1284                     psched->context[ltid][CTX_GTID_ID]   = task_id;
    1285                     psched->context[ltid][CTX_TRDID_ID]  = thread_id;
    1286                     psched->context[ltid][CTX_VSID_ID]   = vspace_id;
    1287                     psched->context[ltid][CTX_NORUN_ID]  = ctx_norun;
    1288                     psched->context[ltid][CTX_SIG_ID]    = 0;
    1289 
    1290                     psched->context[ltid][CTX_TTY_ID]    = 0xFFFFFFFF;
    1291                     psched->context[ltid][CTX_CMA_FB_ID] = 0xFFFFFFFF;
    1292                     psched->context[ltid][CTX_CMA_RX_ID] = 0xFFFFFFFF;
    1293                     psched->context[ltid][CTX_CMA_TX_ID] = 0xFFFFFFFF;
    1294                     psched->context[ltid][CTX_NIC_RX_ID] = 0xFFFFFFFF;
    1295                     psched->context[ltid][CTX_NIC_TX_ID] = 0xFFFFFFFF;
    1296                     psched->context[ltid][CTX_TIM_ID]    = 0xFFFFFFFF;
    1297                     psched->context[ltid][CTX_HBA_ID]    = 0xFFFFFFFF;
    1298 
    1299                     // update task ltid field in the mapping
    1300                     task[task_id].ltid = ltid;
     1274                    // ltid : compute local thread index in scheduler
     1275                    unsigned int ltid = psched->threads;
     1276
     1277                    // update the threads field in scheduler:
     1278                    psched->threads   = ltid + 1;
     1279
     1280                    // ctx_trd_id : compute pthread global identifier
     1281                    unsigned int ctx_trdid = x << 24 | y<<16 | lpid<<8 | ltid;
     1282
     1283                    // initializes the thread context
     1284                    psched->context[ltid].slot[CTX_CR_ID]     = 0;
     1285                    psched->context[ltid].slot[CTX_SR_ID]     = GIET_SR_INIT_VALUE;
     1286                    psched->context[ltid].slot[CTX_SP_ID]     = ctx_sp;
     1287                    psched->context[ltid].slot[CTX_EPC_ID]    = ctx_entry;
     1288                    psched->context[ltid].slot[CTX_ENTRY_ID]  = ctx_entry;
     1289                    psched->context[ltid].slot[CTX_PTPR_ID]   = ctx_ptpr;
     1290                    psched->context[ltid].slot[CTX_PTAB_ID]   = ctx_ptab;
     1291                    psched->context[ltid].slot[CTX_LTID_ID]   = ltid;
     1292                    psched->context[ltid].slot[CTX_TRDID_ID]  = ctx_trdid;
     1293                    psched->context[ltid].slot[CTX_VSID_ID]   = vspace_id;
     1294                    psched->context[ltid].slot[CTX_NORUN_ID]  = ctx_norun;
     1295                    psched->context[ltid].slot[CTX_SIGS_ID]   = 0;
     1296                    psched->context[ltid].slot[CTX_LOCKS_ID]  = 0;
     1297
     1298                    psched->context[ltid].slot[CTX_TTY_ID]    = 0xFFFFFFFF;
     1299                    psched->context[ltid].slot[CTX_CMA_FB_ID] = 0xFFFFFFFF;
     1300                    psched->context[ltid].slot[CTX_CMA_RX_ID] = 0xFFFFFFFF;
     1301                    psched->context[ltid].slot[CTX_CMA_TX_ID] = 0xFFFFFFFF;
     1302                    psched->context[ltid].slot[CTX_NIC_RX_ID] = 0xFFFFFFFF;
     1303                    psched->context[ltid].slot[CTX_NIC_TX_ID] = 0xFFFFFFFF;
     1304                    psched->context[ltid].slot[CTX_TIM_ID]    = 0xFFFFFFFF;
     1305                    psched->context[ltid].slot[CTX_HBA_ID]    = 0xFFFFFFFF;
     1306
     1307                    // update thread ltid field in the mapping
     1308                    thread[thread_id].ltid = ltid;
    13011309
    13021310#if BOOT_DEBUG_SCHED
    1303 _printf("\nTask %s in vspace %s allocated to P[%d,%d,%d]\n"
     1311_printf("\nThread %s in vspace %s allocated to P[%d,%d,%d]\n"
    13041312        " - ctx[LTID]  = %d\n"
     1313        " - ctx[TRDID] = %d\n"
    13051314        " - ctx[SR]    = %x\n"
    13061315        " - ctx[SP]    = %x\n"
     
    13091318        " - ctx[PTAB]  = %x\n"
    13101319        " - ctx[VSID]  = %d\n"
    1311         " - ctx[TRDID] = %d\n"
    13121320        " - ctx[NORUN] = %x\n"
    13131321        " - ctx[SIG]   = %x\n",
    1314         task[task_id].name,
     1322        thread[thread_id].name,
    13151323        vspace[vspace_id].name,
    13161324        x, y, lpid,
    1317         psched->context[ltid][CTX_LTID_ID],
    1318         psched->context[ltid][CTX_SR_ID],
    1319         psched->context[ltid][CTX_SP_ID],
    1320         psched->context[ltid][CTX_ENTRY_ID],
    1321         psched->context[ltid][CTX_PTPR_ID],
    1322         psched->context[ltid][CTX_PTAB_ID],
    1323         psched->context[ltid][CTX_VSID_ID],
    1324         psched->context[ltid][CTX_TRDID_ID],
    1325         psched->context[ltid][CTX_NORUN_ID],
    1326         psched->context[ltid][CTX_SIG_ID] );
     1325        psched->context[ltid].slot[CTX_LTID_ID],
     1326        psched->context[ltid].slot[CTX_TRDID_ID],
     1327        psched->context[ltid].slot[CTX_SR_ID],
     1328        psched->context[ltid].slot[CTX_SP_ID],
     1329        psched->context[ltid].slot[CTX_ENTRY_ID],
     1330        psched->context[ltid].slot[CTX_PTPR_ID],
     1331        psched->context[ltid].slot[CTX_PTAB_ID],
     1332        psched->context[ltid].slot[CTX_VSID_ID],
     1333        psched->context[ltid].slot[CTX_NORUN_ID],
     1334        psched->context[ltid].slot[CTX_SIG_ID] );
    13271335#endif
    13281336                } // end if FIT
    13291337            } // end for loop on local procs
    1330         } // end loop on tasks
     1338        } // end loop on threads
    13311339    } // end loop on vspaces
    13321340} // end boot_scheduler_init()
     
    15441552                        " check that all global variables are in data segment\n",
    15451553                        seg_vaddr, pathname , seg_memsz , seg_filesz );
    1546                 _exit();
     1554                 _exit();
    15471555            }
    15481556
  • soft/giet_vm/giet_common/kernel_locks.c

    r632 r709  
    7070        : "r" (ptr), "r" (mask)
    7171        : "$10", "$11", "$12", "memory" );
     72}
     73
     74/////////////////////////////////////////////////////
     75unsigned int _atomic_test_and_set( unsigned int* ptr,
     76                                   unsigned int  value )
     77{
     78    unsigned int ret = 1;
     79
     80    asm volatile (
     81        "ori  %0,    $0,     1         \n"   /* default : ret <= 1       */
     82        "move $10,   %1                \n"   /* $10 <= ptr               */
     83        "move $11,   %2                \n"   /* $11 <= value             */
     84        "ll   $12,   0($10)            \n"   /* $12 <= *ptr              */
     85        "bne  $12,   $0,     1515f     \n"   /* return 1 if non zero     */
     86        "sc   $11,   0($10)            \n"   /* *ptr <= $12              */
     87        "beqz $11,           1515f     \n"   /* return 1 if failure      */
     88        "ori  %0,    $0,     0         \n"   /* success : ret <= 0       */
     89        "1515:                         \n"   
     90        : "=r" (ret)
     91        : "r" (ptr), "r" (value)
     92        : "$10", "$11", "$12", "memory" );
     93
     94    return ret;
    7295}
    7396
  • soft/giet_vm/giet_common/kernel_locks.h

    r632 r709  
    2020
    2121extern unsigned int _atomic_increment( unsigned int* ptr,
    22                                        int  increment );
     22                                       int           increment );
    2323
    2424extern void _atomic_or( unsigned int* ptr,
     
    2727extern void _atomic_and( unsigned int* ptr,
    2828                         unsigned int  mask );
     29
     30extern unsigned int _atomic_test_and_set( unsigned int* ptr,
     31                                          unsigned int  value );
    2932
    3033//////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/giet_common/mips32_registers.h

    r399 r709  
    11/********************************************************************************/
    2 /*    File : mips32_registers.h                        */
    3 /*    Author : Alain Greiner                            */
    4 /*    Date : 26/03/2012                            */
     2/*    File : mips32_registers.h                                                 */
     3/*    Author : Alain Greiner                                                    */
     4/*    Date : 26/03/2012                                                         */
    55/********************************************************************************/
    6 /*     We define mnemonics for MIPS32 registers                          */
     6/*     We define mnemonics for MIPS32 registers                                 */
    77/********************************************************************************/
    88
  • soft/giet_vm/giet_common/tty0.c

    r594 r709  
    1212#include <stdarg.h>
    1313#include <tty_driver.h>
     14#include <ctx_handler.h>
    1415#include <utils.h>
    1516#include <kernel_locks.h>
     
    3031spin_lock_t          _tty0_spin_lock  __attribute__((aligned(64)));
    3132
    32 //////////////////////////////////////////////
    33 unsigned int _tty0_write( char*        buffer,
    34                           unsigned int nbytes )
     33/////////////////////////////////////////////////////
     34unsigned int _tty_channel_write( unsigned int channel,
     35                                 char*        buffer,
     36                                 unsigned int nbytes )
    3537{
    3638    unsigned int n;
     
    4042    {
    4143        // test TTY_TX buffer full
    42         if ( (_tty_get_register( 0, TTY_STATUS ) & 0x2) ) // buffer full
     44        if ( (_tty_get_register( channel , TTY_STATUS ) & 0x2) ) // buffer full
    4345        {
    4446            // retry if full
    4547            for( k = 0 ; k < 10000 ; k++ )
    4648            {
    47                 if ( (_tty_get_register( 0, TTY_STATUS ) & 0x2) == 0) break;
     49                if ( (_tty_get_register( channel , TTY_STATUS ) & 0x2) == 0) break;
    4850            }
    4951            // return error if full after 10000 retry
     
    5254
    5355        // write one byte
    54         if (buffer[n] == '\n') _tty_set_register( 0, TTY_WRITE, (unsigned int)'\r' );
    55         _tty_set_register( 0, TTY_WRITE, (unsigned int)buffer[n] );
     56        if (buffer[n] == '\n') _tty_set_register( channel, TTY_WRITE, (unsigned int)'\r' );
     57        _tty_set_register( channel, TTY_WRITE, (unsigned int)buffer[n] );
    5658    }
    5759    return 0;
     
    6567    while ( string[n] > 0 ) n++;
    6668
    67     _tty0_write( string, n );
     69    _tty_channel_write( 0, string, n );
    6870}
    6971
     
    8486        val = val >> 4;
    8587    }
    86     _tty0_write( buf, 10 );
     88    _tty_channel_write( 0, buf, 10 );
    8789}
    8890
     
    102104        val = val >> 4;
    103105    }
    104     _tty0_write( buf, 18 );
     106    _tty_channel_write( 0, buf, 18 );
    105107}
    106108
     
    126128        val /= 10;
    127129    }
    128     _tty0_write( &buf[first], 10 - first );
     130    _tty_channel_write( 0, &buf[first], 10 - first );
    129131}
    130132
     
    140142
    141143//////////////////////////////////////////////////////////
    142 static void _kernel_printf( char * format, va_list* args )
     144static void _kernel_printf( unsigned int channel,
     145                            char *       format,
     146                            va_list*     args )
    143147{
    144148
     
    151155        if (i)
    152156        {
    153             if ( _tty0_write( format, i ) ) goto return_error;
     157            if ( _tty_channel_write( channel, format, i ) ) goto return_error;
    154158            format += i;
    155159        }
     
    188192                {
    189193                    val = -val;
    190                     if ( _tty0_write( "-" , 1 ) ) goto return_error;
     194                    if ( _tty_channel_write( channel, "-" , 1 ) ) goto return_error;
    191195                }
    192196                for(i = 0; i < 10; i++)
     
    214218            {
    215219                unsigned int val = va_arg( *args , unsigned int );
    216                 if ( _tty0_write( "0x" , 2 ) ) goto return_error;
     220                if ( _tty_channel_write( channel, "0x" , 2 ) ) goto return_error;
    217221                for(i = 0; i < 8; i++)
    218222                {
     
    227231            {
    228232                unsigned int val = va_arg( *args , unsigned int );
    229                 if ( _tty0_write( "0x" , 2 ) ) goto return_error;
     233                if ( _tty_channel_write( channel, "0x" , 2 ) ) goto return_error;
    230234                for(i = 0; i < 8; i++)
    231235                {
     
    240244            {
    241245                unsigned long long val = va_arg( *args , unsigned long long );
    242                 if ( _tty0_write( "0x" , 2 ) ) goto return_error;
     246                if ( _tty_channel_write( channel, "0x" , 2 ) ) goto return_error;
    243247                for(i = 0; i < 16; i++)
    244248                {
     
    264268        }
    265269
    266         if ( _tty0_write( pbuf, len ) ) goto return_error;
     270        if ( _tty_channel_write( channel, pbuf, len ) ) goto return_error;
    267271       
    268272        goto printf_text;
     
    284288        _putd( lpid );
    285289        _puts("]\n");
    286 
    287290        _exit();
    288291    }
     
    294297    va_list   args;
    295298
     299    // call kernel_printf
    296300    va_start( args , format );
    297     _kernel_printf( format , &args );
     301    _kernel_printf( 0, format , &args );
    298302    va_end( args );
    299303}
     304
    300305////////////////////////////////
    301306void _printf( char* format, ...)
     
    309314    else                   _sqt_lock_acquire( &_tty0_sqt_lock );
    310315
     316    // call kernel_printf
    311317    va_start( args , format );
    312     _kernel_printf( format , &args );
     318    _kernel_printf( 0, format , &args );
    313319    va_end( args );
    314320
     
    318324    _it_restore( &save_sr );
    319325}
     326
     327/////////////////////////////////////
     328void _user_printf( char* format, ...)
     329{
     330    va_list   args;
     331
     332    // get calling thread TYY channel
     333    unsigned int channel = _get_context_slot( CTX_TTY_ID );
     334    if( channel >= NB_TTY_CHANNELS )
     335    {
     336        _puts("\n[GIET ERROR] in _user_printf() : no TTY allocated for thread ");
     337        _putx( _get_thread_trdid() );
     338        _puts("\n");
     339        _exit();
     340    }
     341
     342    // call kernel_printf
     343    va_start( args , format );
     344    _kernel_printf( channel, format , &args );
     345    va_end( args );
     346}
     347
    320348
    321349
  • soft/giet_vm/giet_common/tty0.h

    r466 r709  
    1414
    1515///////////////////////////////////////////////////////////////////////////////////
    16 //       Access functions to kernel terminal TTY0
     16//       Access functions to kernel terminal TTY0 (or calling thread TTY)
    1717///////////////////////////////////////////////////////////////////////////////////
    1818
     
    2727extern void         _getc( char* byte );       
    2828
     29extern void         _printf( char* format, ... );
     30
    2931extern void         _nolock_printf( char* format, ... );
    3032
    31 extern void         _printf( char* format, ... );
     33extern void         _user_printf( char* format, ... );
    3234
    3335#endif
  • soft/giet_vm/giet_common/utils.c

    r618 r709  
    1616#include <ctx_handler.h>
    1717
    18 // This variable is allocated in the boot.c file or in kernel_init.c file
    19 extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
     18// This variable is allocated in boot.c file or in kernel_init.c file
     19extern static_scheduler_t*  _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
    2020
    2121///////////////////////////////////////////////////////////////////////////
     
    2323///////////////////////////////////////////////////////////////////////////
    2424
    25 /////////////////////////
    26 unsigned int _get_sched()
     25////////////////////////////////
     26static_scheduler_t* _get_sched()
    2727{
    2828    unsigned int ret;
    2929    asm volatile( "mfc0      %0,     $4,2    \n"
    3030                  : "=r"(ret) );
    31     return ret;
     31
     32    return (static_scheduler_t*)ret;
    3233}
    3334///////////////////////
     
    411412
    412413////////////////////////////////////////////////////////////////////////////
    413 //           Scheduler and tasks context access functions
     414//           Scheduler and threads context access functions
    414415////////////////////////////////////////////////////////////////////////////
    415416
    416417
    417 ///////////////////////////////////
    418 unsigned int _get_current_task_id()
    419 {
    420     static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
    421     return (unsigned int) (psched->current);
     418///////////////////////////////
     419unsigned int _get_thread_ltid()
     420{
     421    static_scheduler_t* psched = (static_scheduler_t *) _get_sched();
     422    return psched->current;
     423}
     424
     425////////////////////////////////
     426unsigned int _get_thread_trdid()
     427{
     428    static_scheduler_t* psched  = (static_scheduler_t *) _get_sched();
     429    unsigned int        current = psched->current;
     430    return psched->context[current].slot[CTX_TRDID_ID];
     431}
     432
     433//////////////////////////////////////////////
     434unsigned int _get_thread_slot( unsigned int x,
     435                               unsigned int y,
     436                               unsigned int p,
     437                               unsigned int ltid,
     438                               unsigned int slotid )
     439{
     440    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
     441    return psched->context[ltid].slot[slotid];
     442}
     443
     444//////////////////////////////////////
     445void _set_thread_slot( unsigned int x,
     446                       unsigned int y,
     447                       unsigned int p,
     448                       unsigned int ltid,
     449                       unsigned int slotid,
     450                       unsigned int value )
     451{
     452    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
     453    psched->context[ltid].slot[slotid] = value;
     454}
     455
     456/////////////////////////////////////////////////////
     457unsigned int _get_context_slot( unsigned int slotid )
     458{
     459    static_scheduler_t* psched  = (static_scheduler_t*)_get_sched();
     460    unsigned int        ltid    = psched->current;
     461    return psched->context[ltid].slot[slotid];
    422462}
    423463
    424464////////////////////////////////////////////
    425 unsigned int _get_task_slot( unsigned int x,
    426                              unsigned int y,
    427                              unsigned int p,
    428                              unsigned int ltid,
    429                              unsigned int slot )
    430 {
    431     static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
    432     return psched->context[ltid][slot];
    433 }
    434 
    435 ////////////////////////////////////
    436 void _set_task_slot( unsigned int x,
    437                      unsigned int y,
    438                      unsigned int p,
    439                      unsigned int ltid,
    440                      unsigned int slot,
    441                      unsigned int value )
    442 {
    443     static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
    444     psched->context[ltid][slot] = value;
    445 }
    446 
    447 ///////////////////////////////////////////////////
    448 unsigned int _get_context_slot( unsigned int slot )
     465void _set_context_slot( unsigned int slotid,
     466                        unsigned int value )
    449467{
    450468    static_scheduler_t* psched  = (static_scheduler_t*)_get_sched();
    451     unsigned int        task_id = psched->current;
    452     return psched->context[task_id][slot];
    453 }
    454 
    455 ///////////////////////////////////////////
    456 void _set_context_slot( unsigned int slot,
    457                        unsigned int value )
    458 {
    459     static_scheduler_t* psched  = (static_scheduler_t*)_get_sched();
    460     unsigned int        task_id = psched->current;
    461     psched->context[task_id][slot] = value;
     469    unsigned int        ltid    = psched->current;
     470    psched->context[ltid].slot[slotid] = value;
    462471}
    463472
     
    496505            MAPPING_VSPACE_SIZE * header->vspaces);
    497506}
    498 //////////////////////////////////////////////////////////
    499 mapping_task_t * _get_task_base(mapping_header_t * header)
    500 {
    501     return (mapping_task_t *) ((char *) header +
     507//////////////////////////////////////////////////////////////
     508mapping_thread_t * _get_thread_base(mapping_header_t * header)
     509{
     510    return (mapping_thread_t *) ((char *) header +
    502511            MAPPING_HEADER_SIZE +
    503512            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
     
    515524            MAPPING_VSPACE_SIZE * header->vspaces +
    516525            MAPPING_VSEG_SIZE * header->vsegs +
    517             MAPPING_TASK_SIZE * header->tasks);
     526            MAPPING_THREAD_SIZE * header->threads);
    518527}
    519528///////////////////////////////////////////////////////
     
    526535            MAPPING_VSPACE_SIZE * header->vspaces +
    527536            MAPPING_VSEG_SIZE * header->vsegs +
    528             MAPPING_TASK_SIZE * header->tasks +
     537            MAPPING_THREAD_SIZE * header->threads +
    529538            MAPPING_PROC_SIZE * header->procs);
    530539}
     
    538547            MAPPING_VSPACE_SIZE * header->vspaces +
    539548            MAPPING_VSEG_SIZE * header->vsegs +
    540             MAPPING_TASK_SIZE * header->tasks +
     549            MAPPING_THREAD_SIZE * header->threads +
    541550            MAPPING_PROC_SIZE * header->procs +
    542551            MAPPING_IRQ_SIZE * header->irqs);
  • soft/giet_vm/giet_common/utils.h

    r618 r709  
    1414
    1515#include <mapping_info.h>
     16#include <ctx_handler.h>
    1617
    1718//////////////////////////////////////////////////////////////////////////////////
     
    4142///////////////////////////////////////////////////////////////////////////
    4243
    43 extern unsigned int _get_sched(void);
     44extern static_scheduler_t* _get_sched(void);
    4445
    4546extern unsigned int _get_epc(void);
     
    105106
    106107///////////////////////////////////////////////////////////////////////////
    107 //       Scheduler and task context access functions
     108//       Scheduler and thread context access functions
    108109///////////////////////////////////////////////////////////////////////////
    109110
    110 extern unsigned int _get_current_task_id(void);
     111extern unsigned int _get_thread_ltid(void);
    111112
    112 extern unsigned int _get_task_slot( unsigned int x,
    113                                     unsigned int y,
    114                                     unsigned int p,
    115                                     unsigned int ltid,
    116                                     unsigned int slot );
     113extern unsigned int _get_thread_trdid(void);
    117114
    118 extern void         _set_task_slot( unsigned int x,
    119                                     unsigned int y,
    120                                     unsigned int p,
    121                                     unsigned int ltid,
    122                                     unsigned int slot,
    123                                     unsigned int value );
     115extern unsigned int _get_thread_slot( unsigned int x,
     116                                      unsigned int y,
     117                                      unsigned int p,
     118                                      unsigned int ltid,
     119                                      unsigned int slot );
     120
     121extern void         _set_thread_slot( unsigned int x,
     122                                      unsigned int y,
     123                                      unsigned int p,
     124                                      unsigned int ltid,
     125                                      unsigned int slot,
     126                                      unsigned int value );
    124127
    125128extern unsigned int _get_context_slot( unsigned int slot );
     
    136139extern mapping_vspace_t *   _get_vspace_base(mapping_header_t* header);
    137140extern mapping_vseg_t *     _get_vseg_base(mapping_header_t* header);
    138 extern mapping_task_t *     _get_task_base(mapping_header_t* header);
     141extern mapping_thread_t *   _get_thread_base(mapping_header_t* header);
    139142extern mapping_proc_t *     _get_proc_base(mapping_header_t* header);
    140143extern mapping_irq_t *      _get_irq_base(mapping_header_t* header);
  • soft/giet_vm/giet_config.h

    r649 r709  
    3737#define GIET_DEBUG_FBF_CMA        0            /* FBF_CMA access */
    3838#define GIET_DEBUG_COPROC         0            /* coprocessor access */
    39 #define GIET_DEBUG_EXEC           0            /* kill/exec mechanism */
     39#define GIET_DEBUG_EXEC           1            /* kill/exec & thread control */
    4040
    4141#define GIET_DEBUG_USER_MALLOC    0            /* malloc library */
     
    4949
    5050#define GIET_ELF_BUFFER_SIZE     0x80000       /* buffer for .elf files  */
    51 #define GIET_IDLE_TASK_PERIOD    0x10000000    /* Idle Task message period */
     51#define GIET_IDLE_THREAD_PERIOD  0x10000000    /* Idle Task message period */
    5252#define GIET_OPEN_FILES_MAX      16            /* max simultaneously open files */
    5353#define GIET_NB_VSPACE_MAX       16            /* max number of virtual spaces */
  • soft/giet_vm/giet_drivers/bdv_driver.c

    r657 r709  
    3737spin_lock_t  _bdv_lock __attribute__((aligned(64)));
    3838
    39 // global index of the waiting task (only used in descheduling mode)
     39// global index of the waiting thread (only used in descheduling mode)
    4040__attribute__((section(".kdata")))
    41 unsigned int _bdv_gtid;
     41unsigned int _bdv_trdid;
    4242
    4343// BDV peripheral status (only used in descheduling mode)
     
    7575                          unsigned int       count)
    7676{
    77     unsigned int procid  = _get_procid();
    78     unsigned int x       = procid >> (Y_WIDTH + P_WIDTH);
    79     unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH) - 1);
    80     unsigned int p       = procid & ((1<<P_WIDTH)-1);
    81 
    82 #if GIET_DEBUG_IOC
     77
     78#if GIET_DEBUG_IOC
     79unsigned int procid  = _get_procid();
     80unsigned int x       = procid >> (Y_WIDTH + P_WIDTH);
     81unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH) - 1);
     82unsigned int p       = procid & ((1<<P_WIDTH)-1);
    8383if ( _get_proctime() > GIET_DEBUG_IOC )
    8484_printf("\n[BDV DEBUG] P[%d,%d,%d] enters _bdv_access at cycle %d\n"
     
    9797    unsigned int status;
    9898
    99     // get the lock protecting BDV
     99    // get the BDV lock and register it in task context
     100    static_scheduler_t*  psched = _get_sched();
     101    unsigned int         ltid   = _get_thread_ltid();
    100102    _spin_lock_acquire( &_bdv_lock );
     103    _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_BDV );
    101104
    102105    // set device registers
     
    149152
    150153    /////////////////////////////////////////////////////////////////
    151     // in descheduling mode, we deschedule the task
    152     // and use an interrupt to reschedule the task.
     154    // in descheduling mode, we deschedule the thread
     155    // and use an interrupt to reschedule the thread.
    153156    // We need a critical section, because we must reset the RUN bit
    154157        // before to launch the transfer, and we don't want to be
     
    158161    {
    159162        unsigned int save_sr;
    160         unsigned int ltid = _get_current_task_id();
    161163
    162164        // activates BDV interrupt
    163165        _bdv_set_register( BLOCK_DEVICE_IRQ_ENABLE, 1 );
    164166
    165         // set _bdv_gtid
    166         _bdv_gtid = (procid<<16) + ltid;
     167        // set _bdv_trdid
     168        _bdv_trdid = _get_thread_trdid();
    167169
    168170        // enters critical section
     
    170172
    171173        // Set NORUN_MASK_IOC bit
    172         static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
    173         _atomic_or( &psched->context[ltid][CTX_NORUN_ID] , NORUN_MASK_IOC );
     174        static_scheduler_t* psched  = (static_scheduler_t*)_get_sched();
     175        unsigned int ltid = psched->current;
     176        _atomic_or( &psched->context[ltid].slot[CTX_NORUN_ID] , NORUN_MASK_IOC );
    174177       
    175178        // launch transfer
     
    184187#endif
    185188
    186         // deschedule task
     189        // deschedule thread
    187190        _ctx_switch();                     
    188191
     
    201204    }
    202205
    203     // release lock
     206    // release BDV lock and clear task context
    204207    _spin_lock_release( &_bdv_lock );     
     208    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_BDV );
    205209
    206210#if GIET_DEBUG_IOC
     
    241245    _bdv_status = status;
    242246
    243     // identify task waiting on BDV
    244     unsigned int procid  = _bdv_gtid>>16;
    245     unsigned int ltid    = _bdv_gtid & 0xFFFF;
    246     unsigned int cluster = procid >> P_WIDTH;
    247     unsigned int x       = cluster >> Y_WIDTH;
    248     unsigned int y       = cluster & ((1<<Y_WIDTH)-1);
    249     unsigned int p       = procid & ((1<<P_WIDTH)-1);
     247    // identify thread waiting on BDV
     248    unsigned int x       = (_bdv_trdid >> 24) & 0xFF;
     249    unsigned int y       = (_bdv_trdid >> 16) & 0xFF;
     250    unsigned int p       = (_bdv_trdid >>  8) & 0xFF;
     251    unsigned int ltid    = (_bdv_trdid      ) & 0xFF;
    250252
    251253    // Reset NORUN_MASK_IOC bit
    252254    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
    253     unsigned int*       ptr     = &psched->context[ltid][CTX_NORUN_ID];
     255    unsigned int*       ptr     = &psched->context[ltid].slot[CTX_NORUN_ID];
    254256    _atomic_and( ptr , ~NORUN_MASK_IOC );
    255257
    256     // send a WAKUP WTI to processor running the sleeping task
    257     _xcu_send_wti( cluster,   
     258    // send a WAKUP WTI to processor running the sleeping thread
     259    _xcu_send_wti( (x<<Y_WIDTH) + y,
    258260                   p,
    259261                   0 );          // don't force context switch
     
    266268if ( _get_proctime() > GIET_DEBUG_IOC )
    267269_printf("\n[BDV DEBUG] Processor[%d,%d,%d] enters _bdv_isr() at cycle %d\n"
    268         "  for task %d running on P[%d,%d,%d] / bdv_status = %x\n",
     270        "  for thread %d running on P[%d,%d,%d] / bdv_status = %x\n",
    269271        c_x , c_y , c_p , _get_proctime() ,
    270272        ltid , x , y , p , status );
  • soft/giet_vm/giet_drivers/bdv_driver.h

    r529 r709  
    7878
    7979///////////////////////////////////////////////////////////////////////////////////
    80 //            Access functions
     80//            Low level access function
    8181///////////////////////////////////////////////////////////////////////////////////
     82
     83unsigned int _bdv_get_register( unsigned int index );
     84
     85void _bdv_set_register( unsigned int index,
     86                        unsigned int value );
    8287
    8388///////////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/giet_drivers/hba_driver.c

    r657 r709  
    4646sqt_lock_t          _hba_allocator_lock  __attribute__((aligned(64)));
    4747
    48 // state of each slot (allocated to a task or not)
     48// state of each slot (allocated to a thread or not)
    4949// access must be protected by the allocator_lock in descheduling mode
    5050__attribute__((section(".kdata")))
     
    5656unsigned int        _hba_active_cmd[32];
    5757
    58 // global index of the task, for each entry in the command list
    59 __attribute__((section(".kdata")))
    60 unsigned int        _hba_gtid[32];
     58// global index of the thread, for each entry in the command list
     59__attribute__((section(".kdata")))
     60unsigned int        _hba_trid[32];
    6161
    6262// status of HBA commands
     
    9797
    9898///////////////////////////////////////////////////////////////////////////////
    99 // This blocking fonction allocates a free command index to the task.
     99// This blocking fonction allocates a free command index to the thread.
    100100// The hba_allocator_lock is not used in boot mode.
    101101// It returns the allocated command index (between 0 and 31)
     
    132132///////////////////////////////////////////////////////////////////////////////
    133133// This function releases the command index in the hba_allocated_cmd table.
    134 // There is no need to take the lock because only the task which owns the
     134// There is no need to take the lock because only the thread which owns the
    135135// command can release it.
    136136// return 0 if success, -1 if error
     
    281281
    282282    /////////////////////////////////////////////////////////////////
    283     // in descheduling mode, we deschedule the task
    284     // and use an interrupt to reschedule the task.
     283    // in descheduling mode, we deschedule the thread
     284    // and use an interrupt to reschedule the thread.
    285285    // We need a critical section, because we must set the NORUN bit
    286286        // before to launch the transfer, and we don't want to be
     
    297297#endif
    298298        unsigned int save_sr;
    299         unsigned int ltid = _get_current_task_id();
     299        unsigned int ltid = _get_thread_ltid();
    300300
    301301        // activates HBA interrupts
    302302        _hba_set_register( HBA_PXIE , 0x00000001 );
    303303
    304         // set _hba_gtid[cmd_id]
    305         _hba_gtid[cmd_id] = (procid<<16) + ltid;
     304        // set _hba_trid[cmd_id]
     305        _hba_trid[cmd_id] = (x<<24) + (y<<16) + (p<<8) + ltid;
    306306
    307307        // enters critical section
     
    310310        // Set NORUN_MASK_IOC bit
    311311        static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
    312         unsigned int*       ptr     = &psched->context[ltid][CTX_NORUN_ID];
     312        unsigned int*       ptr     = &psched->context[ltid].slot[CTX_NORUN_ID];
    313313        _atomic_or( ptr , NORUN_MASK_IOC );
    314314     
     
    319319        _hba_active_cmd[cmd_id] = 1;
    320320
    321         // deschedule task
     321        // deschedule thread
    322322        _ctx_switch();                     
    323323
    324324#if GIET_DEBUG_IOC
    325325if (_get_proctime() > GIET_DEBUG_IOC)
    326 _printf("\n[DEBUG HBA] _hba_access() : task %d on P[%d,%d,%d] resume at cycle %d\n",
     326_printf("\n[DEBUG HBA] _hba_access() : thread %d on P[%d,%d,%d] resume at cycle %d\n",
    327327        ltid , x , y , p , _get_proctime() );
    328328#endif
     
    438438            _hba_active_cmd[cmd_id] = 0;
    439439
    440             // identify waiting task
    441             unsigned int procid  = _hba_gtid[cmd_id]>>16;
    442             unsigned int ltid    = _hba_gtid[cmd_id] & 0xFFFF;
    443             unsigned int cluster = procid >> P_WIDTH;
    444             unsigned int x       = cluster >> Y_WIDTH;
    445             unsigned int y       = cluster & ((1<<Y_WIDTH)-1);
    446             unsigned int p       = procid & ((1<<P_WIDTH)-1);
     440            // identify waiting thread
     441            unsigned int x       = (_hba_trid[cmd_id]>>24) & 0xFF;
     442            unsigned int y       = (_hba_trid[cmd_id]>>16) & 0xFF;
     443            unsigned int p       = (_hba_trid[cmd_id]>> 8) & 0xFF;
     444            unsigned int ltid    = (_hba_trid[cmd_id]    ) & 0xFF;
    447445 
    448446            // Reset NORUN_MASK_IOC bit
    449447            static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
    450             _atomic_and( &psched->context[ltid][CTX_NORUN_ID] , ~NORUN_MASK_IOC );
    451 
    452             // send a WAKUP WTI to processor running the waiting task
    453             _xcu_send_wti( cluster ,
     448            _atomic_and( &psched->context[ltid].slot[CTX_NORUN_ID] , ~NORUN_MASK_IOC );
     449
     450            // send a WAKUP WTI to processor running the waiting thread
     451            _xcu_send_wti( (x<<Y_WIDTH) + y,
    454452                           p ,
    455453                           0 );          // don't force context switch
     
    458456if (_get_proctime() > GIET_DEBUG_IOC)
    459457_printf("\n[DEBUG HBA] _hba_isr() : command %d completed at cycle %d\n"
    460         "  resume task %d running on P[%d,%d,%d]\n",
     458        "  resume thread %d running on P[%d,%d,%d]\n",
    461459        cmd_id , _get_proctime() ,
    462460        ltid , x , y , p );
  • soft/giet_vm/giet_drivers/mwr_driver.c

    r668 r709  
    7474unsigned int   _coproc_error[X_SIZE*Y_SIZE];
    7575
    76 // descheduled task gtid (for MODE_DMA_IRQ)
    77 __attribute__((section(".kdata")))
    78 unsigned int   _coproc_gtid[X_SIZE*Y_SIZE];
     76// descheduled thread trdid (for MODE_DMA_IRQ)
     77__attribute__((section(".kdata")))
     78unsigned int   _coproc_trdid[X_SIZE*Y_SIZE];
    7979
    8080/////////////////////////////////////////////////////////////////////////////
     
    205205    _coproc_error[cluster_id]  = error;
    206206
    207     // identify task waiting on coprocessor completion
    208     // this task can run in a remote cluster
    209     unsigned int r_gtid    = _coproc_gtid[cluster_id];
    210     unsigned int r_procid  = r_gtid>>16;
    211     unsigned int r_ltid    = r_gtid & 0xFFFF;
    212     unsigned int r_cluster = r_procid >> P_WIDTH;
    213     unsigned int r_x       = r_cluster >> Y_WIDTH;
    214     unsigned int r_y       = r_cluster & ((1<<Y_WIDTH)-1);
    215     unsigned int r_p       = r_procid & ((1<<P_WIDTH)-1);
     207    // identify thread waiting on coprocessor completion (can run in a remote cluster)
     208    unsigned int r_x       = (_coproc_trdid[cluster_id]>>24) & 0xFF;
     209    unsigned int r_y       = (_coproc_trdid[cluster_id]>>16) & 0xFF;
     210    unsigned int r_p       = (_coproc_trdid[cluster_id]>> 8) & 0xFF;
     211    unsigned int r_ltid    = (_coproc_trdid[cluster_id]    ) & 0xFF;
    216212
    217213    // Reset NORUN_MASK_IOC bit
    218214    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[r_x][r_y][r_p];
    219     unsigned int*       ptr     = &psched->context[r_ltid][CTX_NORUN_ID];
     215    unsigned int*       ptr     = &psched->context[r_ltid].slot[CTX_NORUN_ID];
    220216    _atomic_and( ptr , ~NORUN_MASK_COPROC );
    221217
    222     // send a WAKUP WTI to processor running the sleeping task
    223     _xcu_send_wti( r_cluster,   
     218    // send a WAKUP WTI to processor running the sleeping thread
     219    _xcu_send_wti( (r_x<<Y_WIDTH) + r_y,
    224220                   r_p,
    225221                   0 );          // don't force context switch
     
    228224unsigned int p          = gpid & ((1<<P_WIDTH)-1);
    229225_printf("\n[GIET DEBUG COPROC] P[%d,%d,%d] executes _mwr_isr() at cycle %d\n"
    230         "  for task %d running on P[%d,%d,%d] / error = %d\n",
     226        "  for thread %d running on P[%d,%d,%d] / error = %d\n",
    231227        x , y , p , _get_proctime() , r_ltid , r_x , r_y , r_p , error );
    232228#endif
  • soft/giet_vm/giet_drivers/sdc_driver.c

    r657 r709  
    3232///////////////////////////////////////////////////////////////////////////////////
    3333
    34 // global index ot the task, for each entry in the command list
    35 __attribute__((section(".kdata")))
    36 unsigned int     _ahci_gtid[32];
     34// global index ot the thread, for each entry in the command list
     35__attribute__((section(".kdata")))
     36unsigned int     _ahci_trdid[32];
    3737
    3838// status of the command, for each entry in the command list
     
    406406
    407407    /////////////////////////////////////////////////////////////////
    408     // in descheduling mode, we deschedule the task
    409     // and use an interrupt to reschedule the task.
     408    // in descheduling mode, we deschedule the thread
     409    // and use an interrupt to reschedule the thread.
    410410    // We need a critical section, because we must set the NORUN bit
    411411        // before to launch the transfer, and we don't want to be
     
    422422#endif
    423423        unsigned int save_sr;
    424         unsigned int ltid = _get_current_task_id();
     424        unsigned int ltid = _get_thread_ltid();
    425425
    426426        // activates interrupt
    427427        _sdc_set_register( AHCI_PXIE , 0x00000001 );
    428428
    429         // set _ahci_gtid[ptw]
    430         _ahci_gtid[ptw] = (procid<<16) + ltid;
     429        // set _ahci_trdid[ptw]
     430        _ahci_trdid[ptw] = (x<<24) + (y<<16) + (p<<8) + ltid;
    431431
    432432        // enters critical section
     
    435435        // Set NORUN_MASK_IOC bit
    436436        static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
    437         unsigned int*       ptr     = &psched->context[ltid][CTX_NORUN_ID];
     437        unsigned int*       ptr     = &psched->context[ltid].slot[CTX_NORUN_ID];
    438438        _atomic_or( ptr , NORUN_MASK_IOC );
    439439       
     
    441441        _sdc_set_register( AHCI_PXCI, (1<<ptw) );
    442442
    443         // deschedule task
     443        // deschedule thread
    444444        _ctx_switch();                     
    445445
    446446#if GIET_DEBUG_IOC
    447447if (_get_proctime() > GIET_DEBUG_IOC)
    448 _printf("\n[DEBUG SDC] _sdc_access() : task %d on P[%d,%d,%d] resume at cycle %d\n",
     448_printf("\n[DEBUG SDC] _sdc_access() : thread %d on P[%d,%d,%d] resume at cycle %d\n",
    449449        ltid , x , y , p , _get_proctime() );
    450450#endif
     
    497497            _sdc_set_register( AHCI_PXIS , 0 );
    498498 
    499             // identify waiting task
    500             unsigned int procid  = _ahci_gtid[cmd_id]>>16;
    501             unsigned int ltid    = _ahci_gtid[cmd_id] & 0xFFFF;
    502             unsigned int cluster = procid >> P_WIDTH;
    503             unsigned int x       = cluster >> Y_WIDTH;
    504             unsigned int y       = cluster & ((1<<Y_WIDTH)-1);
    505             unsigned int p       = procid & ((1<<P_WIDTH)-1);
    506  
     499            // identify waiting thread
     500            unsigned int x       = (_ahci_trdid[cmd_id]>>24) & 0xFF;
     501            unsigned int y       = (_ahci_trdid[cmd_id]>>16) & 0xFF;
     502            unsigned int p       = (_ahci_trdid[cmd_id]>> 8) & 0xFF;
     503            unsigned int ltid    = (_ahci_trdid[cmd_id]    ) & 0xFF;
     504
    507505            // Reset NORUN_MASK_IOC bit
    508506            static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
    509             _atomic_and( &psched->context[ltid][CTX_NORUN_ID] , ~NORUN_MASK_IOC );
    510 
    511             // send a WAKUP WTI to processor running the waiting task
    512             _xcu_send_wti( cluster ,
     507            _atomic_and( &psched->context[ltid].slot[CTX_NORUN_ID] , ~NORUN_MASK_IOC );
     508
     509            // send a WAKUP WTI to processor running the waiting thread
     510            _xcu_send_wti( (x<<Y_WIDTH) + y,
    513511                           p ,
    514512                           0 );          // don't force context switch
     
    517515if (_get_proctime() > GIET_DEBUG_IOC)
    518516_printf("\n[DEBUG SDC] _sdc_isr() : command %d completed at cycle %d\n"
    519         "  resume task %d running on P[%d,%d,%d] / status = %x\n",
     517        "  resume thread %d running on P[%d,%d,%d] / status = %x\n",
    520518        cmd_id , _get_proctime() ,
    521519        ltid , x , y , p , _ahci_status[cmd_id] );
  • soft/giet_vm/giet_drivers/tty_driver.c

    r605 r709  
    1919
    2020////////////////////////////////////////////////////////////////////////////////////
     21//               extern variables
     22////////////////////////////////////////////////////////////////////////////////////
     23
     24// This variable is allocated in kernel_init.c file
     25extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
     26
     27////////////////////////////////////////////////////////////////////////////////////
    2128//               global variables
    2229////////////////////////////////////////////////////////////////////////////////////
    2330
     31__attribute__((section(".kdata")))
     32tty_fifo_t  _tty_rx_fifo[NB_TTY_CHANNELS];
     33
     34/*
    2435__attribute__((section(".kdata")))
    2536unsigned int   _tty_rx_buf[NB_TTY_CHANNELS];
     
    2738__attribute__((section(".kdata")))
    2839unsigned int   _tty_rx_full[NB_TTY_CHANNELS];
     40
     41__attribute__((section(".kdata")))
     42unsigned int   _tty_rx_trdid[NB_TTY_CHANNELS];
     43*/
    2944
    3045////////////////////////////////////////////////////////////////////////////////////
     
    5267void _tty_init( unsigned int channel )
    5368{
    54     _tty_rx_full[channel] = 0;
     69    _tty_rx_fifo[channel].sts = 0;
     70    _tty_rx_fifo[channel].ptr = 0;
     71    _tty_rx_fifo[channel].ptw = 0;
    5572}
    5673
     
    6077                  unsigned int channel )   // TTY channel
    6178{
    62     // transfer character to kernel buffer and acknowledge TTY IRQ
    63     _tty_rx_buf[channel]  = _tty_get_register( channel, TTY_READ );
     79    // get pointer on TTY_RX FIFO
     80    tty_fifo_t*   fifo = &_tty_rx_fifo[channel];
    6481
    65     // flush pending memory writes
    66     asm volatile( "sync" );
     82    // get character from TTY_RX channel and acknowledge IRQ
     83    unsigned int data = _tty_get_register( channel, TTY_READ );
    6784
    68     // set kernel buffer status
    69     _tty_rx_full[channel] = 1;
     85    // transfer character to FIFO if not full
     86    // discard incoming character if full
     87    if ( fifo->sts < TTY_FIFO_DEPTH )
     88    {
     89        // store data into FIFO
     90        fifo->data[fifo->ptw] = (char)data;
    7091
    71 #if GIET_DEBUG_IRQS  // we don't take the TTY lock to avoid deadlock
    72 unsigned int gpid           = _get_procid();
    73 unsigned int cluster_xy     = gpid >> P_WIDTH;
    74 unsigned int x              = cluster_xy >> Y_WIDTH;
    75 unsigned int y              = cluster_xy & ((1<<Y_WIDTH)-1);
    76 unsigned int lpid           = gpid & ((1<<P_WIDTH)-1);
    77 _puts("\n[IRQS DEBUG] Processor[");
    78 _putd(x );
    79 _puts(",");
    80 _putd(y );
    81 _puts(",");
    82 _putd(lpid );
    83 _puts("] enters _tty_rx_isr() at cycle ");
    84 _putd(_get_proctime() );
    85 _puts("\n  read byte = ");
    86 _putx(_tty_rx_buf[channel] );
    87 _puts("\n");
    88 #endif
     92        // avoid race
     93        asm volatile( "sync" );
    8994
     95        // update FIFO state
     96        fifo->ptw = (fifo->ptw + 1) % TTY_FIFO_DEPTH;
     97        fifo->sts = fifo->sts + 1;
     98    }
     99
     100    // get owner thread indexes
     101    unsigned int trdid          = fifo->trdid;
     102    unsigned int x              = (trdid >> 24) & 0xFF;
     103    unsigned int y              = (trdid >> 16) & 0xFF;
     104    unsigned int p              = (trdid >>  8) & 0xFF;
     105    unsigned int ltid           = (trdid      ) & 0xFF;
     106
     107    // Reset NORUN_MASK_TTY bit
     108    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
     109    unsigned int*       ptr     = &psched->context[ltid].slot[CTX_NORUN_ID];
     110    _atomic_and( ptr , ~NORUN_MASK_TTY );
    90111}
    91112
     
    95116                  unsigned int channel )   // TTY channel
    96117{
    97     _puts("\n[GIET ERROR] the _tty_tx_isr() is not implemented\n");
     118    _printf("\n[GIET ERROR] the _tty_tx_isr() is not implemented\n");
    98119    _exit();
    99120}
  • soft/giet_vm/giet_drivers/tty_driver.h

    r496 r709  
    2727#include "kernel_locks.h"
    2828
     29
    2930///////////////////////////////////////////////////////////////////////////////////
    3031//                     registers offsets
     
    4142};
    4243
     44
     45//////////////////////////////////////////////////////////////////////////////////
     46//                    struct tty_fifo_t
     47//////////////////////////////////////////////////////////////////////////////////
     48
     49#define TTY_FIFO_DEPTH  16
     50
     51typedef struct tty_fifo_s     // 32 bytes
     52{
     53    char          data[TTY_FIFO_DEPTH];   // one char per slot
     54    unsigned int  trdid;                  // owner thread trdid
     55    unsigned int  ptr;                    // next free slot index
     56    unsigned int  ptw;                    // next full slot index
     57    unsigned int  sts;                    // number of full slots
     58} tty_fifo_t;
     59 
    4360//////////////////////////////////////////////////////////////////////////////////
    4461//                    access functions
  • soft/giet_vm/giet_fat32/fat32.c

    r707 r709  
    3838#include <vmem.h>
    3939#include <kernel_malloc.h>
     40#include <ctx_handler.h>
    4041#include <bdv_driver.h>
    4142#include <hba_driver.h>
     
    9394#if GIET_DEBUG_FAT
    9495static void _display_fat_descriptor();
    95 #endif
    96 
    97 /////////////////////////////////////////////////////////////////////////////////
    98 // This debug function displays the sequence of clusters allocated to a
    99 // file (or directory) identified by the "inode" argument.
    100 /////////////////////////////////////////////////////////////////////////////////
    101 
    102 #if GIET_DEBUG_FAT
    103 static void _display_clusters_list( fat_inode_t* inode );
    10496#endif
    10597
     
    593585
    594586
    595 #if GIET_DEBUG_FAT
     587#if 0
    596588////////////////////////////////////////////////////////
    597589static void _display_clusters_list( fat_inode_t* inode )
     
    28322824    }
    28332825
    2834     // takes the lock
     2826    // takes the FAT lock and register it in thread context
     2827    static_scheduler_t*  psched = _get_sched();
     2828    unsigned int         ltid   = _get_thread_ltid();
    28352829    _spin_lock_acquire( &_fat.fat_lock );
     2830    _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT );
    28362831
    28372832    // get inode pointer
     
    28412836    {
    28422837        _spin_lock_release( &_fat.fat_lock );
     2838        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     2839
    28432840        _printf("\n[FAT ERROR] _fat_open(): path to parent not found"
    28442841                " for file <%s>\n", pathname );
     
    28482845    {
    28492846        _spin_lock_release( &_fat.fat_lock );
     2847        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     2848
    28502849        _printf("\n[FAT ERROR] _fat_open(): one name in path too long"
    28512850                " for file <%s>\n", pathname );
     
    28552854    {
    28562855        _spin_lock_release( &_fat.fat_lock );
     2856        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     2857
    28572858        _printf("\n[FAT ERROR] _fat_open(): file not found"
    28582859                " for file <%s>\n", pathname );
     
    28902891        {
    28912892            _spin_lock_release( &_fat.fat_lock );
     2893            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     2894
    28922895            _printf("\n[FAT ERROR] _fat_open(): cannot update parent directory"
    28932896                    " for file <%s>\n" , pathname );
     
    29012904        {
    29022905            _spin_lock_release( &_fat.fat_lock );
     2906            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     2907
    29032908            _printf("\n[FAT ERROR] _fat_open(): cannot update DATA region "
    29042909                    " for parent of file <%s>\n", pathname );
     
    29122917        {
    29132918            _spin_lock_release( &_fat.fat_lock );
     2919            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     2920
    29142921            _printf("\n[FAT ERROR] _fat_open(): cannot update FAT region"
    29152922                    " for file <%s>\n", pathname );
     
    29212928        {
    29222929            _spin_lock_release( &_fat.fat_lock );
     2930            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     2931
    29232932            _printf("\n[FAT ERROR] _fat_open(): cannot update FS-INFO"
    29242933                    " for file <%s>\n", pathname );
     
    29522961    {
    29532962        _spin_lock_release( &_fat.fat_lock );
     2963        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     2964
    29542965        _printf("\n[FAT ERROR] _fat_open(): File-Descriptors-Array full\n");
    29552966        return GIET_FAT32_TOO_MANY_OPEN_FILES;
     
    29792990        {
    29802991            _spin_lock_release( &_fat.fat_lock );
     2992            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     2993
    29812994            _printf("\n[FAT ERROR] _fat_open(): can't truncate file\n");
    29822995            return GIET_FAT32_IO_ERROR;
     
    29873000        {
    29883001            _spin_lock_release( &_fat.fat_lock );
     3002            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3003
    29893004            _printf("\n[FAT ERROR] _fat_open(): can't truncate file\n");
    29903005            return GIET_FAT32_IO_ERROR;
     
    29943009    // releases the lock
    29953010    _spin_lock_release( &_fat.fat_lock );
     3011    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3012
    29963013
    29973014#if GIET_DEBUG_FAT
     
    30363053    }
    30373054
    3038     // takes lock
     3055    // takes the FAT lock and register it in thread context
     3056    static_scheduler_t*  psched = _get_sched();
     3057    unsigned int         ltid   = _get_thread_ltid();
    30393058    _spin_lock_acquire( &_fat.fat_lock );
     3059    _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT );
    30403060
    30413061    if( _fat.fd[fd_id].allocated == 0 )
    30423062    {
    30433063        _spin_lock_release( &_fat.fat_lock );
     3064        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3065
    30443066        _printf("\n[FAT ERROR] _fat_close(): file not open\n");
    30453067        return GIET_FAT32_NOT_OPEN;
     
    30673089        {
    30683090            _spin_lock_release( &_fat.fat_lock );
     3091            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3092
    30693093            _printf("\n[FAT ERROR] _fat_close(): cannot write dirty clusters "
    30703094                    "for file <%s>\n", inode->name );
     
    30843108        {
    30853109            _spin_lock_release( &_fat.fat_lock );
     3110            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3111
    30863112            _printf("\n[FAT ERROR] _fat_close(): cannot write dirty clusters "
    30873113                    "for directory <%s>\n", inode->parent->name );
     
    31113137    // release lock
    31123138    _spin_lock_release( &_fat.fat_lock );
     3139    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
    31133140
    31143141    return GIET_FAT32_OK;
     
    31613188
    31623189/////////////////////////////////////////////////////////////////////////////////
    3163 // The following function implements the "giet_fat_read()" system call.
    3164 // It transfers "count" bytes from the File_Cache associated to the file
    3165 // identified by "fd_id", to the user "buffer", from the current file offset.
     3190// The following function implements the "giet_fat_read()" system call,
     3191// but can also be used by the kernel in physical addressing mode.
     3192// It transfers <count> bytes from the File_Cache associated to the file
     3193// identified by <fd_id>, to the destination buffer defined by <vaddr>.
     3194// It uses the current file offset defined in the file descriptor.
     3195// If the <extend> 16 MSB bits are non zero, it uses physical addressing:
     3196// the physical  address is computed as extend[15:0] | vaddr[31:0]
    31663197// In case of miss in the File_Cache, it loads all involved clusters into cache.
    31673198/////////////////////////////////////////////////////////////////////////////////
     
    31753206/////////////////////////////////////////////////////////////////////////////////
    31763207int _fat_read( unsigned int fd_id,          // file descriptor index
    3177                paddr_t buffer,              // destination buffer
     3208               unsigned int vaddr,          // destination buffer vaddr
    31783209               unsigned int count,          // number of bytes to read
    3179                unsigned int phys )          // use physical_memcpy
    3180 {
    3181     // checking FAT initialized
    3182     if( _fat.initialized != FAT_INITIALIZED )
    3183     {
    3184         _printf("\n[FAT ERROR] _fat_write(): FAT not initialized\n");
    3185         return GIET_FAT32_NOT_INITIALIZED;
    3186     }
    3187 
    3188     // check fd_id overflow
    3189     if ( fd_id >= GIET_OPEN_FILES_MAX )
    3190     {
    3191         _printf("\n[FAT ERROR] _fat_read(): illegal file descriptor\n");
    3192         return GIET_FAT32_INVALID_FD;
    3193     }
    3194 
    3195     // check file is open
    3196     if ( _fat.fd[fd_id].allocated == 0 )
    3197     {
    3198         _printf("\n[FAT ERROR] _fat_read(): file not open\n");
    3199         return GIET_FAT32_NOT_OPEN;
    3200     }
    3201 
    3202     // takes lock
    3203     _spin_lock_acquire( &_fat.fat_lock );
    3204            
    3205     // get file inode pointer and offset
    3206     fat_inode_t* inode  = _fat.fd[fd_id].inode;
    3207     unsigned int seek   = _fat.fd[fd_id].seek;
    3208 
    3209     // check count & seek versus file size
    3210     if ( count + seek > inode->size && !inode->is_dir )
    3211     {
    3212         _spin_lock_release( &_fat.fat_lock );
    3213         _printf("\n[FAT ERROR] _fat_read(): file too small"
    3214                 " / seek = %x / count = %x / file_size = %x\n",
    3215                 seek , count , inode->size );
    3216         return 0;
    3217     }
    3218 
    3219     // compute first_cluster_id and first_byte_to_move
    3220     unsigned int first_cluster_id   = seek >> 12;
    3221     unsigned int first_byte_to_move = seek & 0xFFF;   
    3222 
    3223     // compute last_cluster and last_byte_to_move
    3224     unsigned int last_cluster_id   = (seek + count - 1) >> 12;   
    3225     unsigned int last_byte_to_move = (seek + count - 1) & 0xFFF;
     3210               unsigned int extend )        // physical address extension
     3211{
    32263212
    32273213#if GIET_DEBUG_FAT
     
    32313217unsigned int p       = procid & ((1<<P_WIDTH)-1);
    32323218if ( _get_proctime() > GIET_DEBUG_FAT )
    3233 _printf("\n[DEBUG FAT] _fat_read(): P[%d,%d,%d] enters for file <%s> "
    3234         " / bytes = %x / offset = %x\n"
    3235         "first_cluster_id = %x / first_byte_to_move = %x"
     3219_printf("\n[DEBUG FAT] _fat_read(): P[%d,%d,%d] enters at cycle %d\n"
     3220        "  fd = %d / vaddr = %x / bytes = %x / extend = %x\n",
     3221        x , y , p , _get_proctime(),
     3222        fd_id , vaddr , count , extend );
     3223#endif
     3224
     3225    // checking FAT initialized
     3226    if( _fat.initialized != FAT_INITIALIZED )
     3227    {
     3228        _printf("\n[FAT ERROR] _fat_read(): FAT not initialized\n");
     3229        return GIET_FAT32_NOT_INITIALIZED;
     3230    }
     3231
     3232    // check fd_id overflow
     3233    if ( fd_id >= GIET_OPEN_FILES_MAX )
     3234    {
     3235        _printf("\n[FAT ERROR] _fat_read(): illegal file descriptor\n");
     3236        return GIET_FAT32_INVALID_FD;
     3237    }
     3238
     3239    // check file is open
     3240    if ( _fat.fd[fd_id].allocated == 0 )
     3241    {
     3242        _printf("\n[FAT ERROR] _fat_read(): file not open\n");
     3243        return GIET_FAT32_NOT_OPEN;
     3244    }
     3245
     3246    // takes the FAT lock and register it in thread context
     3247    static_scheduler_t*  psched = _get_sched();
     3248    unsigned int         ltid   = _get_thread_ltid();
     3249    _spin_lock_acquire( &_fat.fat_lock );
     3250    _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT );
     3251
     3252           
     3253    // get file inode pointer and offset
     3254    fat_inode_t* inode  = _fat.fd[fd_id].inode;
     3255    unsigned int seek   = _fat.fd[fd_id].seek;
     3256
     3257    // check count & seek versus file size
     3258    if ( count + seek > inode->size && !inode->is_dir )
     3259    {
     3260        _spin_lock_release( &_fat.fat_lock );
     3261        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3262
     3263        _printf("\n[FAT ERROR] _fat_read(): file too small"
     3264                " / seek = %x / count = %x / file_size = %x\n",
     3265                seek , count , inode->size );
     3266        return 0;
     3267    }
     3268
     3269    // compute first_cluster_id and first_byte_to_move
     3270    unsigned int first_cluster_id   = seek >> 12;
     3271    unsigned int first_byte_to_move = seek & 0xFFF;   
     3272
     3273    // compute last_cluster and last_byte_to_move
     3274    unsigned int last_cluster_id   = (seek + count - 1) >> 12;   
     3275    unsigned int last_byte_to_move = (seek + count - 1) & 0xFFF;
     3276
     3277#if GIET_DEBUG_FAT
     3278if ( _get_proctime() > GIET_DEBUG_FAT )
     3279_printf("\n[DEBUG FAT] _fat_read(): P[%d,%d,%d] search file <%s> with seek = %x\n "
     3280        " first_cluster_id = %x / first_byte_to_move = %x"
    32363281        " / last_cluster_id = %x / last_byte_to_move = %x\n",
    3237         x , y , p , inode->name , count , seek ,
     3282        x , y , p , inode->name , seek ,
    32383283        first_cluster_id , first_byte_to_move , last_cluster_id , last_byte_to_move );
    32393284#endif
     
    32523297        {
    32533298            _spin_lock_release( &_fat.fat_lock );
     3299            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3300
    32543301            _printf("\n[FAT ERROR] _fat_read(): cannot load file <%s>\n",
    32553302                    inode->name );
     
    32893336        }
    32903337
    3291         // move data
    3292         if ( !phys )
    3293         {
    3294             void* dest = (void*)(unsigned int)buffer + done;
    3295 
    3296             memcpy( dest, source, nbytes );
    3297         }
    3298         else
     3338        // move data
     3339        if ( (extend & 0xFFFF0000) == 0 )         // no physical addressing
     3340        {
     3341            char* dest = (char*)(vaddr + done);
     3342            memcpy( dest , source , nbytes );
     3343        }
     3344        else                                      // physical addressing required
    32993345        {
    33003346            unsigned int flags;
    3301             paddr_t pdest = buffer + done;
     3347            paddr_t pdest    = (((paddr_t)(extend & 0x0000FFFF))<<32) + vaddr + done;
    33023348            paddr_t psource  = _v2p_translate( (unsigned int)source, &flags );
    3303 
    3304             _physical_memcpy( pdest, psource, nbytes );
     3349            _physical_memcpy( pdest , psource , nbytes );
    33053350        }
    33063351
     
    33193364    // release lock
    33203365    _spin_lock_release( &_fat.fat_lock );
     3366    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
    33213367
    33223368    return done;
     
    33273373
    33283374/////////////////////////////////////////////////////////////////////////////////
    3329 // The following function implements the "giet_fat_write()" system call.
    3330 // It transfers "count" bytes to the fat_cache associated to the file
    3331 // identified by "fd_id", from the user "buffer", using the current file offset.
     3375// The following function implements the "giet_fat_write()" system call,
     3376// but can also be used by the kernel in physical addressing mode.
     3377// It transfers <count> bytes to the File_Cache associated to the file
     3378// identified by <fd_id>, from the source buffer defined by <vaddr>.
     3379// It uses the current file offset defined in the file descriptor.
     3380// If the <extend> 16 MSB bits are non zero, it uses physical addressing:
     3381// the physical  address is computed as extend[15:0] | vaddr[31:0]
    33323382// It increases the file size and allocate new clusters if (count + offset)
    33333383// is larger than the current file size. Then it loads and updates all
     
    33443394/////////////////////////////////////////////////////////////////////////////////
    33453395int _fat_write( unsigned int fd_id,    // file descriptor index
    3346                 void*        buffer,   // source buffer
    3347                 unsigned int count )   // number of bytes to write
     3396                unsigned int vaddr,    // source buffer vaddr
     3397                unsigned int count,    // number of bytes to write
     3398                unsigned int extend )  // physical address extension
    33483399{
    33493400    // checking FAT initialized
     
    33543405    }
    33553406
    3356     // takes lock
     3407    // takes the FAT lock and register it in thread context
     3408    static_scheduler_t*  psched = _get_sched();
     3409    unsigned int         ltid   = _get_thread_ltid();
    33573410    _spin_lock_acquire( &_fat.fat_lock );
     3411    _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT );
     3412
    33583413           
    33593414    // check fd_id overflow
     
    33613416    {
    33623417        _spin_lock_release( &_fat.fat_lock );
     3418        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3419
    33633420        _printf("\n[FAT ERROR] _fat_write(): illegal file descriptor\n");
    33643421        return GIET_FAT32_INVALID_FD;
     
    33693426    {
    33703427        _spin_lock_release( &_fat.fat_lock );
     3428        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3429
    33713430        _printf("\n[FAT ERROR] _fat_write(): file not open\n" );
    33723431        return GIET_FAT32_NOT_OPEN;
     
    33773436    {
    33783437        _spin_lock_release( &_fat.fat_lock );
     3438        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3439
    33793440        _printf("\n[FAT ERROR] _fat_write(): file <%s> is read-only\n",
    33803441                _fat.fd[fd_id].inode->name );
     
    34293490            {
    34303491                _spin_lock_release( &_fat.fat_lock );
     3492                _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3493
    34313494                _printf("\n[FAT ERROR] _fat_write(): no free clusters"
    34323495                        " for file <%s>\n", _fat.fd[fd_id].inode->name );
     
    34393502        {
    34403503            _spin_lock_release( &_fat.fat_lock );
     3504            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3505
    34413506            _printf("\n[FAT ERROR] _fat_write(): cannot update parent directory entry"
    34423507                    " for file <%s>\n", _fat.fd[fd_id].inode->name );
     
    34833548        {
    34843549            _spin_lock_release( &_fat.fat_lock );
     3550            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3551
    34853552            _printf("\n[FAT ERROR] _fat_write(): cannot load file <%s>\n",
    34863553                    inode->name );
     
    34983565
    34993566        // compute memcpy arguments
    3500         unsigned char* source = (unsigned char*)buffer + done;
    35013567        unsigned char* dest;
    35023568        unsigned int   nbytes;
     
    35223588        }
    35233589
    3524         //move date
    3525         memcpy( dest , source , nbytes );
     3590        // move data
     3591        if ( (extend & 0xFFFF0000) == 0 )     // no physical addressing
     3592        {
     3593            char* source = (char*)(vaddr + done);
     3594            memcpy( dest , source , nbytes );
     3595        }
     3596        else                                  // physical addressing required
     3597        {
     3598            unsigned int flags;
     3599            paddr_t      psource = (((paddr_t)(extend & 0x0000FFFF))<<32) + vaddr + done;
     3600            paddr_t      pdest   = _v2p_translate( (unsigned int)dest , &flags );
     3601            _physical_memcpy( pdest , psource , nbytes );
     3602        }
     3603
    35263604        done = done + nbytes;
    35273605
     
    35393617    // release lock
    35403618    _spin_lock_release( &_fat.fat_lock );
     3619    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
    35413620
    35423621    return done;
     
    35773656    }
    35783657
    3579     // takes lock
     3658    // takes the FAT lock and register it in thread context
     3659    static_scheduler_t*  psched = _get_sched();
     3660    unsigned int         ltid   = _get_thread_ltid();
    35803661    _spin_lock_acquire( &_fat.fat_lock );
     3662    _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT );
     3663
    35813664
    35823665    // check file open
     
    35843667    {
    35853668        _spin_lock_release( &_fat.fat_lock );
     3669        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3670
    35863671        _printf("\n[FAT ERROR] _fat_lseek(): file not open\n");
    35873672        return GIET_FAT32_NOT_OPEN;
     
    35963681    {
    35973682        _spin_lock_release( &_fat.fat_lock );
     3683        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3684
    35983685        _printf("\n[FAT ERROR] _fat_lseek(): illegal whence value\n");
    35993686        return GIET_FAT32_INVALID_ARG;
     
    36153702    // release lock
    36163703    _spin_lock_release( &_fat.fat_lock );
     3704    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
    36173705
    36183706    return new_seek;
     
    36653753    }
    36663754
    3667     // take the lock
     3755    // takes the FAT lock and register it in thread context
     3756    static_scheduler_t*  psched = _get_sched();
     3757    unsigned int         ltid   = _get_thread_ltid();
    36683758    _spin_lock_acquire( &_fat.fat_lock );
     3759    _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT );
     3760
    36693761
    36703762    // get searched file inode
     
    36803772    {
    36813773        _spin_lock_release( &_fat.fat_lock );
     3774        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3775
    36823776        _printf("\n[FAT ERROR] _fat_remove(): file <%s> not found\n",
    36833777                pathname );
     
    36873781    {
    36883782        _spin_lock_release( &_fat.fat_lock );
     3783        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3784
    36893785        _printf("\n[FAT ERROR] _fat_remove(): name too long in <%s>\n",
    36903786                pathname );
     
    36963792    {
    36973793        _spin_lock_release( &_fat.fat_lock );
     3794        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3795
    36983796        _printf("\n[FAT ERROR] _fat_remove(): <%s> is a directory\n",
    36993797                pathname );
     
    37033801    {
    37043802        _spin_lock_release( &_fat.fat_lock );
     3803        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3804
    37053805        _printf("\n[FAT ERROR] _fat_remove(): <%s> is not a directory\n",
    37063806                pathname );
     
    37183818    {
    37193819        _spin_lock_release( &_fat.fat_lock );
     3820        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3821
    37203822        _printf("\n[FAT ERROR] _fat_remove(): file <%s> still referenced\n",
    37213823                pathname );
     
    37303832        {
    37313833            _spin_lock_release( &_fat.fat_lock );
     3834            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3835
    37323836            _printf("\n[FAT ERROR] _fat_remove(): cannot scan directory <%s>\n",
    37333837                    pathname );
     
    37373841        {
    37383842            _spin_lock_release( &_fat.fat_lock );
     3843            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3844
    37393845            _printf("\n[FAT ERROR] _fat_remove(): directory <%s> not empty\n",
    37403846                    pathname );
     
    37533859    {
    37543860        _spin_lock_release( &_fat.fat_lock );
     3861        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3862
    37553863        _printf("\n[FAT ERROR] _fat_remove(): cannot remove <%s> from FS\n",
    37563864                pathname );
     
    37603868    // release lock and return success
    37613869    _spin_lock_release( &_fat.fat_lock );
     3870    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
    37623871
    37633872#if GIET_DEBUG_FAT
     
    38213930    }
    38223931
    3823     // take the lock
     3932    // takes the FAT lock and register it in thread context
     3933    static_scheduler_t*  psched = _get_sched();
     3934    unsigned int         ltid   = _get_thread_ltid();
    38243935    _spin_lock_acquire( &_fat.fat_lock );
     3936    _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT );
     3937
    38253938
    38263939    // get "old" and "old_parent" inode pointers
     
    38283941    {
    38293942        _spin_lock_release( &_fat.fat_lock );
     3943        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3944
    38303945        _printf("\n[FAT ERROR] _fat_rename(): <%s> not found\n", old_path );
    38313946        return GIET_FAT32_FILE_NOT_FOUND;
     
    38453960        {
    38463961            _spin_lock_release( &_fat.fat_lock );
     3962            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3963
    38473964            return GIET_FAT32_OK;
    38483965        }
     
    38593976    {
    38603977        _spin_lock_release( &_fat.fat_lock );
     3978        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3979
    38613980        _printf("\n[FAT ERROR] _fat_rename(): <%s> not found\n", new_path );
    38623981        return GIET_FAT32_FILE_NOT_FOUND;
     
    38673986    {
    38683987        _spin_lock_release( &_fat.fat_lock );
    3869         _printf("\n[FAT ERROR] _fat_rename(): can't move %s into its own subdirectory\n", old_path );
     3988        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3989
     3990        _printf("\n[FAT ERROR] _fat_rename(): can't move %s into  own directory\n", old_path );
    38703991        return GIET_FAT32_MOVE_INTO_SUBDIR;
    38713992    }
     
    38944015            {
    38954016                _spin_lock_release( &_fat.fat_lock );
     4017                _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     4018
    38964019                _printf("\n[FAT ERROR] _fat_rename(): cannot scan directory <%s>\n",
    38974020                        to_remove->name );
     
    39014024            {
    39024025                _spin_lock_release( &_fat.fat_lock );
     4026                _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     4027
    39034028                _printf("\n[FAT ERROR] _fat_rename(): directory <%s> not empty\n",
    39044029                        to_remove->name );
     
    39114036            {
    39124037                _spin_lock_release( &_fat.fat_lock );
     4038                _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     4039
    39134040                _printf("\n[FAT ERROR] _fat_rename(): file <%s> still referenced\n",
    39144041                        to_remove->name );
     
    39454072    {
    39464073        _spin_lock_release( &_fat.fat_lock );
     4074        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     4075
    39474076        _printf("\n[FAT ERROR] _fat_rename(): cannot add <%s> into <%s>\n",
    39484077                new->name , new_parent->name );
     
    39594088    {
    39604089        _spin_lock_release( &_fat.fat_lock );
     4090        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     4091
    39614092        _printf("\n[FAT ERROR] _fat_rename(): cannot update <%s> on device\n",
    39624093                    new_parent->name );
     
    39684099    {
    39694100        _spin_lock_release( &_fat.fat_lock );
     4101        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     4102
    39704103        _printf("\n[FAT ERROR] _fat_rename(): cannot remove <%s> from <%s>\n",
    39714104                old->name , old_parent->name );
     
    39854118    {
    39864119        _spin_lock_release( &_fat.fat_lock );
     4120        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     4121
    39874122        _printf("\n[FAT ERROR] _fat_rename(): cannot update <%s> on device\n",
    39884123                    old_parent->name );
     
    39964131        {
    39974132            _spin_lock_release( &_fat.fat_lock );
     4133            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     4134
    39984135            _printf("\n[FAT ERROR] _fat_rename(): cannot remove <%s> from FS\n",
    39994136                    to_remove->name );
     
    40044141    // release lock
    40054142    _spin_lock_release( &_fat.fat_lock );
     4143    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
    40064144
    40074145    return GIET_FAT32_OK;
     
    40524190    }
    40534191
    4054     // takes the lock
     4192    // takes the FAT lock and register it in thread context
     4193    static_scheduler_t*  psched = _get_sched();
     4194    unsigned int         ltid   = _get_thread_ltid();
    40554195    _spin_lock_acquire( &_fat.fat_lock );
    4056    
     4196    _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT );
     4197
    40574198    // get inode
    40584199    unsigned int code = _get_inode_from_path( pathname , &inode );
     
    40614202    {
    40624203        _spin_lock_release( &_fat.fat_lock );
     4204        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     4205
    40634206        _printf("\n[FAT ERROR] _fat_mkdir(): path to parent not found"
    40644207                " for directory <%s>\n", pathname );
     
    40684211    {
    40694212        _spin_lock_release( &_fat.fat_lock );
     4213        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     4214
    40704215        _printf("\n[FAT ERROR] _fat_mkdir(): one name in path too long"
    40714216                " for directory  <%s>\n", pathname );
     
    40754220    {
    40764221        _spin_lock_release( &_fat.fat_lock );
     4222        _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     4223
    40774224        _printf("\n[FAT ERROR] _fat_mkdir(): directory <%s> already exist\n",
    40784225                pathname );
     
    40984245        {
    40994246            _spin_lock_release( &_fat.fat_lock );
     4247            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     4248
    41004249            _printf("\n[FAT ERROR] _fat_mkdir(): no free cluster"
    41014250                    " for directory <%s>\n" , pathname );
     
    41274276        {
    41284277            _spin_lock_release( &_fat.fat_lock );
     4278            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     4279
    41294280            _printf("\n[FAT ERROR] _fat_mkdir(): cannot update parent directory"
    41304281                    " for directory <%s>\n" , pathname );
     
    41384289        {
    41394290            _spin_lock_release( &_fat.fat_lock );
     4291            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     4292
    41404293            _printf("\n[FAT ERROR] _fat_mkdir(): cannot update DATA region "
    41414294                    " for parent of directory <%s>\n", pathname );
     
    41494302        {
    41504303            _spin_lock_release( &_fat.fat_lock );
     4304            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     4305
    41514306            _printf("\n[FAT ERROR] _fat_mkdir(): cannot update FAT region"
    41524307                    " for directory <%s>\n", pathname );
     
    41584313        {
    41594314            _spin_lock_release( &_fat.fat_lock );
     4315            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     4316
    41604317            _printf("\n[FAT ERROR] _fat_mkdir(): cannot update FS-INFO"
    41614318                    " for directory <%s>\n", pathname );
     
    41694326        {
    41704327            _spin_lock_release( &_fat.fat_lock );
     4328            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     4329
    41714330            _printf("\n[FAT ERROR] _fat_mkdir(): cannot update DATA region"
    41724331                    " for directory <%s>\n", pathname );
     
    41774336    // release lock
    41784337    _spin_lock_release( &_fat.fat_lock );
     4338    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
    41794339
    41804340    return GIET_FAT32_OK;
     
    42934453        {
    42944454            // seek back to this entry
    4295             _spin_lock_acquire( &_fat.fat_lock );
    4296             _fat.fd[fd_id].seek -= DIR_ENTRY_SIZE;
    4297             _spin_lock_release( &_fat.fat_lock );
     4455            _atomic_increment( &_fat.fd[fd_id].seek , -DIR_ENTRY_SIZE );
    42984456
    42994457            return GIET_FAT32_NO_MORE_ENTRIES;
  • soft/giet_vm/giet_fat32/fat32.h

    r707 r709  
    226226
    227227extern int _fat_read( unsigned int fd_id,                  // file descriptor 
    228                       paddr_t buffer,                      // destination buffer
     228                      unsigned int vaddr,                  // destination buffer
    229229                      unsigned int count,                  // number of bytes
    230                       unsigned int phys );                 // use physical_memcpy
     230                      unsigned int extend );               // physical addressing
    231231
    232232extern int _fat_write( unsigned int fd_id,                 // file descriptor
    233                        void*        buffer,                        // source buffer
    234                        unsigned int count );               // number of bytes
     233                       unsigned int vaddr,                         // source buffer
     234                       unsigned int count,                 // number of bytes
     235                       unsigned int extend );              // physical addressing
    235236
    236237extern int _fat_lseek( unsigned int fd_id,                 // file descriptor
  • soft/giet_vm/giet_kernel/ctx_handler.c

    r707 r709  
    99#include <sys_handler.h>
    1010#include <giet_config.h>
     11#include <fat32.h>
    1112#include <hard_config.h>
    1213#include <utils.h>
    1314#include <tty0.h>
    1415#include <xcu_driver.h>
     16#include <bdv_driver.h>
    1517
    1618/////////////////////////////////////////////////////////////////////////////////
     
    1921
    2022// defined in giet_kernel/switch.s file
    21 extern void _task_switch(unsigned int *, unsigned int *);
     23extern void _thread_switch( thread_context_t* , thread_context_t* );
    2224
    2325// allocated in boot.c or kernel_init.c files
    2426extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
    2527
    26 
    27 ///////////////////////////////////////////////
    28 static void _ctx_kill_task( unsigned int ltid )
     28// allocated in kernel_init.c file
     29extern fat_desc_t  _fat;
     30
     31//////////////////////////////////////////////////////////////////
     32// This function is called by the _ctx_switch() function.
     33// It desactivates a thread that received a KILL signal.
     34// We must release all ressources allocated to the thread
     35// before the actual desactivation, that uses NORUN_MASK_THREAD.
     36//////////////////////////////////////////////////////////////////
     37static void _ctx_kill_thread( unsigned int x,
     38                              unsigned int y,
     39                              unsigned int p,
     40                              unsigned int ltid )
    2941{
    3042    // get scheduler address
    31     static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
    32 
    33     // pretend the task to kill is scheduled (required for sys_handler calls)
    34     unsigned int cur_task = psched->current;
     43    static_scheduler_t* psched = _schedulers[x][y][p];
     44
     45    // pretend the thread to kill is the currently scheduled thread
     46    // (required by the _sys_***_release() calls)
     47    unsigned int cur_thread = psched->current;
    3548    psched->current = ltid;
    3649
     50    // release BDV lock if taken and reset BDV peripheral
     51    if ( psched->context[ltid].slot[CTX_LOCKS_ID] & LOCKS_MASK_BDV )
     52    {
     53        _bdv_set_register( BLOCK_DEVICE_STATUS , 0 );
     54        _spin_lock_release( &_bdv_lock );
     55    }
     56
     57    // release FAT lock if taken
     58    if ( psched->context[ltid].slot[CTX_LOCKS_ID] & LOCKS_MASK_FAT )
     59    {
     60        _spin_lock_release( &_fat.fat_lock );
     61    }
     62
    3763    // release private TTY terminal if required
    38     if ( psched->context[ltid][CTX_TTY_ID] < NB_TTY_CHANNELS )
    39     {
    40         _sys_tty_release();
    41         psched->context[ltid][CTX_TTY_ID] = -1;
    42     }
     64    if ( psched->context[ltid].slot[CTX_TTY_ID] < NB_TTY_CHANNELS )
     65        _sys_tty_release();
    4366
    4467    // release private TIM channel if required
    45     if ( psched->context[ltid][CTX_TIM_ID] < NB_TIM_CHANNELS )
     68
     69    if ( psched->context[ltid].slot[CTX_TIM_ID] < NB_TIM_CHANNELS )
    4670    {
    4771        _sys_tim_release();
    48         psched->context[ltid][CTX_TIM_ID] = -1;
    49     }
    50 
    51     // release private NIC_RX channel if required
    52     if ( psched->context[ltid][CTX_NIC_RX_ID] < NB_NIC_CHANNELS )
     72    }
     73
     74    // release private NIC_RX and CMA_RX channels if required
     75    if ( psched->context[ltid].slot[CTX_NIC_RX_ID] < NB_NIC_CHANNELS )
    5376    {
    5477        _sys_nic_release( 1 );
    55         psched->context[ltid][CTX_NIC_RX_ID] = -1;
    56     }
    57 
    58     // release private NIC_TX channel if required
    59     if ( psched->context[ltid][CTX_NIC_TX_ID] < NB_NIC_CHANNELS )
     78    }
     79
     80    // release private NIC_TX and CMA_TX channels if required
     81    if ( psched->context[ltid].slot[CTX_NIC_TX_ID] < NB_NIC_CHANNELS )
    6082    {
    6183        _sys_nic_release( 0 );
    62         psched->context[ltid][CTX_NIC_TX_ID] = -1;
    6384    }
    6485
    6586    // release private FBF_CMA channel if required
    66     if ( psched->context[ltid][CTX_CMA_FB_ID] < NB_CMA_CHANNELS )
     87    if ( psched->context[ltid].slot[CTX_CMA_FB_ID] < NB_CMA_CHANNELS )
    6788    {
    6889        _sys_fbf_cma_release();
    69         psched->context[ltid][CTX_CMA_FB_ID] = -1;
    70     }
    71 
    72     // restore scheduled task
    73     psched->current = cur_task;
    74 
    75     // set NORUN_MASK_TASK bit
    76     _atomic_or( &psched->context[ltid][CTX_NORUN_ID], NORUN_MASK_TASK );
    77 
    78 } // end _ctx_kill_task()
    79 
    80 
    81 //////////////////////////////////
    82 void _ctx_display( unsigned int x,
    83                    unsigned int y,
    84                    unsigned int p,
    85                    unsigned int ltid,
    86                    char*        string )
    87 {
    88     static_scheduler_t* psched = _schedulers[x][y][p];
    89     _printf("\n########## task[%d,%d,%d,%d] context\n"
    90             " - CTX_EPC   = %x\n"
    91             " - CTX_PTAB  = %x\n"
    92             " - CTX_PTPR  = %x\n"
    93             " - CTX_VSID  = %x\n"
    94             " - CTX_SR    = %x\n"
    95             " - CTX_RA    = %x\n"
    96             " - CTX_SP    = %x\n"
    97             " - CTX_NORUN = %x\n"
    98             " - CTX_SIG   = %x\n"
    99             "########## %s\n",
    100             x , y , p , ltid ,
    101             psched->context[ltid][CTX_EPC_ID],
    102             psched->context[ltid][CTX_PTAB_ID],
    103             psched->context[ltid][CTX_PTPR_ID],
    104             psched->context[ltid][CTX_VSID_ID],
    105             psched->context[ltid][CTX_SR_ID],
    106             psched->context[ltid][CTX_RA_ID],
    107             psched->context[ltid][CTX_SP_ID],
    108             psched->context[ltid][CTX_NORUN_ID],
    109             psched->context[ltid][CTX_SIG_ID],
    110             string );
    111 }  // _ctx_display()
     90    }
     91
     92    // restore scheduled thread index
     93    psched->current = cur_thread;
     94
     95    // set NORUN_MASK_THREAD bit to desactivate the target thread
     96    psched->context[ltid].slot[CTX_NORUN_ID] = NORUN_MASK_THREAD;
     97
     98} // end _ctx_kill_thread()
    11299
    113100
    114101//////////////////
    115102void _ctx_switch()
    116 {
    117     unsigned int gpid       = _get_procid();
    118     unsigned int cluster_xy = gpid >> P_WIDTH;
    119     unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
    120 
    121     // get scheduler address
    122     static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
    123 
    124     // get number of tasks allocated to scheduler
    125     unsigned int tasks = psched->tasks;
    126 
    127     // get current task index
    128     unsigned int curr_task_id = psched->current;
    129 
    130     // select the next task using a round-robin policy
    131     unsigned int next_task_id;
    132     unsigned int tid;
    133     unsigned int found = 0;
    134 
    135     for (tid = curr_task_id + 1; tid < curr_task_id + 1 + tasks; tid++)
    136     {
    137         next_task_id = tid % tasks;
    138 
    139         // this task needs to be killed
    140         if ( psched->context[next_task_id][CTX_SIG_ID] & SIG_MASK_KILL )
    141         {
    142             // acknowledge signal
    143             _atomic_and( &psched->context[next_task_id][CTX_SIG_ID], ~SIG_MASK_KILL );
    144 
    145             _ctx_kill_task( next_task_id );
    146         }
    147 
    148         // test if the task is runable
    149         if ( psched->context[next_task_id][CTX_NORUN_ID] == 0 )
    150         {
    151             found = 1;
    152             // TODO: don't break to process all pending signals.
    153             break;
    154         }
    155     }
    156 
    157     // launch "idle" task if no runable task
    158     if (found == 0) next_task_id = IDLE_TASK_INDEX;
    159 
    160 #if ( GIET_DEBUG_SWITCH & 0x1 )
    161 unsigned int x = cluster_xy >> Y_WIDTH;
    162 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    163 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    164 _printf("\n[DEBUG SWITCH] (%d) -> (%d) on processor[%d,%d,%d] at cycle %d\n",
    165         curr_task_id, next_task_id, x, y , lpid, _get_proctime() );
    166 #endif
    167 
    168     if (curr_task_id != next_task_id)  // actual task switch required
    169     {
    170         unsigned int* curr_ctx_vaddr = &(psched->context[curr_task_id][0]);
    171         unsigned int* next_ctx_vaddr = &(psched->context[next_task_id][0]);
    172 
    173         // reset TICK timer counter.
    174         _xcu_timer_reset_cpt( cluster_xy, lpid );
    175 
    176         // set current task index
    177         psched->current = next_task_id;
    178 
    179         // makes context switch
    180         _task_switch( curr_ctx_vaddr , next_ctx_vaddr );
    181     }
    182 } //end _ctx_switch()
    183 
    184 
    185 /////////////////
    186 void _idle_task()
    187103{
    188104    unsigned int gpid       = _get_procid();
     
    192108    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
    193109
     110    unsigned int ltid;     // index for loops on threads in scheduler
     111
     112    // get calling thread scheduler address
     113    static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
     114
     115    // get number of threads allocated to scheduler
     116    unsigned int threads = psched->threads;
     117
     118    // get current thread ltid
     119    unsigned int curr_thread_id = psched->current;
     120
     121    // first loop on threads: handle all pending KILL signals
     122    for ( ltid = 0 ; ltid < threads ; ltid++ )
     123    {
     124        if ( psched->context[ltid].slot[CTX_SIGS_ID] & SIGS_MASK_KILL )
     125        {
     126            // acknowledge KILL signal
     127            _atomic_and( &psched->context[ltid].slot[CTX_SIGS_ID], ~SIGS_MASK_KILL );
     128
     129            // desactivate the killed thread
     130            _ctx_kill_thread( x , y , p , ltid );
     131        }
     132    }
     133
     134    // second loop: select next thread using a round-robin policy
     135    unsigned int next_thread_id;
     136    unsigned int found = 0;
     137    for ( ltid = curr_thread_id + 1 ; ltid < (curr_thread_id + 1 + threads) ; ltid++ )
     138    {
     139        next_thread_id = ltid % threads;
     140
     141        // test if the thread is runable
     142        if ( psched->context[next_thread_id].slot[CTX_NORUN_ID] == 0 )
     143        {
     144            found = 1;
     145            break;
     146        }
     147    }
     148
     149    // launch idle_thread if no runable thread
     150    if ( found == 0 ) next_thread_id = IDLE_THREAD_INDEX;
     151
     152    if ( curr_thread_id != next_thread_id )  // actual thread switch required
     153    {
     154
     155#if GIET_DEBUG_SWITCH
     156unsigned int x = cluster_xy >> Y_WIDTH;
     157unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     158if ( (_get_proctime() > GIET_DEBUG_SWITCH) && (x == 0) && (y == 0) && (p == 0) )
     159_printf("\n[DEBUG SWITCH] (%d) -> (%d) on processor[%d,%d,%d] at cycle %d\n",
     160        curr_thread_id, next_thread_id, x, y , p, _get_proctime() );
     161#endif
     162
     163        thread_context_t* curr_ctx_vaddr = &(psched->context[curr_thread_id]);
     164        thread_context_t* next_ctx_vaddr = &(psched->context[next_thread_id]);
     165
     166        // reset TICK timer counter.
     167        _xcu_timer_reset_cpt( cluster_xy, p );
     168
     169        // set current thread index
     170        psched->current = next_thread_id;
     171
     172        // makes context switch
     173        _thread_switch( curr_ctx_vaddr , next_ctx_vaddr );
     174    }
     175} //end _ctx_switch()
     176
     177
     178///////////////////
     179void _idle_thread()
     180{
     181    unsigned int gpid       = _get_procid();
     182    unsigned int cluster_xy = gpid >> P_WIDTH;
     183    unsigned int x          = cluster_xy >> Y_WIDTH;
     184    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
     185    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
     186
    194187    while(1)
    195188    {
    196189        // initialize counter
    197         unsigned int count = GIET_IDLE_TASK_PERIOD;
     190        unsigned int count = GIET_IDLE_THREAD_PERIOD;
    198191
    199192        // decounting loop
    200193        asm volatile(
    201194                "move   $3,   %0              \n"
    202                 "_idle_task_loop:             \n"
     195                "_idle_thread_loop:             \n"
    203196                "addi   $3,   $3,   -1        \n"
    204                 "bnez   $3,   _idle_task_loop \n"
     197                "bnez   $3,   _idle_thread_loop \n"
    205198                "nop                          \n"
    206199                :
  • soft/giet_vm/giet_kernel/ctx_handler.h

    r707 r709  
    66/////////////////////////////////////////////////////////////////////////////////
    77// The ctx_handler.h and ctx_handler.c files are part of the GIET-VM nano-kernel.
    8 // This code is used to support context switch when several tasks are executing
     8// This code is used to support context switch when several threads are executing
    99// in time multiplexing on a single processor.
    10 // The tasks are statically allocated to a processor in the boot phase, and
     10// The threads are statically allocated to a processor in the boot phase, and
    1111// there is one private scheduler per processor. Each sheduler occupies 8K bytes,
    12 // and contains up to 14 task contexts (task_id is from 0 to 13).
    13 // The task context [13] is reserved for the "idle" task that does nothing, and
    14 // is launched by the scheduler when there is no other runable task.
     12// and contains up to 14 thread contexts (thread_id is from 0 to 13).
     13// The thread context [13] is reserved for the "idle" thread that is
     14// launched by the scheduler when there is no other runable thread.
    1515/////////////////////////////////////////////////////////////////////////////////
    16 // A task context is an array of 64 uint32 words => 256 bytes.
    17 // It contains copies of processor registers (when the task is preempted)
    18 // and some general informations associated to a task, such as the private
    19 // peripheral channels allocated to the task, the vspace index, the various
    20 // task index (local / global / application), and the runnable status.
     16// A thread context is an array of 64 uint32 words => 256 bytes.
     17// It contains copies of processor registers (when the thread is preempted)
     18// and some general informations associated to a thread, such as the private
     19// peripheral channels allocated to the thread, the vspace index, the two
     20// thread index, and the runnable status.
    2121/////////////////////////////////////////////////////////////////////////////////
    2222// ctx[0] <- ***   |ctx[8] <- $8     |ctx[16]<- $16    |ctx[24]<- $24
     
    2424// ctx[2] <- $2    |ctx[10]<- $10    |ctx[18]<- $18    |ctx[26]<- LO
    2525// ctx[3] <- $3    |ctx[11]<- $11    |ctx[19]<- $19    |ctx[27]<- HI
    26 // ctx[4] <- $4    |ctx[12]<- $12    |ctx[20]<- $20    |ctx[28]<- $28
    27 // ctx[5] <- $5    |ctx[13]<- $13    |ctx[21]<- $21    |ctx[29]<- SP
    28 // ctx[6] <- $6    |ctx[14]<- $14    |ctx[22]<- $22    |ctx[30]<- $30
    29 // ctx[7] <- $7    |ctx[15]<- $15    |ctx[23]<- $23    |ctx[31]<- RA
     26// ctx[4] <- A0    |ctx[12]<- $12    |ctx[20]<- $20    |ctx[28]<- $28
     27// ctx[5] <- A1    |ctx[13]<- $13    |ctx[21]<- $21    |ctx[29]<- SP
     28// ctx[6] <- A2    |ctx[14]<- $14    |ctx[22]<- $22    |ctx[30]<- $30
     29// ctx[7] <- A3    |ctx[15]<- $15    |ctx[23]<- $23    |ctx[31]<- RA
    3030//
    3131// ctx[32]<- EPC   |ctx[40]<- TTY    |ctx[48]<- TRDID  |ctx[56]<- ***
    32 // ctx[33]<- CR    |ctx[41]<- CMA_FB |ctx[49]<- GTID   |ctx[57]<- ***
     32// ctx[33]<- CR    |ctx[41]<- CMA_FB |ctx[49]<- LTID   |ctx[57]<- ***
    3333// ctx[34]<- SR    |ctx[42]<- CMA_RX |ctx[50]<- NORUN  |ctx[58]<- ***
    3434// ctx[35]<- BVAR  |ctx[43]<- CMA_TX |ctx[51]<- COPROC |ctx[59]<- ***
    3535// ctx[36]<- PTAB  |ctx[44]<- NIC_RX |ctx[52]<- ENTRY  |ctx[60]<- ***
    36 // ctx[37]<- LTID  |ctx[45]<- NIC_TX |ctx[53]<- SIG    |ctx[61]<- ***
    37 // ctx[38]<- VSID  |ctx[46]<- TIM    |ctx[54]<- ***    |ctx[62]<- ***
    38 // ctx[39]<- PTPR  |ctx[47]<- HBA    |ctx[55]<- ***    |ctx[63]<- ***
     36// ctx[37]<- ***   |ctx[45]<- NIC_TX |ctx[53]<- SIGS   |ctx[61]<- ***
     37// ctx[38]<- ***   |ctx[46]<- TIM    |ctx[54]<- VSID   |ctx[62]<- ***
     38// ctx[39]<- PTPR  |ctx[47]<- HBA    |ctx[55]<- LOCKS  |ctx[63]<- ***
    3939/////////////////////////////////////////////////////////////////////////////////
    4040
     
    4545
    4646/////////////////////////////////////////////////////////////////////////////////
    47 //    Definition of the task context slots indexes
     47//    Definition of some thread context slots indexes
    4848/////////////////////////////////////////////////////////////////////////////////
     49
     50#define CTX_A0_ID        4     // Argument 0
     51#define CTX_A1_ID        5     // Argument 1
     52#define CTX_A2_ID        6     // Argument 2
     53#define CTX_A3_ID        7     // Argument 3
    4954
    5055#define CTX_SP_ID        29    // Stack Pointer
     
    5661#define CTX_BVAR_ID      35        // Bad Virtual Address Register (CP0)
    5762#define CTX_PTAB_ID      36    // Page Table Virtual address
    58 #define CTX_LTID_ID      37    // Local  Task Index (in scheduler)
    59 #define CTX_VSID_ID      38    // Vspace Index     
     63//                       37
     64//                       38
    6065#define CTX_PTPR_ID      39    // Page Table Pointer Register (PADDR>>13)
    6166
     
    6974#define CTX_HBA_ID       47    // private HBA channel index
    7075
    71 #define CTX_TRDID_ID     48    // Thread Task Index in vspace
    72 #define CTX_GTID_ID      49    // Global Task Index in all system
    73 #define CTX_NORUN_ID     50    // bit-vector : task runable if all zero
    74 #define CTX_COPROC_ID    51    // cluster_xy : coprocessor coordinates
    75 #define CTX_ENTRY_ID     52    // Virtual address of task entry point
    76 #define CTX_SIG_ID       53    // bit-vector : pending signals for task
     76#define CTX_TRDID_ID     48    // Global Thread Index ( x | y | p | ltid )
     77#define CTX_LTID_ID      49    // Local Thread Index in scheduler
     78#define CTX_NORUN_ID     50    // bit-vector : thread runable if all zero
     79#define CTX_COPROC_ID    51    // coprocessor coordinates (cluster_xy)
     80#define CTX_ENTRY_ID     52    // Virtual address of thread entry point
     81#define CTX_SIGS_ID      53    // bit-vector : pending signals
     82#define CTX_VSID_ID      54    // Vspace Index     
     83#define CTX_LOCKS_ID     55    // bit-vector : kernel locks taken
    7784
    7885/////////////////////////////////////////////////////////////////////////////////
     
    8087/////////////////////////////////////////////////////////////////////////////////
    8188
    82 #define NORUN_MASK_TASK       0x00000001   // Task not active 
     89#define NORUN_MASK_THREAD     0x00000001   // Task not active 
    8390#define NORUN_MASK_IOC        0x00000002   // Task blocked on IOC transfer
    8491#define NORUN_MASK_COPROC     0x00000004   // Task blocked on COPROC transfer
     92#define NORUN_MASK_TTY        0x00000008   // Task blocked on TTY_RX transfer
    8593
    8694/////////////////////////////////////////////////////////////////////////////////
    87 //    Definition of the SIG bit-vector masks
     95//    Definition of the SIGS bit-vector masks
    8896/////////////////////////////////////////////////////////////////////////////////
    8997
    90 #define SIG_MASK_KILL         0x00000001   // Task will be killed at next tick
     98#define SIGS_MASK_KILL        0x00000001   // Task desactivated at next tick
    9199
    92100/////////////////////////////////////////////////////////////////////////////////
    93 //    Definition of the scheduler structure
     101//    Definition of the LOCKS bit-vector masks
    94102/////////////////////////////////////////////////////////////////////////////////
    95103
    96 typedef struct static_scheduler_s
     104#define LOCKS_MASK_BDV        0x00000001   // BDV kernel lock taken
     105#define LOCKS_MASK_FAT        0x00000002   // FAT kernel lock taken
     106
     107/////////////////////////////////////////////////////////////////////////////////
     108//    Task context and  scheduler structures
     109/////////////////////////////////////////////////////////////////////////////////
     110
     111typedef struct thread_context_s             // 256 bytes
    97112{
    98     unsigned int context[14][64];      // at most 14 task (including idle_task)
    99     unsigned int tasks;                // actual number of tasks
    100     unsigned int current;              // current task index
    101     unsigned int hwi_vector[32];       // hardware interrupt vector
    102     unsigned int pti_vector[32];       // timer    interrupt vector
    103     unsigned int wti_vector[32];       // software interrupt vector
    104     unsigned int reserved[30];         // padding to 4 Kbytes
    105     unsigned int idle_stack[1024];     // private stack for idle stack (4Kbytes)
     113    unsigned int slot[64];     
     114} thread_context_t;
     115
     116
     117typedef struct static_scheduler_s           // 8 Kbytes
     118{
     119    thread_context_t  context[14];          // at most 14 threads (including idle_thread)
     120    unsigned int      threads;              // actual number of allocated threads
     121    unsigned int      current;              // current thread index
     122    unsigned int      hwi_vector[32];       // hardware interrupt vector
     123    unsigned int      pti_vector[32];       // timer    interrupt vector
     124    unsigned int      wti_vector[32];       // software interrupt vector
     125    unsigned int      reserved[30];         // padding to 4 Kbytes
     126    unsigned int      idle_stack[1024];     // private stack for idle stack (4Kbytes)
    106127} static_scheduler_t;
    107128
    108 #define IDLE_TASK_INDEX        13
     129#define IDLE_THREAD_INDEX        13
    109130
    110131
     
    114135
    115136/////////////////////////////////////////////////////////////////////////////////
    116 // This function performs a context switch between the running task
    117 // and  another task, using a round-robin sheduling policy between all
    118 // tasks allocated to a given processor (static allocation).
    119 // It selects the next runable task to resume execution.
    120 // If the only runable task is the current task, return without context switch.
    121 // If there is no runable task, the scheduler switch to the default "idle" task.
    122 // The return address contained in $31 is saved in the current task context
     137// This function performs a context switch between the running thread
     138// and  another thread, using a round-robin sheduling policy between all
     139// threads allocated to a given processor (static allocation).
     140// It selects the next runable thread to resume execution.
     141// If the only runable thread is the current thread, return without context switch.
     142// If there is no runable thread, the scheduler switch to the default "idle" thread.
     143// The return address contained in $31 is saved in the current thread context
    123144// (in the ctx[31] slot), and the function actually returns to the address
    124 // contained in the ctx[31] slot of the next task context.
     145// contained in the ctx[31] slot of the next thread context.
    125146/////////////////////////////////////////////////////////////////////////////////
    126147extern void _ctx_switch();
     
    128149/////////////////////////////////////////////////////////////////////////////////
    129150// The address of this function is used to initialise the return address
    130 // in the "idle" task context.
     151// in the "idle" thread context.
    131152/////////////////////////////////////////////////////////////////////////////////
    132153extern void _ctx_eret();
    133154
    134155/////////////////////////////////////////////////////////////////////////////////
    135 // This function is executed task when no other task can be executed.
     156// This function is executed thread when no other thread can be executed.
    136157/////////////////////////////////////////////////////////////////////////////////
    137 extern void _idle_task();
    138 
    139 /////////////////////////////////////////////////////////////////////////////////
    140 // This function displays the context of a task identified by the processor
    141 // coordinates (x,y,p), and by the local task index ltid.
    142 // The string argument can be used for debug.
    143 /////////////////////////////////////////////////////////////////////////////////
    144 extern void _ctx_display( unsigned int x,
    145                           unsigned int y,
    146                           unsigned int p,
    147                           unsigned int ltid,
    148                           char*        string );
     158extern void _idle_thread();
    149159
    150160#endif
  • soft/giet_vm/giet_kernel/exc_handler.c

    r629 r709  
    6161    unsigned int x          = cluster_xy >> Y_WIDTH;
    6262    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    63     unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
     63    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
     64    unsigned int trdid      = _get_thread_trdid();
     65    unsigned int ltid       = _get_thread_ltid();
    6466
    65     unsigned int task       = _get_context_slot(CTX_LTID_ID);
    66 
     67    static_scheduler_t*  psched = (static_scheduler_t*)_get_sched();
    6768
    6869    const char * mips32_exc_str[] = { "strange unknown cause  ",
     
    7475                                      "reserved instruction   ",
    7576                                      "illegal coproc access  ",
    76                                       "arithmetic overflow    "};
     77                                      "arithmetic overflow    " };
    7778
    78     _printf("\n[GIET] Exception for task %d on processor[%d,%d,%d] at cycle %d\n"
     79    _printf("\n[GIET] Exception for thread %x on processor[%d,%d,%d] at cycle %d\n"
    7980            " - type      : %s\n"
    8081            " - EPC       : %x\n"
    8182            " - BVAR      : %x\n"
    82             "...Task desactivated\n",
    83             task, x, y, lpid, _get_proctime(),
     83            "...Thread desactivated\n",
     84            trdid , x , y , p , _get_proctime(),
    8485            mips32_exc_str[type], _get_epc(), _get_bvar() );
    8586
    86     // goes to sleeping state
    87     _set_context_slot( CTX_NORUN_ID , 1 );
     87    // register KILL signal
     88    _atomic_or( &psched->context[ltid].slot[CTX_SIGS_ID] , SIGS_MASK_KILL );
    8889
    89     // deschedule
     90    // deschedule calling thread
    9091    unsigned int save_sr; 
    9192    _it_disable( &save_sr );
  • soft/giet_vm/giet_kernel/irq_handler.c

    r702 r709  
    2626#include <tty0.h>
    2727
     28////////////////////////////////////////////////////////////////////////////
     29//        Extern variables
     30////////////////////////////////////////////////////////////////////////////
     31
     32// allocated in sys_handler.c file
     33extern unsigned int _tty_channel_wti[NB_TTY_CHANNELS];
     34extern unsigned int _tim_channel_wti[NB_TIM_CHANNELS];
     35extern unsigned int _cma_channel_wti[NB_CMA_CHANNELS];
     36extern unsigned int _nic_rx_channel_wti[NB_NIC_CHANNELS];
     37extern unsigned int _nic_tx_channel_wti[NB_NIC_CHANNELS];
     38
    2839/////////////////////////////////////////////////////////////////////////
    2940//       Global variables
     
    4152__attribute__((section(".kdata")))
    4253unsigned char _wti_alloc_ter[X_SIZE][Y_SIZE][NB_PROCS_MAX];
     54
     55#define MAX_RETRY   10000
    4356
    4457/////////////////////////////////////////////////////////////////////////
     
    134147}  // end _ext_irq_init()
    135148
    136 ////////////////////////////////////////////
     149/////////////////////////////////////////////
    137150void _ext_irq_alloc( unsigned int   isr_type,
    138151                     unsigned int   isr_channel,
     
    143156    unsigned int wti_addr;      // WTI mailbox physical address (32 lsb bits)
    144157
    145     // check arguments
     158    unsigned int count = MAX_RETRY;
     159
     160    // check input arguments
    146161    if ( isr_type >= GIET_ISR_TYPE_MAX )
    147162    {
     
    163178
    164179    // allocate a WTI mailbox to proc[x,y,p] (blocking until success)
     180   
    165181    while ( 1 )
    166182    {
     183        if ( count == 0 )
     184        {
     185            unsigned int trdid = _get_context_slot( CTX_TRDID_ID );
     186            unsigned int vsid  = _get_context_slot( CTX_VSID_ID );
     187            _printf("\n[GIET WARNING] thread %x in vspace %d "
     188                    "running on P[%d,%d,%d] still waiting in _ext_irq_alloc()\n",
     189                    trdid, vsid, x, y, p );
     190            count = MAX_RETRY;
     191        }
     192
    167193        if ( _wti_alloc_one[x][y][p] == 0 )
    168194        {
     
    183209            break;
    184210        }
     211        count--;
    185212    }   
     213
    186214    *wti_index = wti_id;
    187215
     
    196224
    197225#if GIET_DEBUG_IRQS
     226if ( _get_proctime() > GIET_DEBUG_IRQS )
    198227_printf("\n[DEBUG IRQS] _ext_irq_alloc() for P[%d,%d,%d] at cycle %d\n"
    199228        "  wti_id = %d / isr_type = %s / channel = %d / pic_input = %d\n",
     
    204233}  // end ext_irq_alloc()
    205234
    206 ////////////////////////////////////////////
     235////////////////////////////////////////////////
    207236void _ext_irq_release( unsigned int isr_type,
    208                        unsigned int isr_channel )
    209 {
    210     unsigned int wti_id;        // allocated WTI mailbox index in XCU
    211     unsigned int irq_id;        // external IRQ index in PIC (input)
    212 
    213     // get processor coordinates [x,y,p]
    214     unsigned int gpid           = _get_procid();
    215     unsigned int cluster_xy     = gpid >> P_WIDTH;
    216     unsigned int x              = cluster_xy >> Y_WIDTH;
    217     unsigned int y              = cluster_xy & ((1<<Y_WIDTH)-1);
    218     unsigned int p              = gpid & ((1<<P_WIDTH)-1);
    219 
    220     // check arguments
     237                       unsigned int channel )
     238{
     239    // check input arguments
    221240    if ( isr_type >= GIET_ISR_TYPE_MAX )
    222241    {
    223         _printf("\n[GIET ERROR] in _ext_irq_release() illegal ISR type\n");
    224         _exit();
    225     }
    226     if ( isr_channel >= GIET_ISR_CHANNEL_MAX )
    227     {
    228         _printf("\n[GIET ERROR] in _ext_irq_release() : illegal ISR channel\n");
    229         _exit();
    230     }
    231 
    232     // find WTI index
    233     static_scheduler_t*  psched = (static_scheduler_t*)_get_sched();
    234     for ( wti_id = 0 ; wti_id < 32 ; wti_id++ )
    235     {
    236         if ( psched->wti_vector[wti_id] == (isr_channel<<16 | isr_type) )
    237             break;
    238     }
    239     if ( wti_id == 32 )
    240     {
    241         _printf("\n[GIET ERROR] in _ext_irq_release() : isr not found\n");
    242         return;
    243     }
    244 
     242        _printf("\n[GIET ERROR] in _ext_irq_release() : "
     243                "illegal ISR type %d\n", isr_type );
     244        _exit();
     245    }
     246    if ( channel >= GIET_ISR_CHANNEL_MAX )
     247    {
     248        _printf("\n[GIET ERROR] in _ext_irq_release() : "
     249                "illegal ISR channel %d\n", channel );
     250        _exit();
     251    }
     252
     253    // analyse ISR type to get WTI index (wti), and coordinates
     254    // of processor (x,y,p) that has been allocated the external IRQ
     255    unsigned int wti    = 0;
     256    unsigned int x      = 0;
     257    unsigned int y      = 0;
     258    unsigned int p      = 0;
     259
     260    if      ( (isr_type == ISR_TTY_RX) || (isr_type == ISR_TTY_TX) )
     261    {
     262        x       = (_tty_channel_wti[channel]>>24) & 0xFF;
     263        y       = (_tty_channel_wti[channel]>>16) & 0xFF;
     264        p       = (_tty_channel_wti[channel]>> 8) & 0xFF;
     265        wti     = (_tty_channel_wti[channel]    ) & 0xFF;
     266    }
     267#if NB_TIM_CHANNELS
     268    else if ( isr_type == ISR_TIMER )
     269    {
     270        x       = (_tim_channel_wti[channel]>>24) & 0xFF;
     271        y       = (_tim_channel_wti[channel]>>16) & 0xFF;
     272        p       = (_tim_channel_wti[channel]>> 8) & 0xFF;
     273        wti     = (_tim_channel_wti[channel]    ) & 0xFF;
     274    }
     275#endif
     276#if NB_CMA_CHANNELS
     277    else if ( isr_type == ISR_CMA )
     278    {
     279        x       = (_cma_channel_wti[channel]>>24) & 0xFF;
     280        y       = (_cma_channel_wti[channel]>>16) & 0xFF;
     281        p       = (_cma_channel_wti[channel]>> 8) & 0xFF;
     282        wti     = (_cma_channel_wti[channel]    ) & 0xFF;
     283    }
     284#endif
     285#if NB_NIC_CHANNELS
     286    else if ( isr_type == ISR_NIC_RX )
     287    {
     288        x       = (_nic_rx_channel_wti[channel]>>24) & 0xFF;
     289        y       = (_nic_rx_channel_wti[channel]>>16) & 0xFF;
     290        p       = (_nic_rx_channel_wti[channel]>> 8) & 0xFF;
     291        wti     = (_nic_rx_channel_wti[channel]    ) & 0xFF;
     292    }
     293    else if ( isr_type == ISR_NIC_TX )
     294    {
     295        x       = (_nic_tx_channel_wti[channel]>>24) & 0xFF;
     296        y       = (_nic_tx_channel_wti[channel]>>16) & 0xFF;
     297        p       = (_nic_tx_channel_wti[channel]>> 8) & 0xFF;
     298        wti     = (_nic_tx_channel_wti[channel]    ) & 0xFF;
     299    }
     300#endif
     301    else 
     302    {
     303        _printf("\n[GIET ERROR] in _ext_irq_release() : "
     304                "ISR type %s not supported / thread = %x\n",
     305                _isr_type_str[isr_type] , _get_thread_trdid() );
     306        _exit();
     307    }
     308   
    245309    // desactivates dynamically allocated PIC entry
    246     irq_id = _ext_irq_index[isr_type][isr_channel];
     310    unsigned int irq_id = _ext_irq_index[isr_type][channel];
    247311    _pic_set_register( irq_id , IOPIC_MASK , 0 );
    248312
    249313    // releases dynamically allocated WTI mailbox
    250     if      ( wti_id == p +   NB_PROCS_MAX ) _wti_alloc_one[x][y][p] = 0;
    251     else if ( wti_id == p + 2*NB_PROCS_MAX ) _wti_alloc_two[x][y][p] = 0;
    252     else if ( wti_id == p + 3*NB_PROCS_MAX ) _wti_alloc_ter[x][y][p] = 0;
     314    if      ( wti == p +   NB_PROCS_MAX ) _wti_alloc_one[x][y][p] = 0;
     315    else if ( wti == p + 2*NB_PROCS_MAX ) _wti_alloc_two[x][y][p] = 0;
     316    else if ( wti == p + 3*NB_PROCS_MAX ) _wti_alloc_ter[x][y][p] = 0;
    253317    else
    254318    {
    255         _printf("\n[GIET ERROR] in _ext_irq_release() : illegal WTI index\n");
     319        _printf("\n[GIET ERROR] in _ext_irq_release() : "
     320                "WTI = %d / X = %d / Y = %d / P = %d\n", wti , x, y , p );
    256321        _exit();
    257322    }
     
    294359
    295360#if GIET_DEBUG_IRQS    // we don't take the TTY lock to avoid deadlocks
     361if ( _get_proctime() > GIET_DEBUG_IRQS )
    296362_nolock_printf("\n[DEBUG IRQS] _irq_demux() Processor[%d,%d,%d] enters at cycle %d\n"
    297363               " irq_type = %s / irq_id = %d / isr_type = %s / channel = %d\n",
     
    360426
    361427    unsigned int value;     // WTI mailbox value
    362     unsigned int save_sr;   // save SR value in pre-empted task stack
    363 
    364     unsigned int ltid       = _get_current_task_id();
     428    unsigned int save_sr;   // save SR value in pre-empted thread stack
     429
     430    unsigned int ltid       = _get_thread_ltid();
    365431
    366432    if ( irq_type != IRQ_TYPE_WTI )
     
    375441    _xcu_get_wti_value( cluster_xy, irq_id, &value );
    376442
    377 #if GIET_DEBUG_SWITCH
    378 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] enters _isr_wakup() at cycle %d\n"
     443#if GIET_DEBUG_IRQS
     444if ( _get_proctime() > GIET_DEBUG_IRQS )
     445_printf("\n[DEBUG IRQS] P[%d,%d,%d] enters _isr_wakup() at cycle %d\n"
    379446        "  WTI index = %d / current ltid = %d / mailbox value = %x\n",
    380447        x , y , p , _get_proctime() , irq_id , ltid , value );
     
    382449
    383450    // enter critical section and swich context (if required)
    384     if ( (ltid == IDLE_TASK_INDEX) || (value != 0) )
     451    if ( (ltid == IDLE_THREAD_INDEX) || (value != 0) )
    385452    {
    386453        _it_disable( &save_sr );
     
    402469    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
    403470
    404     unsigned int save_sr;   // save SR value in pre-empted task stack
     471    unsigned int save_sr;   // save SR value in pre-empted thread stack
    405472
    406473    if ( irq_type != IRQ_TYPE_PTI )
     
    415482    _xcu_timer_reset_irq( cluster_xy, irq_id );
    416483
    417 #if (GIET_DEBUG_SWITCH & 0x1)
    418 unsigned int ltid  = _get_current_task_id();
    419 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    420 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] enters _isr_tick() at cycle %d\n"
     484#if GIET_DEBUG_IRQS
     485unsigned int ltid  = _get_thread_ltid();
     486if ( _get_proctime() > GIET_DEBUG_IRQS )
     487_printf("\n[DEBUG IRQS] P[%d,%d,%d] enters _isr_tick() at cycle %d\n"
    421488        "  WTI index = %d / current ltid = %d\n",
    422489        x , y , p , _get_proctime() , irq_id , ltid );
  • soft/giet_vm/giet_kernel/kernel_init.c

    r688 r709  
    2323#include <bdv_driver.h>
    2424#include <mmc_driver.h>
     25#include <tty_driver.h>
    2526#include <ctx_handler.h>
    2627#include <irq_handler.h>
     28#include <sys_handler.h>
    2729#include <mapping_info.h>
    2830#include <mips32_registers.h>
     
    6062#endif
    6163
    62 #if !defined(IDLE_TASK_INDEX)
    63 # error: You must define IDLE_TASK_INDEX in the ctx_handler.h file
     64#if !defined(IDLE_THREAD_INDEX)
     65# error: You must define IDLE_THREAD_INDEX in the ctx_handler.h file
    6466#endif
    6567
     
    109111volatile unsigned int _kernel_init_done = 0;
    110112
    111 // Kernel uses sqt_lock to protect TTY0       
     113// Kernel uses a sqt_lock to protect TTY0       
    112114__attribute__((section(".kdata")))
    113115unsigned int   _tty0_boot_mode = 0;
    114116
    115 // Kernel uses sqt_lock to protect command allocator in HBA       
     117// Kernel uses a sqt_lock to protect command allocator in HBA       
    116118__attribute__((section(".kdata")))
    117119unsigned int   _hba_boot_mode = 0;
     
    125127////////////////////////////////////////////////////////////////////////////////
    126128
    127 // this variable is defined in tty0.c file
     129// this variable is allocated in tty0.c file
    128130extern sqt_lock_t _tty0_sqt_lock;
    129131
    130 // this variable is allocated in mmc_kernel.c
     132// this variable is allocated in mmc_driver.c file
    131133extern unsigned int _mmc_boot_mode;
    132134
    133 ////////////////////////////////////////////////////////////////////////////////
    134 // This kernel_init() function completes the kernel initialisation in 6 steps:
     135// this variable is allocated in sys_handler.c file
     136extern unsigned int _tty_channel_alloc[NB_TTY_CHANNELS];
     137
     138////////////////////////////////////////////////////////////////////////////////
     139// This kernel_init() function completes the kernel initialisation in 5 steps:
    135140// Step 0 is done by processor[0,0,0]. Steps 1 to 4 are executed in parallel
    136141// by all processors.
     
    138143// - step 1 : Each processor initialises scheduler pointers array.
    139144// - step 2 : Each processor initialises PTAB pointers arrays.
    140 // - step 3 : Each processor initialise idle task and starts TICK timer.
     145// - step 3 : Each processor initialise idle thread and starts TICK timer.
    141146// - step 4 : Each processor set sp, sr, ptpr, epc registers values.
    142147////////////////////////////////////////////////////////////////////////////////
     
    165170_nolock_printf("\n[DEBUG KINIT] P[%d,%d,%d] completes kernel heap init\n", x, y, p );
    166171#endif
    167         //////  distributed lock for MMC
     172        //////  distributed locks for MMC
    168173        _mmc_boot_mode = 0;
    169174        _mmc_init_locks();
    170175
    171176#if GIET_DEBUG_INIT
    172 _nolock_printf("\n[DEBUG KINIT] P[%d,%d,%d] completes MMC distributed lock init\n", x , y , p );
     177_nolock_printf("\n[DEBUG KINIT] P[%d,%d,%d] completes MMC distributed locks init\n", x , y , p );
    173178#endif
    174179        //////  distributed lock for TTY0
    175180        _sqt_lock_init( &_tty0_sqt_lock );
     181        _tty_channel_alloc[0] = 1;
    176182
    177183#if GIET_DEBUG_INIT
     
    183189#if GIET_DEBUG_INIT
    184190_nolock_printf("\n[DEBUG KINIT] P[%d,%d,%d] completes barrier init\n", x , y , p );
     191#endif
     192
     193        //////  TTY fifos initialisation
     194        unsigned int tty_id;
     195        for ( tty_id = 0 ; tty_id < NB_TTY_CHANNELS ; tty_id++) _tty_init( tty_id );
     196
     197#if GIET_DEBUG_INIT
     198_nolock_printf("\n[DEBUG KINIT] P[%d,%d,%d] completes TTY fifos init\n", x , y , p );
    185199#endif
    186200
     
    245259
    246260    static_scheduler_t* psched     = (static_scheduler_t*)_get_sched();
    247     unsigned int        tasks      = psched->tasks;
     261    unsigned int        threads    = psched->threads;
    248262
    249263    _schedulers[x][y][p] = psched;
     
    252266_printf("\n[DEBUG KINIT] P[%d,%d,%d] initialises SCHED array\n"
    253267        " - scheduler vbase = %x\n"
    254         " - tasks           = %d\n",
    255         x, y, p, (unsigned int)psched, tasks );
     268        " - threads         = %d\n",
     269        x, y, p, (unsigned int)psched, threads );
    256270#endif
    257271
     
    261275
    262276    ////////////////////////////////////////////////////////////////////////////
    263     // step 2 : each processor that is allocated at least one task loops
    264     //          on its allocated tasks:
    265     //          - contributes to _ptabs_vaddr[][][] & _ptabs_ptprs[][][]
    266     //            initialisation, from values stored in the tasks contexts.
     277    // step 2 : each processor that is allocated at least one thread loops
     278    //          on its allocated threads:
     279    //          - contributes to _ptabs_vaddr & _ptabs_ptprs arrays
     280    //            initialisation, from values stored in the threads contexts.
    267281    //          - set CTX_RA slot  with the kernel _ctx_eret() virtual address.
    268     //          - set CTX_ENTRY slot that must contain the task entry point,
    269     //            and contain only at this point the virtual address of the
    270     //            memory word containing this entry point.
     282    //          - set CTX_ENTRY & CTX_EPC slots that must contain the thread
     283    //            entry point. The CTX_ENTRY slot contain only at this point
     284    //            a pointer on the memory word containing this entry point.
    271285    ////////////////////////////////////////////////////////////////////////////
    272286
    273287    unsigned int ltid;
    274288
    275     for (ltid = 0; ltid < tasks; ltid++)
     289    for (ltid = 0; ltid < threads; ltid++)
    276290    {
    277         unsigned int vsid = _get_task_slot( x, y, p, ltid , CTX_VSID_ID );
    278         unsigned int ptab = _get_task_slot( x, y, p, ltid , CTX_PTAB_ID );
    279         unsigned int ptpr = _get_task_slot( x, y, p, ltid , CTX_PTPR_ID );
     291        unsigned int vsid = _get_thread_slot( x, y, p, ltid , CTX_VSID_ID );
     292        unsigned int ptab = _get_thread_slot( x, y, p, ltid , CTX_PTAB_ID );
     293        unsigned int ptpr = _get_thread_slot( x, y, p, ltid , CTX_PTPR_ID );
    280294
    281295        // initialize PTABS arrays
     
    289303        // set CTX_RA slot
    290304        unsigned int ctx_ra = (unsigned int)(&_ctx_eret);
    291         _set_task_slot( x, y, p, ltid, CTX_RA_ID, ctx_ra );
    292 
    293         // set CTX_ENTRY slot
    294         unsigned int* ptr = (unsigned int*)_get_task_slot(x , y , p , ltid , CTX_ENTRY_ID);
     305        _set_thread_slot( x, y, p, ltid, CTX_RA_ID, ctx_ra );
     306
     307        // set CTX_ENTRY and CTX_EPC slots
     308        unsigned int* ptr = (unsigned int*)_get_thread_slot(x , y , p , ltid , CTX_ENTRY_ID);
    295309        unsigned int ctx_entry = *ptr;
    296         _set_task_slot( x , y , p , ltid , CTX_ENTRY_ID , ctx_entry );
     310        _set_thread_slot( x , y , p , ltid , CTX_ENTRY_ID , ctx_entry );
     311        _set_thread_slot( x , y , p , ltid , CTX_EPC_ID , ctx_entry );
    297312
    298313#if GIET_DEBUG_INIT
    299314_printf("\n[DEBUG KINIT] P[%d,%d,%d] initialises PTABS arrays"
    300         " and context for task %d \n"
     315        " and context for thread %d \n"
    301316        " - ptabs_vaddr[%d][%d][%d] = %x\n"
    302317        " - ptabs_paddr[%d][%d][%d] = %l\n"
     
    309324#endif
    310325
    311     }  // end for tasks
     326    }  // end for threads
    312327
    313328    /////////////////////////////////////////
     
    316331
    317332    ////////////////////////////////////////////////////////////////////////////
    318     // step 3 : - Each processor complete idle task context initialisation.
     333    // step 3 : - Each processor complete idle thread context initialisation.
    319334    //            Only CTX_SP, CTX_RA, CTX_EPC, CTX_ENTRY slots, because other
    320335    //            slots have been initialised in boot code)
    321336    //            The 4 Kbytes idle stack is implemented in the scheduler itself.
    322     //          - Each processor starts TICK timer, if at least one task.
     337    //          - Each processor starts TICK timer, if at least one thread.
    323338    //          - P[0,0,0] initialises FAT (not done before, because it must
    324339    //            be done after the _ptabs_vaddr[v][x][y] array initialisation,
     
    328343    unsigned int sp    = ((unsigned int)psched) + 0x2000;
    329344    unsigned int ra    = (unsigned int)(&_ctx_eret);
    330     unsigned int entry = (unsigned int)(&_idle_task);
    331 
    332     _set_task_slot( x , y , p , IDLE_TASK_INDEX , CTX_SP_ID  , sp    );
    333     _set_task_slot( x , y , p , IDLE_TASK_INDEX , CTX_RA_ID  , ra    );
    334     _set_task_slot( x , y , p , IDLE_TASK_INDEX , CTX_EPC_ID , entry );
    335     _set_task_slot( x , y , p , IDLE_TASK_INDEX , CTX_ENTRY_ID , entry );
    336 
    337     if (tasks > 0) _xcu_timer_start( cluster_xy, p, GIET_TICK_VALUE );
    338 
    339 #if GIET_DEBUG_INIT
    340 _printf("\n[DEBUG KINIT] P[%d,%d,%d] initializes idle_task and starts TICK\n", 
     345    unsigned int entry = (unsigned int)(&_idle_thread);
     346
     347    _set_thread_slot( x , y , p , IDLE_THREAD_INDEX , CTX_SP_ID  , sp    );
     348    _set_thread_slot( x , y , p , IDLE_THREAD_INDEX , CTX_RA_ID  , ra    );
     349    _set_thread_slot( x , y , p , IDLE_THREAD_INDEX , CTX_EPC_ID , entry );
     350    _set_thread_slot( x , y , p , IDLE_THREAD_INDEX , CTX_ENTRY_ID , entry );
     351
     352    if (threads > 0) _xcu_timer_start( cluster_xy, p, GIET_TICK_VALUE );
     353
     354#if GIET_DEBUG_INIT
     355_printf("\n[DEBUG KINIT] P[%d,%d,%d] initializes idle_thread and starts TICK\n", 
    341356        x, y, p );
    342357#endif
     
    358373
    359374    ////////////////////////////////////////////////////////////////////////////
    360     // step 4 : Each processor computes the task index (ltid), and the values
     375    // step 4 : Each processor computes the thread index (ltid), and the values
    361376    //          to initialize the SP, SR, PTPR, EPC registers.
    362     //          It jumps to a runable task if possible, and jumps to IDLE-TASK
    363     //          if no task allocated or no runable task.
    364     ////////////////////////////////////////////////////////////////////////////
    365 
    366     if (tasks == 0) _printf("\n[GIET WARNING] No task allocated to P[%d,%d,%d]\n",
     377    //          It jumps to a runable thread if possible,
     378    //          or jumps to IDLE-THREAD if no runable thread.
     379    ////////////////////////////////////////////////////////////////////////////
     380
     381    if (threads == 0) _printf("\n[GIET WARNING] No thread allocated to P[%d,%d,%d]\n",
    367382                            x, y, p );
    368383
    369384    // default value for ltid
    370     ltid = IDLE_TASK_INDEX;
    371 
    372     // scan allocated tasks to find a runable task
    373     unsigned int  task_id;
    374     for ( task_id = 0 ; task_id < tasks ; task_id++ )
     385    ltid = IDLE_THREAD_INDEX;
     386
     387    // scan allocated threads to find a runable thread
     388    unsigned int  thread_id;
     389    for ( thread_id = 0 ; thread_id < threads ; thread_id++ )
    375390    {
    376         if ( _get_task_slot( x, y, p, task_id, CTX_NORUN_ID ) == 0 )
     391        if ( _get_thread_slot( x, y, p, thread_id, CTX_NORUN_ID ) == 0 )
    377392        {
    378             ltid = task_id;
     393            ltid = thread_id;
    379394            break;
    380395        }
     
    384399    psched->current = ltid;
    385400
    386     // get values from selected task context
    387     unsigned int sp_value   = _get_task_slot( x, y, p, ltid, CTX_SP_ID);
    388     unsigned int sr_value   = _get_task_slot( x, y, p, ltid, CTX_SR_ID);
    389     unsigned int ptpr_value = _get_task_slot( x, y, p, ltid, CTX_PTPR_ID);
    390     unsigned int epc_value  = _get_task_slot( x, y, p, ltid, CTX_ENTRY_ID);
     401    // get values from selected thread context
     402    unsigned int sp_value   = _get_thread_slot( x, y, p, ltid, CTX_SP_ID);
     403    unsigned int sr_value   = _get_thread_slot( x, y, p, ltid, CTX_SR_ID);
     404    unsigned int ptpr_value = _get_thread_slot( x, y, p, ltid, CTX_PTPR_ID);
     405    unsigned int epc_value  = _get_thread_slot( x, y, p, ltid, CTX_ENTRY_ID);
    391406
    392407#if GIET_DEBUG_INIT
  • soft/giet_vm/giet_kernel/switch.s

    r301 r709  
    11/******************************************************************************
    2 * This function receives two arguments that are the current task context
    3 * (virtual) addresses and the next task context (virtual) address.
     2* This function receives two arguments that are the current thread context
     3* (virtual) addresses and the next thread context (virtual) address.
    44*
    55* This function should be called in a critical section
     
    1515******************************************************************************/
    1616
    17     .globl  _task_switch
    18     .func   _task_switch
    19     .type   _task_switch, %function
     17    .globl  _thread_switch
     18    .func   _thread_switch
     19    .type   _thread_switch, %function
    2020
    21 _task_switch:
     21_thread_switch:
    2222
    23     /* save _current task context */
    24     add     $27,    $4,     $0  /* $27 <= &context[curr_task_id] */
     23    /* first step : save current thread context */
     24    add     $27,    $4,     $0  /* $27 <= &context[current] */
    2525
    2626    .set noat
     
    7070    sw      $26,    39*4($27)   /* ctx[35] <= PTPR */
    7171
    72     /* restore next task context */
    73     add     $27,    $5,     $0  /* $27<= &context[next_task_id] */
     72    /* second step : restore next thread context */
     73    add     $27,    $5,     $0  /* $27<= &context[next] */
    7474
    7575    .set noat
     
    123123
    124124    .endfunc
    125     .size _task_switch, .-_task_switch
     125    .size _thread_switch, .-_thread_switch
    126126
  • soft/giet_vm/giet_kernel/sys_handler.c

    r707 r709  
    2626#include <io.h>
    2727
     28#if !defined(X_SIZE)
     29# error: You must define X_SIZE in the hard_config.h file
     30#endif
     31
     32#if !defined(Y_SIZE)
     33# error: You must define Y_SIZE in the hard_config.h file
     34#endif
     35
     36#if !defined(NB_PROCS_MAX)
     37# error: You must define NB_PROCS_MAX in the hard_config.h file
     38#endif
     39
    2840#if !defined(SEG_BOOT_MAPPING_BASE)
    2941# error: You must define SEG_BOOT_MAPPING_BASE in the hard_config.h file
     
    7587extern unsigned int   _coproc_mode[X_SIZE*Y_SIZE];
    7688extern unsigned int   _coproc_error[X_SIZE*Y_SIZE];
    77 extern unsigned int   _coproc_gtid[X_SIZE*Y_SIZE];
    78 
     89extern unsigned int   _coproc_trdid[X_SIZE*Y_SIZE];
    7990
    8091// allocated in tty_driver.c file.
    81 extern unsigned int _tty_rx_full[NB_TTY_CHANNELS];
    82 extern unsigned int _tty_rx_buf[NB_TTY_CHANNELS];
     92extern tty_fifo_t   _tty_rx_fifo[NB_TTY_CHANNELS];
    8393
    8494// allocated in kernel_init.c file
    8595extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
    8696
    87 ////////////////////////////////////////////////////////////////////////////
    88 //     Channel allocators for peripherals
    89 //     (TTY[0] is reserved for kernel)
    90 ////////////////////////////////////////////////////////////////////////////
    91 
     97////////////////////////////////////////////////////////////////////////////////
     98//     Channel allocators for multi-channels peripherals
     99// - The array _***_channel_allocator[channel] defines the number of user
     100//   threads for a dynamically allocated channel of peripheral ***.
     101// - The array _***_channel_wti[channel] defines the WTI index and the
     102//   processor coordinates for the processor receiving the channel WTI.
     103////////////////////////////////////////////////////////////////////////////////
     104
     105#if NB_TTY_CHANNELS
    92106__attribute__((section(".kdata")))
    93 unsigned int _tty_channel[NB_TTY_CHANNELS]  = {1};
     107unsigned int _tty_channel_alloc[NB_TTY_CHANNELS] = {0};
    94108
    95109__attribute__((section(".kdata")))
    96 unsigned int _tim_channel_allocator    = 0;
    97 
     110unsigned int _tty_channel_wti[NB_TTY_CHANNELS];
     111#endif
     112
     113#if NB_TIM_CHANNELS
    98114__attribute__((section(".kdata")))
    99 unsigned int _cma_channel[NB_CMA_CHANNELS] = {0};
     115unsigned int _tim_channel_alloc[NB_TIM_CHANNELS] = {0};
    100116
    101117__attribute__((section(".kdata")))
    102 unsigned int _nic_rx_channel_allocator = 0;
    103 
     118unsigned int _tim_channel_wti[NB_TIM_CHANNELS];
     119#endif
     120
     121#if NB_CMA_CHANNELS
    104122__attribute__((section(".kdata")))
    105 unsigned int _nic_tx_channel_allocator = 0;
     123unsigned int _cma_channel_alloc[NB_CMA_CHANNELS] = {0};
     124
     125__attribute__((section(".kdata")))
     126unsigned int _cma_channel_wti[NB_CMA_CHANNELS];
     127#endif
     128
     129#if NB_NIC_CHANNELS
     130__attribute__((section(".kdata")))
     131unsigned int _nic_rx_channel_alloc[NB_NIC_CHANNELS] = {0};
     132
     133__attribute__((section(".kdata")))
     134unsigned int _nic_rx_channel_wti[NB_NIC_CHANNELS];
     135
     136__attribute__((section(".kdata")))
     137unsigned int _nic_tx_channel_alloc[NB_NIC_CHANNELS] = {0};
     138
     139__attribute__((section(".kdata")))
     140unsigned int _nic_tx_channel_wti[NB_NIC_CHANNELS];
     141#endif
    106142
    107143////////////////////////////////////////////////////////////////////////////
     
    140176    &_sys_proc_xyp,                  /* 0x00 */
    141177    &_get_proctime,                  /* 0x01 */
    142     &_sys_tty_write,                 /* 0x02 */
    143     &_sys_tty_read,                  /* 0x03 */
    144     &_sys_tty_alloc,                 /* 0x04 */
    145     &_sys_tasks_status,              /* 0x05 */
     178    &_sys_procs_number,              /* 0x02 */
     179    &_sys_xy_from_ptr,               /* 0x03 */
     180    &_sys_ukn,                       /* 0x04 */
     181    &_sys_ukn,                       /* 0x05 */
    146182    &_sys_ukn,                       /* 0x06 */
    147183    &_sys_heap_info,                 /* 0x07 */
    148     &_sys_local_task_id,             /* 0x08 */
    149     &_sys_global_task_id,            /* 0x09 */
     184    &_sys_vseg_get_vbase,            /* 0x08 */
     185    &_sys_vseg_get_length,           /* 0x09 */
    150186    &_sys_fbf_cma_alloc,             /* 0x0A */
    151187    &_sys_fbf_cma_init_buf,          /* 0x0B */
     
    153189    &_sys_fbf_cma_display,           /* 0x0D */
    154190    &_sys_fbf_cma_stop,              /* 0x0E */
    155     &_sys_task_exit,                 /* 0x0F */
    156 
    157     &_sys_procs_number,              /* 0x10 */
     191    &_sys_ukn,                       /* 0x0F */
     192
     193    &_sys_applications_status,       /* 0x10 */
    158194    &_sys_fbf_sync_write,            /* 0x11 */
    159195    &_sys_fbf_sync_read,             /* 0x12 */
    160     &_sys_thread_id,                 /* 0x13 */
     196    &_sys_ukn,                       /* 0x13 */
    161197    &_sys_tim_alloc,                 /* 0x14 */
    162198    &_sys_tim_start,                 /* 0x15 */
     
    164200    &_sys_kill_application,          /* 0x17 */
    165201    &_sys_exec_application,          /* 0x18 */   
    166     &_sys_context_switch,            /* 0x19 */
    167     &_sys_vseg_get_vbase,            /* 0x1A */
    168     &_sys_vseg_get_length,           /* 0x1B */
    169     &_sys_xy_from_ptr,               /* 0x1C */
    170     &_sys_ukn,                       /* 0x1D */
    171     &_sys_ukn,                       /* 0x1E */
    172     &_sys_ukn,                       /* 0x1F */
     202    &_sys_ukn,                       /* 0x19 */
     203    &_sys_pthread_control,           /* 0x1A */
     204    &_sys_pthread_yield,             /* 0x1B */
     205    &_sys_pthread_kill,              /* 0x1C */
     206    &_sys_pthread_create,            /* 0x1D */
     207    &_sys_pthread_join,              /* 0x1E */
     208    &_sys_pthread_exit,              /* 0x1F */
    173209
    174210    &_fat_open,                      /* 0x20 */
    175     &_sys_fat_read,                  /* 0x21 */
     211    &_fat_read,                      /* 0x21 */
    176212    &_fat_write,                     /* 0x22 */
    177213    &_fat_lseek,                     /* 0x23 */
     
    195231    &_sys_nic_stats,                 /* 0x34 */
    196232    &_sys_nic_clear,                 /* 0x35 */
    197     &_sys_ukn,                       /* 0x36 */
    198     &_sys_ukn,                       /* 0x37 */
    199     &_sys_ukn,                       /* 0x38 */   
     233    &_sys_tty_write,                 /* 0x36 */
     234    &_sys_tty_read,                  /* 0x37 */
     235    &_sys_tty_alloc,                 /* 0x38 */
    200236    &_sys_ukn,                       /* 0x39 */
    201237    &_sys_ukn,                       /* 0x3A */
     
    207243};
    208244
     245
     246//////////////////////////////////////////////////////////////////////////////
     247//           Applications related syscall handlers
     248//////////////////////////////////////////////////////////////////////////////
     249
     250////////////////////////////////////////////////////////////////////////
     251// This function is called by the _sys_exec_application function
     252// to reload all data segments contained in an application.elf file.
    209253////////////////////////////////////////////////////////////////////////
    210254static unsigned int _load_writable_segments( mapping_vspace_t*  vspace )
    211255{
    212 #if GIET_DEBUG_SWITCH
     256
     257#if GIET_DEBUG_EXEC 
    213258unsigned int gpid       = _get_procid();
    214259unsigned int cluster_xy = gpid >> P_WIDTH;
     
    216261unsigned int x          = cluster_xy >> Y_WIDTH;
    217262unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    218 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    219 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : enters for %s\n",
    220         x , y , p , vspace->name );
     263if ( _get_proctime() > GIET_DEBUG_EXEC )
     264_printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] "
     265        "enters for %s\n", x , y , p , vspace->name );
    221266#endif
    222267
     
    224269    mapping_vseg_t*    vseg    = _get_vseg_base(header);
    225270
    226     // buffer to store one cluster
    227     char  buf[4096];
    228 
    229     // open the .elf file associated to vspace
    230     unsigned int      vseg_id;
    231     unsigned int      fd = 0;
    232 
     271    unsigned int vseg_id;        // vseg index in mapping
     272    char         buf[4096];      // buffer to store one cluster
     273    unsigned int fd = 0;         // file descriptor
     274
     275    // first scan on vsegs in vspace to find the .elf pathname
    233276    for (vseg_id = vspace->vseg_offset;
    234277         vseg_id < (vspace->vseg_offset + vspace->vsegs);
    235278         vseg_id++)
    236279    {
    237         if(vseg[vseg_id].type == VSEG_TYPE_ELF)
     280        if( vseg[vseg_id].type == VSEG_TYPE_ELF )
    238281        {
     282            // open the .elf file associated to vspace
    239283            fd = _fat_open( vseg[vseg_id].binpath , O_RDONLY );
    240 
    241 #if GIET_DEBUG_SWITCH
    242 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    243 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : open %s / fd = %d\n",
    244         x , y , p , vseg[vseg_id].binpath , fd );
    245 #endif
    246 
    247284            if ( fd < 0 ) return 1;
    248285            break;
     286
     287#if GIET_DEBUG_EXEC
     288if ( _get_proctime() > GIET_DEBUG_EXEC )
     289_printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] "
     290        "open %s / fd = %d\n", x , y , p , vseg[vseg_id].binpath , fd );
     291#endif
    249292        }
    250293    }
    251 
     294 
    252295    // load Elf-Header into buffer from .elf file
    253     if ( _fat_lseek( fd, 0, SEEK_SET ) < 0 ) return 1;
    254     if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 ) return 1;
    255 
    256 #if GIET_DEBUG_SWITCH
    257 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    258 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : load Elf-Header\n",
    259         x , y , p );
     296    if ( _fat_lseek( fd, 0, SEEK_SET ) < 0 )
     297    {
     298        _fat_close( fd );
     299        return 1;
     300    }
     301    if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 )
     302    {
     303        _fat_close( fd );
     304        return 1;
     305    }
     306
     307#if GIET_DEBUG_EXEC
     308if ( _get_proctime() > GIET_DEBUG_EXEC )
     309_printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] "
     310        "loaded Elf-Header\n", x , y , p );
    260311#endif
    261312
     
    266317
    267318    // load Program-Header-Table from .elf file
    268     if ( _fat_lseek( fd, offset, SEEK_SET ) < 0 ) return 1;
    269     if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 ) return 1;
    270 
    271 #if GIET_DEBUG_SWITCH
    272 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    273 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : "
    274         "load Program-Header-Table\n", x , y , p );
     319    if ( _fat_lseek( fd, offset, SEEK_SET ) < 0 )
     320    {
     321        _fat_close( fd );
     322        return 1;
     323    }
     324    if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 )
     325    {
     326        _fat_close( fd );
     327        return 1;
     328    }
     329
     330#if GIET_DEBUG_EXEC
     331if ( _get_proctime() > GIET_DEBUG_EXEC )
     332_printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] "
     333        "loaded Program-Header-Table\n", x , y , p );
    275334#endif
    276335
     
    278337    Elf32_Phdr*  elf_pht_ptr = (Elf32_Phdr*)buf;
    279338
    280     // scan segments to  load all loadable & writable segments
    281     unsigned int seg_id;
    282     for (seg_id = 0 ; seg_id < nsegments ; seg_id++)
    283     {
    284         if ( (elf_pht_ptr[seg_id].p_type == PT_LOAD) &&    // loadable
    285              (elf_pht_ptr[seg_id].p_flags & PF_W) )        // writable
     339    // second scan on vsegs in vspace to load the seg_data segments :
     340    // - type == VSEG_TYPE_ELF
     341    // - non eXecutable
     342    for (vseg_id = vspace->vseg_offset;
     343         vseg_id < (vspace->vseg_offset + vspace->vsegs);
     344         vseg_id++)
     345    {
     346        if( (vseg[vseg_id].type == VSEG_TYPE_ELF) &&   // type ELF
     347            ((vseg[vseg_id].mode & 0x4) == 0) )        // non executable
    286348        {
    287             // Get segment attributes
    288             paddr_t      seg_paddr  = vseg[vseg_id].pbase;
    289             unsigned int seg_offset = elf_pht_ptr[seg_id].p_offset;
    290             unsigned int seg_size   = elf_pht_ptr[seg_id].p_filesz;
    291 
    292             // load the segment
    293             if ( _fat_lseek( fd, seg_offset, SEEK_SET ) < 0 ) return 1;
    294             if ( _fat_read( fd, seg_paddr, seg_size, 1 ) < 0 ) return 1;
    295 
    296 #if GIET_DEBUG_SWITCH
    297 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    298 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : load segment %x\n",
    299         x , y , p , seg_vaddr );
     349            // get vbase and pbase
     350            paddr_t      pbase = vseg[vseg_id].pbase;
     351            unsigned int vbase = vseg[vseg_id].vbase;
     352
     353            // scan segments in Progam-Header-Table to find match
     354            // No match checking as the segment was previously found
     355            unsigned int seg;
     356            for (seg = 0 ; seg < nsegments ; seg++)
     357            {
     358                if ( (elf_pht_ptr[seg].p_type == PT_LOAD) &&    // loadable
     359                     (elf_pht_ptr[seg].p_flags & PF_W)    &&    // writable
     360                     (elf_pht_ptr[seg].p_vaddr == vbase) )      // matching
     361                {
     362                    // Get segment offset and size in .elf file
     363                    unsigned int seg_offset = elf_pht_ptr[seg].p_offset;
     364                    unsigned int seg_size   = elf_pht_ptr[seg].p_filesz;
     365
     366                    // compute destination address and extension for _fat_read()
     367                    unsigned int dest   = (unsigned int)pbase;
     368                    unsigned int extend = (unsigned int)(pbase>>32) | 0xFFFF0000;
     369
     370                    // load the segment
     371                    if ( _fat_lseek( fd, seg_offset, SEEK_SET ) < 0 )
     372                    {
     373                        _fat_close( fd );
     374                        return 1;
     375                    }
     376                    if ( _fat_read( fd, dest, seg_size, extend ) < 0 )
     377                    {
     378                        _fat_close( fd );
     379                        return 1;
     380                    }
     381                }
     382            }
     383
     384#if GIET_DEBUG_EXEC
     385if ( _get_proctime() > GIET_DEBUG_EXEC )
     386_printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] "
     387        "loaded segment %x\n", x , y , p , vbase );
    300388#endif
    301389        }
     
    308396}  // end load_writable_segments()
    309397
    310 //////////////////////////////////////////////////////////////////////////////
    311 //           Applications related syscall handlers
    312 //////////////////////////////////////////////////////////////////////////////
     398
     399
     400///////////////////////////////////////
     401int _sys_exec_application( char* name )
     402{
     403    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     404    mapping_vspace_t * vspace  = _get_vspace_base(header);
     405    mapping_thread_t * thread  = _get_thread_base(header);
     406    mapping_vseg_t   * vseg    = _get_vseg_base(header);
     407
     408    unsigned int vspace_id;
     409    unsigned int thread_id;
     410
     411#if GIET_DEBUG_EXEC
     412unsigned int gpid       = _get_procid();
     413unsigned int cluster_xy = gpid >> P_WIDTH;
     414unsigned int p          = gpid & ((1<<P_WIDTH)-1);
     415unsigned int x          = cluster_xy >> Y_WIDTH;
     416unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
     417if ( _get_proctime() > GIET_DEBUG_EXEC )
     418_printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] "
     419        "enters for %s at cycle %d\n", x, y, p, name, _get_proctime() );
     420#endif
     421
     422    unsigned int y_size = header->y_size;
     423
     424    // scan vspaces to find matching vspace name
     425    for (vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++)
     426    {
     427        if ( _strcmp( vspace[vspace_id].name, name ) == 0 )  // vspace found
     428        {
     429
     430#if GIET_DEBUG_EXEC
     431if ( _get_proctime() > GIET_DEBUG_EXEC )
     432_printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] "
     433        "found vspace %s at cycle  %d\n", x, y, p, name, _get_proctime() );
     434#endif
     435            // reload writable segments
     436            if ( _load_writable_segments( &vspace[vspace_id] ) )
     437            {
     438                _printf("[GIET ERROR] _sys_exec_application() : "
     439                        "can't load data segment for vspace %s\n", name );
     440                return GIET_SYSCALL_CANNOT_LOAD_DATA_SEGMENT;
     441            }
     442 
     443#if GIET_DEBUG_EXEC
     444if ( _get_proctime() > GIET_DEBUG_EXEC )
     445_printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] "
     446        "load segments for vspace %s at cycle  %d\n", x, y, p, name, _get_proctime() );
     447#endif
     448            // scan threads in vspace with three goals :
     449            // - check all threads desactivated
     450            // - re-initialise all threads contexts
     451            // - find main thread
     452            unsigned int        main_found  = 0;
     453            unsigned int        main_ltid   = 0;
     454            static_scheduler_t* main_psched = NULL;
     455            unsigned int        min         = vspace[vspace_id].thread_offset;
     456            unsigned int        max         = min + vspace[vspace_id].threads;
     457            for ( thread_id = min ; thread_id < max ; thread_id++ )
     458            {
     459                // get thread identifiers : [x,y,p,ltid]
     460                unsigned int cid   = thread[thread_id].clusterid;
     461                unsigned int x     = cid / y_size;
     462                unsigned int y     = cid % y_size;
     463                unsigned int p     = thread[thread_id].proclocid;
     464                unsigned int ltid  = thread[thread_id].ltid;
     465                unsigned int vsid  = thread[thread_id].stack_vseg_id;
     466
     467                // get scheduler pointer
     468                static_scheduler_t* psched = _schedulers[x][y][p];
     469
     470                // check thread non active
     471                if ( psched->context[ltid].slot[CTX_NORUN_ID] == 0 )  // runnable !!!
     472                {
     473                    _printf("\n[GIET ERROR] in _sys_exec_application() : "
     474                            "thread %s already active in vspace %s\n",
     475                            thread[thread_id].name, name );
     476                    return GIET_SYSCALL_THREAD_ALREADY_ACTIVE;
     477                }
     478               
     479                // initialise thread context
     480                unsigned int ctx_epc = psched->context[ltid].slot[CTX_ENTRY_ID];
     481                unsigned int ctx_sp  = vseg[vsid].vbase + vseg[vsid].length;
     482                unsigned int ctx_ra  = (unsigned int)&_ctx_eret;
     483                unsigned int ctx_sr  = GIET_SR_INIT_VALUE;
     484
     485                psched->context[ltid].slot[CTX_EPC_ID] = ctx_epc;
     486                psched->context[ltid].slot[CTX_RA_ID]  = ctx_ra;
     487                psched->context[ltid].slot[CTX_SR_ID]  = ctx_sr;
     488                psched->context[ltid].slot[CTX_SP_ID]  = ctx_sp;
     489
     490                // register information required to activate main thread
     491                // actual activation done when threads initialisation is completed
     492                if ( thread[thread_id].is_main )
     493                {
     494                    main_psched = psched;
     495                    main_ltid   = ltid;
     496                    main_found  = 1;
     497                }
     498 
     499#if GIET_DEBUG_EXEC
     500if ( _get_proctime() > GIET_DEBUG_EXEC )
     501_printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] "
     502        "initialise thread %s at cycle  %d\n",
     503        x, y, p, thread[thread_id].name, _get_proctime() );
     504#endif
     505            }  // end loop on vspace threads
     506
     507            // activate main thread
     508            if ( main_found )
     509            {
     510                main_psched->context[main_ltid].slot[CTX_NORUN_ID] = 0;
     511            }
     512            else
     513            {
     514                _printf("\n[GIET ERROR] in _sys_exec_application() : "
     515                        "main not found in vspace %s\n", name );
     516                return GIET_SYSCALL_MAIN_NOT_FOUND;
     517            }
     518             
     519#if GIET_DEBUG_EXEC
     520if ( _get_proctime() > GIET_DEBUG_EXEC )
     521_printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] "
     522        "lauched %s at cycle %d\n", x, y, p, name, _get_proctime() );
     523#endif
     524            return GIET_SYSCALL_OK;
     525        }
     526    }  // end of loop on vspaces
     527
     528    // vspace not found
     529    _printf("\n[GIET ERROR] in _sys_exec_application() : "
     530            "vspace %s not found\n", name );
     531    return GIET_SYSCALL_VSPACE_NOT_FOUND;
     532
     533}  // end _sys_exec_application()
     534   
    313535
    314536///////////////////////////////////////
     
    317539    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    318540    mapping_vspace_t * vspace  = _get_vspace_base(header);
    319     mapping_task_t   * task    = _get_task_base(header);
     541    mapping_thread_t * thread  = _get_thread_base(header);
    320542
    321543    unsigned int vspace_id;
    322     unsigned int task_id;
    323     unsigned int y_size = header->y_size;
     544    unsigned int thread_id;
    324545
    325546#if GIET_DEBUG_EXEC
     547unsigned int gpid       = _get_procid();
     548unsigned int cluster_xy = gpid >> P_WIDTH;
     549unsigned int p          = gpid & ((1<<P_WIDTH)-1);
     550unsigned int x          = cluster_xy >> Y_WIDTH;
     551unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    326552if ( _get_proctime() > GIET_DEBUG_EXEC )
    327 _printf("\n[DEBUG EXEC] enters _sys_kill_application() for %s\n", name );
    328 #endif
    329 
    330     // scan vspaces
     553_printf("\n[DEBUG EXEC] _sys_kill_application() P[%d,%d,%d] "
     554        "enters at cycle %d for %s\n", x, y, p, _get_proctime() , name );
     555#endif
     556
     557    // shell cannot be killed
     558    if ( _strcmp( name , "shell" ) == 0 )
     559    {
     560        _printf("\n[GIET ERROR] in _sys_kill_application() : "
     561                "%s application cannot be killed\n", name );
     562        return GIET_SYSCALL_APPLI_CANNOT_BE_KILLED;
     563    }
     564
     565    // scan vspaces to find matching vspace name
    331566    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++)
    332567    {
    333568        if ( _strcmp( vspace[vspace_id].name, name ) == 0 )
    334569        {
    335             // check if application can be killed
    336             if ( vspace[vspace_id].active ) return -2;
    337 
    338             // scan tasks in vspace
    339             for (task_id = vspace[vspace_id].task_offset;
    340                  task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
    341                  task_id++)
     570            // scan threads to send KILL signal to all threads in vspace
     571            unsigned int y_size = header->y_size;
     572            unsigned int min    = vspace[vspace_id].thread_offset;
     573            unsigned int max    = min + vspace[vspace_id].threads;
     574            for ( thread_id = min ; thread_id < max ; thread_id++ )
    342575            {
    343                 unsigned int cid   = task[task_id].clusterid;
     576                unsigned int cid   = thread[thread_id].clusterid;
    344577                unsigned int x     = cid / y_size;
    345578                unsigned int y     = cid % y_size;
    346                 unsigned int p     = task[task_id].proclocid;
    347                 unsigned int ltid  = task[task_id].ltid;
    348 
    349                 // get scheduler pointer for processor running the task
     579                unsigned int p     = thread[thread_id].proclocid;
     580                unsigned int ltid  = thread[thread_id].ltid;
     581
     582                // get scheduler pointer for processor running the thread
    350583                static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
    351584
    352585                // set KILL signal bit
    353                 _atomic_or( &psched->context[ltid][CTX_SIG_ID] , SIG_MASK_KILL );
     586                _atomic_or( &psched->context[ltid].slot[CTX_SIGS_ID] , SIGS_MASK_KILL );
    354587            }
    355588
    356589#if GIET_DEBUG_EXEC
    357590if ( _get_proctime() > GIET_DEBUG_EXEC )
    358 _printf("\n[DEBUG EXEC] exit _sys_kill_application() : %s will be killed\n", name );
    359 #endif
    360 
    361             return 0;
     591_printf("\n[DEBUG EXEC] _sys_kill_application() P[%d,%d,%d] "
     592        "kill %s at cycle %d\n", x, y, p, name, _get_proctime() );
     593#endif
     594
     595            return GIET_SYSCALL_OK;
    362596        }
    363     }
     597    }  // en loop on vspaces
     598
     599    _printf("\n[GIET ERROR] in _sys_kill_application() : "
     600            "application %s not found\n", name );
     601    return GIET_SYSCALL_VSPACE_NOT_FOUND;
     602
     603}  // end _sys_kill_application()
     604   
     605
     606
     607//////////////////////////////
     608int _sys_applications_status()
     609{
     610    mapping_header_t *  header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     611    mapping_thread_t *  thread  = _get_thread_base(header);
     612    mapping_vspace_t *  vspace  = _get_vspace_base(header);
     613    mapping_cluster_t * cluster = _get_cluster_base(header);
     614
     615    unsigned int thread_id;
     616    unsigned int vspace_id;
     617
     618    // scan all vspaces
     619    for( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ )
     620    {
     621        _user_printf("\n*** vspace %s\n", vspace[vspace_id].name );
     622
     623        // scan all threads in vspace
     624        unsigned int min = vspace[vspace_id].thread_offset ;
     625        unsigned int max = min + vspace[vspace_id].threads ;
     626        for ( thread_id = min ; thread_id < max ; thread_id++ )
     627        {
     628            unsigned int         clusterid = thread[thread_id].clusterid;
     629            unsigned int         p         = thread[thread_id].proclocid;
     630            unsigned int         x         = cluster[clusterid].x;
     631            unsigned int         y         = cluster[clusterid].y;
     632            unsigned int         ltid      = thread[thread_id].ltid;
     633            static_scheduler_t*  psched    = (static_scheduler_t*)_schedulers[x][y][p];
     634            unsigned int         norun     = psched->context[ltid].slot[CTX_NORUN_ID];
     635            unsigned int         tty       = psched->context[ltid].slot[CTX_TTY_ID];
     636            unsigned int         current   = psched->current;
     637
     638            if ( current == ltid )
     639            _user_printf(" - thread %s / P[%d,%d,%d] / ltid = %d / "
     640                         "TTY = %d / norun = %x : running\n",
     641                         thread[thread_id].name, x, y, p, ltid, tty, norun );
     642            else if ( norun == 0 )
     643            _user_printf(" - thread %s / P[%d,%d,%d] / ltid = %d / "
     644                         "TTY = %d / norun = %x : runable\n",
     645                         thread[thread_id].name, x, y, p, ltid, tty, norun);
     646            else
     647            _user_printf(" - thread %s / P[%d,%d,%d] / ltid = %d / "
     648                         "TTY = %d / norun = %x : blocked\n",
     649                         thread[thread_id].name, x, y, p, ltid, tty, norun);
     650        }
     651    }
     652    _user_printf("\n");
     653    return GIET_SYSCALL_OK;
     654}  // end _sys_applications_status()
     655
     656
     657
     658/////////////////////////////////////////////////////////////////////////////
     659//          Threads related syscall handlers
     660/////////////////////////////////////////////////////////////////////////////
     661
     662////////////////////////////////////////////////
     663int _sys_pthread_create( unsigned int*  buffer,
     664                         void*          attr,
     665                         void*          function,
     666                         void*          arg )
     667{
     668    // attr argument not supported
     669    if ( attr != NULL )
     670    {
     671        _printf("\n[GIET ERROR] in _sys_pthread_create() : "
     672                "attr argument not supported\n" );
     673       
     674        return GIET_SYSCALL_PTHREAD_ARGUMENT_NOT_SUPPORTED;
     675    }
     676
     677    // get pointers in mapping
     678    mapping_header_t*    header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     679    mapping_thread_t*    thread   = _get_thread_base(header);
     680    mapping_vspace_t*    vspace   = _get_vspace_base(header);
     681    mapping_cluster_t*   cluster  = _get_cluster_base(header);
     682
     683    // get scheduler for processor running the calling thread
     684    static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
     685
     686    // get calling thread local index in scheduler
     687    unsigned int  current = psched->current;
     688
     689    // get vspace index
     690    unsigned int  vspace_id = psched->context[current].slot[CTX_VSID_ID];
    364691
    365692#if GIET_DEBUG_EXEC
    366693if ( _get_proctime() > GIET_DEBUG_EXEC )
    367 _printf("\n[DEBUG EXEC] exit _sys_kill_application() : %s not found\n", name );
    368 #endif
    369 
    370     return -1;    // not found
    371 
    372 }  // end _sys_kill_application()
     694_printf("\n[DEBUG EXEC] _sys_pthread_create() : enters at cycle %d"
     695        " for vspace %s / entry = %x\n",
     696        _get_proctime() , vspace[vspace_id].name , (unsigned int)function );
     697#endif
     698
     699    unsigned int thread_id;        // searched thread : local index in mapping
     700    unsigned int clusterid;        // searched thread : cluster index
     701    unsigned int lpid;             // searched thread : processor local index
     702    unsigned int ltid;             // searched thread : scheduler thread index
     703    unsigned int cx;               // searched thread : X coordinate for searched thread
     704    unsigned int cy;               // searched thread : Y coordinate for searched thread
     705    unsigned int entry;            // searched thread : entry point
     706    unsigned int norun;            // searched thread : norun vector
     707    unsigned int trdid;            // searched thread : thread identifier
     708
     709    // scan threads in vspace to find an inactive thread matching function
     710    unsigned int min   = vspace[vspace_id].thread_offset;
     711    unsigned int max   = min + vspace[vspace_id].threads;
     712    unsigned int found = 0;
     713    for ( thread_id = min ; (thread_id < max) && (found == 0) ; thread_id++ )
     714    {
     715        // get thread coordinates [cx,cy,lpid] and ltid from mapping
     716        ltid       = thread[thread_id].ltid;
     717        clusterid  = thread[thread_id].clusterid;
     718        lpid       = thread[thread_id].proclocid;
     719        cx = cluster[clusterid].x;
     720        cy = cluster[clusterid].y;
     721
     722        // get thread scheduler pointer
     723        psched = _schedulers[cx][cy][lpid];
     724
     725        // get thread entry-point, norun-vector, and trdid from context
     726        entry = psched->context[ltid].slot[CTX_ENTRY_ID];
     727        norun = psched->context[ltid].slot[CTX_NORUN_ID];
     728        trdid = psched->context[ltid].slot[CTX_TRDID_ID];
     729
     730        // check matching
     731        if ( ((unsigned int)function == entry ) &&
     732             (norun & NORUN_MASK_THREAD)  ) found = 1;
     733
     734    }  // end loop on threads
     735
     736    if ( found )  // one matching inactive thread has been found
     737    {
     738        // set argument value in thread context
     739        if ( arg != NULL ) psched->context[ltid].slot[CTX_A0_ID] = (unsigned int)arg;
     740
     741        // activate thread
     742        psched->context[ltid].slot[CTX_NORUN_ID] = 0;
     743
     744        // return launched thead global identifier
     745        *buffer   = trdid;
     746               
     747#if GIET_DEBUG_EXEC
     748if ( _get_proctime() > GIET_DEBUG_EXEC )
     749_printf("\n[DEBUG EXEC] exit _sys_pthread_create() at cycle %d : thread %x launched\n",
     750        _get_proctime() , trdid);
     751#endif
     752        return GIET_SYSCALL_OK;
     753    }
     754    else         // no matching thread found
     755    {
     756        _printf("\n[GIET ERROR] in _sys_pthread_create() : "
     757                "no matching thread for entry = %x in vspace %s\n",
     758                (unsigned int)function , vspace[vspace_id].name );
     759       
     760        return GIET_SYSCALL_THREAD_NOT_FOUND;
     761    }
     762
     763} // end _sys_pthread_create()
     764
     765
     766///////////////////////////////////////////
     767int _sys_pthread_join( unsigned int  trdid,
     768                       void*         ptr )
     769{
     770    // ptr argument not supported
     771    if ( ptr != NULL )
     772    {
     773        _printf("\n[GIET ERROR] in _sys_pthread_join() : "
     774                "ptr argument not supported, must be NULL\n" );
     775       
     776        return GIET_SYSCALL_PTHREAD_ARGUMENT_NOT_SUPPORTED;
     777    }
     778
     779               
     780#if GIET_DEBUG_EXEC
     781if ( _get_proctime() > GIET_DEBUG_EXEC )
     782_printf("\n[DEBUG EXEC] enters _sys_pthread_join() at cycle %d for thread %x\n",
     783        _get_proctime() , trdid );
     784#endif
     785
     786    // get calling thread vspace
     787    unsigned int  caller_vspace = _get_context_slot( CTX_VSID_ID );
     788
     789    // get and check target thread indexes from trdid
     790    unsigned int cx   = (trdid>>24) & 0xFF;
     791    unsigned int cy   = (trdid>>16) & 0xFF;
     792    unsigned int lpid = (trdid>>8 ) & 0xFF;
     793    unsigned int ltid = (trdid    ) & 0xFF;
     794
     795    // get target thread scheduler, vspace and registered trdid
     796    static_scheduler_t*  psched   = _schedulers[cx][cy][lpid];
     797    unsigned int target_vspace    = psched->context[ltid].slot[CTX_VSID_ID];
     798    unsigned int registered_trdid = psched->context[ltid].slot[CTX_TRDID_ID];
     799
     800    // check trdid
     801    if ( trdid != registered_trdid )
     802    {
     803       _printf("\nerror in _sys_pthread_join() : "
     804               "trdid = %x / registered_trdid = %x\n",
     805               trdid , registered_trdid );
     806
     807       return GIET_SYSCALL_UNCOHERENT_THREAD_CONTEXT;
     808    }
     809   
     810    // check calling thread and target thread in same vspace
     811    if ( caller_vspace != target_vspace )
     812    {
     813       _printf("\n[GIET ERROR] in _sys_pthread_join() : "
     814               " calling thread and target thread not in same vspace\n");
     815
     816       return GIET_SYSCALL_NOT_IN_SAME_VSPACE;
     817    }
     818
     819    // get target thread state
     820    unsigned int* pnorun = &psched->context[ltid].slot[CTX_NORUN_ID];
     821
     822    asm volatile ( "2000:                      \n"                         
     823                   "move  $11,  %0             \n"   /* $11 <= ptr           */
     824                   "lw    $11,  0($11)         \n"   /* $11 <= M[ptr]        */
     825                   "andi  $11,  $11,    1      \n"   /* $11 <= norun & 0x1   */
     826                   "beqz  $11,  2000b          \n"   
     827                   :
     828                   : "r" (pnorun)
     829                   : "$11" );
     830
     831    return GIET_SYSCALL_OK;
     832
     833}  // end _sys_pthread_join()
     834                       
     835
     836////////////////////////////////////////
     837int _sys_pthread_kill( pthread_t  trdid,
     838                       int        signal )
     839{
     840    // get calling thread vspace
     841    unsigned int  caller_vspace = _get_context_slot( CTX_VSID_ID );
     842
     843    // get and check target thread indexes from trdid
     844    unsigned int cx   = (trdid>>24) & 0xFF;
     845    unsigned int cy   = (trdid>>16) & 0xFF;
     846    unsigned int lpid = (trdid>>8 ) & 0xFF;
     847    unsigned int ltid = (trdid    ) & 0xFF;
     848
     849    // get target thread scheduler, vspace and registered trdid
     850    static_scheduler_t*  psched       = _schedulers[cx][cy][lpid];
     851    unsigned int target_vspace        = psched->context[ltid].slot[CTX_VSID_ID];
     852    unsigned int registered_trdid = psched->context[ltid].slot[CTX_TRDID_ID];
     853
     854    // check trdid
     855    if ( trdid != registered_trdid )
     856    {
     857       _printf("\n[GIET ERROR] in _sys_pthread_kill() : trdid = %x"
     858               " / registered_trdid = %x\n", trdid , registered_trdid );
     859       return GIET_SYSCALL_UNCOHERENT_THREAD_CONTEXT;
     860    }
     861   
     862    // check calling thread and target thread in same vspace
     863    if ( caller_vspace != target_vspace )
     864    {
     865       _printf("\n[GIET ERROR] in _sys_pthread_kill() : not in same vspace\n");
     866       return GIET_SYSCALL_NOT_IN_SAME_VSPACE;
     867    }
     868
     869    // register KILL signal in target thread context if required
     870    if ( signal )
     871    {
     872        _atomic_or( &psched->context[ltid].slot[CTX_SIGS_ID] , SIGS_MASK_KILL );
     873    }
     874
     875    return GIET_SYSCALL_OK;
     876
     877}  // end _sys_pthread_kill()
     878
     879
     880/////////////////////////////////////
     881int _sys_pthread_exit( void* string )
     882{
     883    unsigned int date       = _get_proctime();
     884
     885    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     886    mapping_vspace_t * vspace  = _get_vspace_base(header);
     887
     888    unsigned int ltid       = _get_context_slot(CTX_LTID_ID);
     889    unsigned int trdid      = _get_context_slot(CTX_TRDID_ID);
     890    unsigned int vsid       = _get_context_slot(CTX_VSID_ID);
     891
     892    // print exit message
     893    if ( string == NULL )
     894    {
     895        _printf("\n[GIET WARNING] Exit thread %x in vspace %s at cycle %d\n",
     896                trdid , vspace[vsid].name , date );
     897    }
     898    else
     899    {
     900        _printf("\n[GIET WARNING] Exit thread %x in vspace %s at cycle %d\n"
     901                "               Cause : %s\n\n",
     902                trdid , vspace[vsid].name , date , (char*) string );
     903    }
    373904   
    374 ///////////////////////////////////////
    375 int _sys_exec_application( char* name )
    376 {
    377     mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    378     mapping_vseg_t   * vseg    = _get_vseg_base(header);
    379     mapping_vspace_t * vspace  = _get_vspace_base(header);
    380     mapping_task_t   * task    = _get_task_base(header);
    381 
    382     unsigned int vspace_id;
    383     unsigned int task_id;
    384     unsigned int y_size = header->y_size;
    385 
    386 #if GIET_DEBUG_EXEC
     905    // get scheduler pointer for calling thread
     906    static_scheduler_t*  psched = (static_scheduler_t*)_get_sched();
     907
     908    // register KILL signal in calling thread context (suicid request)
     909    _atomic_or( &psched->context[ltid].slot[CTX_SIGS_ID] , SIGS_MASK_KILL );
     910
     911    // deschedule calling thread
     912    unsigned int save_sr; 
     913    _it_disable( &save_sr );
     914
     915    _ctx_switch();
     916
     917    return GIET_SYSCALL_OK;
     918
     919}  // end _sys_pthread_exit()
     920
     921////////////////////////
     922int _sys_pthread_yield()
     923{
     924    unsigned int save_sr;
     925
     926    _it_disable( &save_sr );
     927    _ctx_switch();
     928    _it_restore( &save_sr );
     929
     930    return GIET_SYSCALL_OK;
     931}
     932
     933//////////////////////////////////////////////////
     934int _sys_pthread_control( unsigned  int  command,
     935                          char*     vspace_name,
     936                          char*     thread_name )
     937{
     938
     939#if GIET_DEBUG_EXEC
    387940if ( _get_proctime() > GIET_DEBUG_EXEC )
    388 _printf("\n[DEBUG EXEC] enters _sys_exec_application() at cycle %d for %s\n",
    389          _get_proctime() , name );
    390 #endif
    391 
    392     // find vspace
    393     for ( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ )
    394     {
    395         if ( _strcmp( vspace[vspace_id].name, name ) == 0 )
     941_printf("\n[DEBUG EXEC] _sys_pthread_control() at cycle %d : "
     942        "enter for vspace %s / thread %s / command = %d\n",
     943        _get_proctime() , vspace_name, thread_name, command );
     944#endif
     945
     946    // get pointers in mapping
     947    mapping_header_t*    header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     948    mapping_thread_t*    thread   = _get_thread_base(header);
     949    mapping_vspace_t*    vspace   = _get_vspace_base(header);
     950    mapping_cluster_t*   cluster  = _get_cluster_base(header);
     951
     952    unsigned int found;
     953
     954    // search vspace name to get vspace index: vsid
     955    found = 0;
     956    unsigned int   vsid;
     957    for( vsid = 0 ; vsid < header->vspaces ; vsid++ )
     958    {
     959        if ( _strcmp( vspace[vsid].name, vspace_name ) == 0 )
     960        {
     961            found = 1;
    396962            break;
    397     }
    398 
    399     if ( vspace_id == header->vspaces )
    400     {
    401         _printf("\n[GIET ERROR] _sys_exec_application() : %s not found\n", name );
    402         return -1;
    403     }
    404 
    405     // scan tasks in vspace
    406     for (task_id = vspace[vspace_id].task_offset;
    407          task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
    408          task_id++)
    409     {
    410         unsigned int cid   = task[task_id].clusterid;
    411         unsigned int x     = cid / y_size;
    412         unsigned int y     = cid % y_size;
    413         unsigned int p     = task[task_id].proclocid;
    414         unsigned int ltid  = task[task_id].ltid;
    415 
    416         // get scheduler pointer for processor running the task
    417         static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
    418 
    419         // check if an application task is runnable
    420         if ( psched->context[ltid][CTX_NORUN_ID] == 0 )
     963        }
     964    }
     965
     966    if ( found == 0 ) return GIET_SYSCALL_VSPACE_NOT_FOUND;
     967
     968    // search thread name in vspace to get thread index: tid
     969    found = 0;
     970    unsigned int   tid;
     971    unsigned int   min = vspace[vsid].thread_offset;
     972    unsigned int   max = min + vspace[vsid].threads;
     973    for( tid = min ; tid < max ; tid++ )
     974    {
     975        if ( _strcmp( thread[tid].name, thread_name ) == 0 )
    421976        {
    422             _printf( "\n[GIET ERROR] _sys_exec_application() : %s already executed\n", name );
    423             return -2;
     977            found = 1;
     978            break;
    424979        }
    425980    }
    426981
    427     // reload writable segments
    428     if ( _load_writable_segments( &vspace[vspace_id] ) )
    429     {
    430          _printf("[GIET ERROR] _sys_exec_application() : can't load segments for %s\n", name );
    431          return -3;
    432     }
    433 
    434     // scan tasks in vspace
    435     for (task_id = vspace[vspace_id].task_offset;
    436          task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
    437          task_id++)
    438     {
    439         unsigned int cid   = task[task_id].clusterid;
    440         unsigned int x     = cid / y_size;
    441         unsigned int y     = cid % y_size;
    442         unsigned int p     = task[task_id].proclocid;
    443         unsigned int ltid  = task[task_id].ltid;
    444 
    445         // get scheduler pointer for processor running the task
    446         static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
    447 
    448         // reset task context: RA / SR / SP / EPC / NORUN
    449         unsigned int vseg_id       = task[task_id].stack_vseg_id;
    450         unsigned int sp_value      = vseg[vseg_id].vbase + vseg[vseg_id].length;
    451 
    452         psched->context[ltid][CTX_RA_ID]     = (unsigned int)&_ctx_eret;
    453         psched->context[ltid][CTX_SR_ID]     = GIET_SR_INIT_VALUE;
    454         psched->context[ltid][CTX_SP_ID]     = sp_value;
    455         psched->context[ltid][CTX_EPC_ID]    = psched->context[ltid][CTX_ENTRY_ID];
    456         psched->context[ltid][CTX_NORUN_ID]  = 0;
    457     }
    458 
    459 #if GIET_DEBUG_EXEC
    460 if ( _get_proctime() > GIET_DEBUG_EXEC )
    461 _printf("\n[DEBUG EXEC] exit _sys_exec_application() at cycle %d : %s will be executed\n",
    462         _get_proctime() , name );
    463 #endif
    464 
    465     return 0;
    466 }  // end _sys_exec_application()
    467    
     982    if ( found == 0 ) return GIET_SYSCALL_THREAD_NOT_FOUND;
     983
     984    // get thread coordinates
     985    unsigned int cid  = thread[tid].clusterid;
     986    unsigned int x    = cluster[cid].x;
     987    unsigned int y    = cluster[cid].y;
     988    unsigned int p    = thread[tid].proclocid;
     989    unsigned int ltid = thread[tid].ltid;
     990
     991    static_scheduler_t* psched = _schedulers[x][y][p];
     992
     993    // check trdid and vsid
     994    unsigned int trdid = x<<24 | y<<16 | p<<8 | ltid;
     995    if ( (psched->context[ltid].slot[CTX_TRDID_ID] != trdid) ||
     996         (psched->context[ltid].slot[CTX_VSID_ID]  != vsid) )
     997        return GIET_SYSCALL_UNCOHERENT_THREAD_CONTEXT;
     998
     999    // execute command
     1000    if ( command == THREAD_CMD_PAUSE )
     1001    {
     1002        _atomic_or ( &psched->context[ltid].slot[CTX_NORUN_ID],  NORUN_MASK_THREAD );
     1003        return GIET_SYSCALL_OK;
     1004    }
     1005    else if ( command == THREAD_CMD_RESUME )
     1006    {
     1007        _atomic_and( &psched->context[ltid].slot[CTX_NORUN_ID], ~NORUN_MASK_THREAD );
     1008        return GIET_SYSCALL_OK;
     1009    }
     1010    else if ( command == THREAD_CMD_CONTEXT )
     1011    {
     1012        _user_printf( " - CTX_TRDID  = %x\n"
     1013                      " - CTX_VSID   = %x\n"
     1014                      " - CTX_EPC    = %x\n"
     1015                      " - CTX_PTAB   = %x\n"
     1016                      " - CTX_PTPR   = %x\n"
     1017                      " - CTX_SR     = %x\n"
     1018                      " - CTX_RA     = %x\n"
     1019                      " - CTX_SP     = %x\n"
     1020                      " - CTX_ENTRY  = %x\n"
     1021                      " - CTX_NORUN  = %x\n"
     1022                      " - CTX_SIGS   = %x\n"
     1023                      " - CTX_LOCKS  = %x\n"
     1024                      " - CTX_TTY    = %x\n"
     1025                      " - CTX_NIC_RX = %x\n"
     1026                      " - CTX_NIC_TX = %x\n"
     1027                      " - CTX_CMA_RX = %x\n"
     1028                      " - CTX_CMA_TX = %x\n"
     1029                      " - CTX_CMA_FB = %x\n",
     1030                      psched->context[ltid].slot[CTX_TRDID_ID],
     1031                      psched->context[ltid].slot[CTX_VSID_ID],
     1032                      psched->context[ltid].slot[CTX_EPC_ID],
     1033                      psched->context[ltid].slot[CTX_PTAB_ID],
     1034                      psched->context[ltid].slot[CTX_PTPR_ID],
     1035                      psched->context[ltid].slot[CTX_SR_ID],
     1036                      psched->context[ltid].slot[CTX_RA_ID],
     1037                      psched->context[ltid].slot[CTX_SP_ID],
     1038                      psched->context[ltid].slot[CTX_ENTRY_ID],
     1039                      psched->context[ltid].slot[CTX_NORUN_ID],
     1040                      psched->context[ltid].slot[CTX_SIGS_ID],
     1041                      psched->context[ltid].slot[CTX_LOCKS_ID],
     1042                      psched->context[ltid].slot[CTX_TTY_ID],
     1043                      psched->context[ltid].slot[CTX_NIC_RX_ID],
     1044                      psched->context[ltid].slot[CTX_NIC_TX_ID],
     1045                      psched->context[ltid].slot[CTX_CMA_RX_ID],
     1046                      psched->context[ltid].slot[CTX_CMA_TX_ID],
     1047                      psched->context[ltid].slot[CTX_CMA_FB_ID] );
     1048        return GIET_SYSCALL_OK;
     1049    }
     1050    else
     1051    {
     1052        return GIET_SYSCALL_ILLEGAL_THREAD_COMMAND_TYPE;
     1053    }
     1054
     1055} // end _sys_pthread_control()
     1056
     1057
     1058
    4681059
    4691060//////////////////////////////////////////////////////////////////////////////
     
    4761067{
    4771068    // In this implementation, the allocation policy is constrained:
    478     // the coprocessor must be in the same cluster as the calling task,
     1069    // the coprocessor must be in the same cluster as the calling thread,
    4791070    // and there is at most one coprocessor per cluster
    4801071
     
    5191110        *coproc_info = _coproc_info[cluster_id];
    5201111
    521         // register coprocessor coordinates in task context
     1112        // register coprocessor coordinates in thread context
    5221113        unsigned int cluster_xy = (x<<Y_WIDTH) + y;
    5231114        _set_context_slot( CTX_COPROC_ID , cluster_xy );
     
    5281119        x , y , *coproc_info , cluster_xy );
    5291120#endif
    530         return 0;
     1121        return GIET_SYSCALL_OK;
    5311122    }
    5321123    else
     
    5351126                 " with type %d available in cluster[%d,%d]\n",
    5361127                 coproc_type , x , y );
    537         return -1;
     1128        return GIET_SYSCALL_COPROCESSOR_NOT_FOUND;
    5381129    }
    5391130}  // end _sys_coproc_alloc()
     
    5531144    {
    5541145         _printf("\n[GIET_ERROR] in _sys_coproc_release(): "
    555                  "no coprocessor allocated to task running on P[%d,%d,%d]\n",
     1146                 "no coprocessor allocated to thread running on P[%d,%d,%d]\n",
    5561147                 x , y , p );
    557          return -1;
     1148         return GIET_SYSCALL_COPROCESSOR_NOT_FOUND;
    5581149    }
    5591150
     
    5731164    }
    5741165
    575     // deallocates coprocessor coordinates in task context
     1166    // deallocates coprocessor coordinates in thread context
    5761167    _set_context_slot( CTX_COPROC_ID , 0xFFFFFFFF );
    5771168
     
    5841175#endif
    5851176
    586     return 0;
     1177    return GIET_SYSCALL_OK;
    5871178}  // end _sys_coproc_release()
    5881179
     
    6021193    {
    6031194         _printf("\n[GIET_ERROR] in _sys_coproc_channel_init(): "
    604                  "no coprocessor allocated to task running on P[%d,%d,%d]\n",
     1195                 "no coprocessor allocated to thread running on P[%d,%d,%d]\n",
    6051196                 x , y , p );
    606          return -1;
     1197         return GIET_SYSCALL_COPROCESSOR_NOT_FOUND;
    6071198    }
    6081199
     
    6151206         _printf("\n[GIET_ERROR] in _sys_coproc_channel_init(): "
    6161207                 " illegal mode\n");
    617          return -1;
     1208         return GIET_SYSCALL_COPROCESSOR_ILLEGAL_MODE;
    6181209    }
    6191210
     
    6221213 
    6231214    // physical addresses
    624     paddr_t            buffer_paddr;
     1215    unsigned long long buffer_paddr;
    6251216    unsigned int       buffer_lsb;
    6261217    unsigned int       buffer_msb;
    627     paddr_t            mwmr_paddr = 0;
     1218    unsigned long long mwmr_paddr = 0;
    6281219    unsigned int       mwmr_lsb;
    6291220    unsigned int       mwmr_msb;
    630     paddr_t            lock_paddr = 0;
     1221    unsigned long long lock_paddr = 0;
    6311222    unsigned int       lock_lsb;
    6321223    unsigned int       lock_msb;
     
    6741265#endif
    6751266       
    676     return 0;
     1267    return GIET_SYSCALL_OK;
    6771268} // end _sys_coproc_channel_init()
    6781269
     
    6911282    {
    6921283         _printf("\n[GIET_ERROR] in _sys_coproc_run(): "
    693                  "no coprocessor allocated to task running on P[%d,%d,%d]\n",
     1284                 "no coprocessor allocated to thread running on P[%d,%d,%d]\n",
    6941285                 x , y , p );
    695          return -1;
     1286         return -1111;
    6961287    }
    6971288
     
    7191310            _printf("\n[GIET_ERROR] P[%d,%d,%d] in _sys_coproc_run() for coprocessor[%d,%d]\n"
    7201311                    "  all channels don't have the same mode\n", x , y , p , cx , cy );
    721             return -1;
     1312            return -1111;
    7221313        }
    7231314    }
     
    7451336#endif
    7461337
    747         return 0;
     1338        return GIET_SYSCALL_OK;
    7481339    }
    7491340    ///////////////////////////////////////////////////////////////////////////
    7501341    else                                // mode == MODE_DMA_IRQ => descheduling
    7511342    {
    752         // set _coproc_gtid
    753         unsigned int ltid = _get_current_task_id();
    754         _coproc_gtid[cluster_id] = (procid<<16) + ltid;
     1343        // set _coproc_trdid
     1344        unsigned int ltid = _get_thread_ltid();
     1345        _coproc_trdid[cluster_id] = (x<<24) + (y<<16) + (p<<8) + ltid;
    7551346
    7561347        // enters critical section
     
    7601351        // set NORUN_MASK_COPROC bit
    7611352        static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
    762         unsigned int*       ptr     = &psched->context[ltid][CTX_NORUN_ID];
     1353        unsigned int*       ptr     = &psched->context[ltid].slot[CTX_NORUN_ID];
    7631354        _atomic_or( ptr , NORUN_MASK_COPROC );
    7641355
     
    7711362#endif
    7721363
    773         // deschedule task
     1364        // deschedule thread
    7741365        _ctx_switch();
    7751366
     
    8021393    {
    8031394         _printf("\n[GIET_ERROR] in _sys_coproc_completed(): "
    804                  "no coprocessor allocated to task running on P[%d,%d,%d]\n",
     1395                 "no coprocessor allocated to thread running on P[%d,%d,%d]\n",
    8051396                 x , y , p );
    806          return -1;
     1397         return -1111;
    8071398    }
    8081399
     
    8791470int _sys_tty_alloc( unsigned int shared )
    8801471{
    881     unsigned int channel;
    882 
     1472    unsigned int channel;    // allocated TTY channel
     1473
     1474    // get trdid and vsid for the calling thread
     1475    unsigned int vsid  = _get_context_slot( CTX_VSID_ID );
     1476    unsigned int trdid = _get_thread_trdid();
     1477
     1478    // check no TTY already allocated to calling thread
    8831479    if ( _get_context_slot( CTX_TTY_ID ) < NB_TTY_CHANNELS )
    8841480    {
    885         _printf("\n[GIET_ERROR] in _sys_tty_alloc() : TTY channel already allocated\n");
    886         return 0;
    887     }
    888 
    889     // get a new TTY channel
     1481        _printf("\n[GIET_ERROR] in _sys_tty_alloc() : "
     1482                "TTY channel already allocated to thread %x\n", trdid );
     1483        return -1111;
     1484    }
     1485
     1486    mapping_header_t  *header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     1487    mapping_vspace_t  *vspace   = _get_vspace_base(header);
     1488    mapping_thread_t  *thread   = _get_thread_base(header);
     1489   
     1490    // compute number of users
     1491    unsigned int users;
     1492    if ( shared )  users = vspace[vsid].threads;
     1493    else           users = 1;
     1494
     1495    // get a TTY channel
    8901496    for ( channel = 0 ; channel < NB_TTY_CHANNELS ; channel++ )
    8911497    {
    892         if ( !_tty_channel[channel] )
    893         {
    894             _tty_channel[channel] = 1;
    895             break;
    896         }
     1498        unsigned int* palloc  = &_tty_channel_alloc[channel];
     1499
     1500        if ( _atomic_test_and_set( palloc , users ) == 0 ) break;
    8971501    }
    8981502    if ( channel >= NB_TTY_CHANNELS )
    8991503    {
    900         _printf("\n[GIET_ERROR] in _sys_tty_alloc() : no TTY channel available\n");
    901         return -1;
    902     }
    903 
    904     // reset kernel buffer for allocated TTY channel
    905     _tty_rx_full[channel] = 0;
     1504        _printf("\n[GIET_ERROR] in _sys_tty_alloc() : "
     1505                "no TTY channel available for thread %x\n", trdid );
     1506        return -1111;
     1507    }
     1508
     1509    // initialise allocated TTY channel
     1510    _tty_init( channel );
    9061511
    9071512    // allocate a WTI mailbox to the calling proc if external IRQ
    908     unsigned int unused;
    909     if ( USE_PIC ) _ext_irq_alloc( ISR_TTY_RX , channel , &unused );
     1513    unsigned int wti_id;
     1514    if ( USE_PIC ) _ext_irq_alloc( ISR_TTY_RX , channel , &wti_id );
     1515
     1516    // register wti_id and coordinates for processor receiving WTI
     1517    unsigned int procid = _get_procid();
     1518    unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
     1519    unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
     1520    unsigned int p      = procid & ((1<<P_WIDTH)-1);
     1521    _tty_channel_wti[channel] = x<<24 | y<<16 | p<<8 | wti_id;
    9101522   
    9111523    // update CTX_TTY_ID
    912     if ( shared )         // for all tasks in the same vspace
    913     {
    914         unsigned int      vspace_id = _get_context_slot( CTX_VSID_ID );
    915         mapping_header_t  *header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    916         mapping_vspace_t  *vspace   = _get_vspace_base(header);
    917         mapping_task_t    *task     = _get_task_base(header);
    918 
    919         // scan tasks in vspace
    920         unsigned int task_id;
    921         for (task_id = vspace[vspace_id].task_offset;
    922              task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
    923              task_id++)
     1524    if ( shared )         // for all threads in vspace
     1525    {
     1526        // scan threads in vspace
     1527        unsigned int tid;
     1528        for (tid = vspace[vsid].thread_offset;
     1529             tid < (vspace[vsid].thread_offset + vspace[vsid].threads);
     1530             tid++)
    9241531        {
    9251532            unsigned int y_size        = header->y_size;
    926             unsigned int cid           = task[task_id].clusterid;
     1533            unsigned int cid           = thread[tid].clusterid;
    9271534            unsigned int x             = cid / y_size;
    9281535            unsigned int y             = cid % y_size;
    929             unsigned int p             = task[task_id].proclocid;
    930             unsigned int ltid          = task[task_id].ltid;
     1536            unsigned int p             = thread[tid].proclocid;
     1537            unsigned int ltid          = thread[tid].ltid;
    9311538            static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p];
    9321539
    933             // don't overwrite TTY_ID
    934             if ( psched->context[ltid][CTX_TTY_ID] >= NB_TTY_CHANNELS )
    935             {
    936                 psched->context[ltid][CTX_TTY_ID] = channel;
    937             }
     1540            psched->context[ltid].slot[CTX_TTY_ID] = channel;
    9381541        }
    9391542    }
    940     else                  // for calling task only
     1543    else                  // for calling thread only
    9411544    {
    9421545        _set_context_slot( CTX_TTY_ID, channel );
    9431546    }
    9441547
    945     return 0;
    946 }
    947 
    948 /////////////////////////////////////////
    949 // NOTE: not a syscall
    950 int _sys_tty_release()
     1548    return GIET_SYSCALL_OK;
     1549}  // end _sys_tty_alloc()
     1550
     1551//////////////////////
     1552int _sys_tty_release()     // NOTE: not a syscall
    9511553{
    9521554    unsigned int channel = _get_context_slot( CTX_TTY_ID );
     
    9541556    if ( channel == -1 )
    9551557    {
    956         _printf("\n[GIET_ERROR] in _sys_tty_release() : TTY channel already released\n");
    957         return -1;
    958     }
    959 
    960     // release WTI mailbox
    961     if ( USE_PIC ) _ext_irq_release( ISR_TTY_RX , channel );
    962 
    963     // reset CTX_TTY_ID for all tasks in vspace
    964     unsigned int      vspace_id = _get_context_slot( CTX_VSID_ID );
    965     mapping_header_t  *header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    966     mapping_vspace_t  *vspace   = _get_vspace_base(header);
    967     mapping_task_t    *task     = _get_task_base(header);
    968 
    969     unsigned int task_id;
    970     for (task_id = vspace[vspace_id].task_offset;
    971          task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
    972          task_id++)
    973     {
    974         unsigned int y_size        = header->y_size;
    975         unsigned int cid           = task[task_id].clusterid;
    976         unsigned int x             = cid / y_size;
    977         unsigned int y             = cid % y_size;
    978         unsigned int p             = task[task_id].proclocid;
    979         unsigned int ltid          = task[task_id].ltid;
    980         static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p];
    981 
    982         // only clear matching TTY_ID
    983         if ( psched->context[ltid][CTX_TTY_ID] == channel )
    984         {
    985             psched->context[ltid][CTX_TTY_ID] = -1;
    986         }
    987     }
    988 
    989     // release TTY channel
    990     _tty_channel[channel] = 0;
    991 
    992     return 0;
    993 }
    994 
    995 /////////////////////////////////////////////////
     1558        unsigned int trdid = _get_thread_trdid();
     1559        _printf("\n[GIET_ERROR] in _sys_tty_release() : "
     1560                "TTY channel already released for thread %x\n", trdid );
     1561        return -1111;
     1562    }
     1563
     1564    // reset CTX_TTY_ID for the calling thread
     1565    _set_context_slot( CTX_TTY_ID , 0xFFFFFFFF );
     1566
     1567    // atomically decrement the _tty_channel_allocator[] array
     1568    _atomic_increment( &_tty_channel_alloc[channel] , -1 );
     1569
     1570    // release WTI mailbox if TTY channel no more used
     1571    if ( USE_PIC  && (_tty_channel_alloc[channel] == 0) )
     1572    {
     1573        _ext_irq_release( ISR_TTY_RX , channel );
     1574    }
     1575
     1576    return GIET_SYSCALL_OK;
     1577}  // end sys_tty_release()
     1578
     1579////////////////////////////////////////
    9961580int _sys_tty_write( const char*  buffer,   
    9971581                    unsigned int length,    // number of characters
     
    10021586    // compute and check tty channel
    10031587    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
    1004     if( channel >= NB_TTY_CHANNELS ) return -1;
     1588    if( channel >= NB_TTY_CHANNELS ) return -1111;
    10051589
    10061590    // write string to TTY channel
     
    10211605}
    10221606
    1023 ////////////////////////////////////////////////
     1607///////////////////////////////////////
    10241608int _sys_tty_read( char*        buffer,
    10251609                   unsigned int length,    // unused
     
    10281612    // compute and check tty channel
    10291613    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
    1030     if( channel >= NB_TTY_CHANNELS ) return -1;
    1031 
    1032     // read one character from TTY channel
    1033     if (_tty_rx_full[channel] == 0)
    1034     {
    1035         return 0;
    1036     }
    1037     else
    1038     {
    1039         *buffer = _tty_rx_buf[channel];
    1040         _tty_rx_full[channel] = 0;
    1041         return 1;
    1042     }
     1614    if( channel >= NB_TTY_CHANNELS ) return -1111;
     1615
     1616    unsigned int save_sr;
     1617    unsigned int found = 0;
     1618
     1619    // get pointer on TTY_RX FIFO
     1620    tty_fifo_t*  fifo = &_tty_rx_fifo[channel];
     1621
     1622    // try to read one character from FIFO
     1623    // blocked in while loop until success
     1624    while ( found == 0 )
     1625    {
     1626        if ( fifo->sts == 0)   // FIFO empty => deschedule
     1627        {
     1628            // enters critical section
     1629             _it_disable( &save_sr );
     1630
     1631            // set NORUN_MASK_TTY bit for calling thread
     1632            static_scheduler_t* psched  = (static_scheduler_t*)_get_sched();
     1633            unsigned int ltid = psched->current;
     1634            _atomic_or( &psched->context[ltid].slot[CTX_NORUN_ID] , NORUN_MASK_TTY );
     1635
     1636            // register descheduling thread trdid
     1637            fifo->trdid = _get_thread_trdid();
     1638
     1639             // deschedule calling thread
     1640            _ctx_switch();
     1641
     1642            // exit critical section
     1643            _it_restore( &save_sr );
     1644        }
     1645        else                             // FIFO not empty => get one character
     1646        {
     1647            *buffer   = fifo->data[fifo->ptr];
     1648            fifo->sts = fifo->sts - 1;
     1649            fifo->ptr = (fifo->ptr + 1) % TTY_FIFO_DEPTH;
     1650            found     = 1;
     1651        }
     1652    }
     1653
     1654    return 1;
    10431655}
    10441656
    1045 ///////////////////////////////////////////
    1046 int _sys_tty_get_lock( unsigned int   channel,       // unused
    1047                        unsigned int * save_sr_ptr )
    1048 {
    1049     // check tty channel
    1050     if( channel != 0 )  return 1;
    1051 
    1052     _it_disable( save_sr_ptr );
    1053     _sqt_lock_acquire( &_tty0_sqt_lock );
    1054     return 0;
    1055 }
    1056 
    1057 ///////////////////////////////////////////////
    1058 int _sys_tty_release_lock( unsigned int   channel,
    1059                            unsigned int * save_sr_ptr )
    1060 {
    1061     // check tty channel
    1062     if( channel != 0 )  return 1;
    1063 
    1064     _sqt_lock_release( &_tty0_sqt_lock );
    1065     _it_restore( save_sr_ptr );
    1066     return 0;
    1067 }
     1657
    10681658
    10691659//////////////////////////////////////////////////////////////////////////////
    1070 //             TIM related syscall handlers
     1660//             TIMER related syscall handlers
    10711661//////////////////////////////////////////////////////////////////////////////
    10721662
     
    10741664int _sys_tim_alloc()
    10751665{
    1076     // get a new timer index
    1077     unsigned int channel = _atomic_increment( &_tim_channel_allocator, 1 );
    1078 
     1666
     1667#if NB_TIM_CHANNELS
     1668
     1669    unsigned int channel;    // allocated TIMER channel
     1670
     1671    unsigned int trdid = _get_thread_trdid();
     1672
     1673    // check no TIMER already allocated to calling thread
     1674    if ( _get_context_slot( CTX_TIM_ID ) < NB_TIM_CHANNELS )
     1675    {
     1676        _printf("\n[GIET_ERROR] in _sys_tim_alloc() : "
     1677                "TIMER channel already allocated to thread %x\n", trdid );
     1678        return -1111;
     1679    }
     1680
     1681    // get a TIMER channel
     1682    for ( channel = 0 ; channel < NB_TIM_CHANNELS ; channel++ )
     1683    {
     1684        unsigned int* palloc  = &_tim_channel_alloc[channel];
     1685
     1686        if ( _atomic_test_and_set( palloc , 1 ) == 0 ) break;
     1687    }
    10791688    if ( channel >= NB_TIM_CHANNELS )
    10801689    {
    1081         _printf("\n[GIET_ERROR] in _sys_tim_alloc() : not enough TIM channels\n");
    1082         return -1;
    1083     }
    1084     else
    1085     {
    1086         _set_context_slot( CTX_TIM_ID, channel );
    1087         return 0;
    1088     }
    1089 }
    1090 
    1091 ////////////////////
    1092 // NOTE: not a syscall
    1093 int _sys_tim_release()
    1094 {
    1095     // release one timer
    1096     _atomic_increment( &_tim_channel_allocator, 0xFFFFFFFF );
    1097 
    1098     return 0;
    1099 }
     1690        _printf("\n[GIET_ERROR] in _sys_tim_alloc() : "
     1691                "no TIMER channel available for thread %x\n", trdid );
     1692        return -1111;
     1693    }
     1694
     1695    // allocate a WTI mailbox to the calling proc if external IRQ
     1696    unsigned int wti_id;
     1697    if ( USE_PIC ) _ext_irq_alloc( ISR_TIMER , channel , &wti_id );
     1698
     1699    // register wti_id and coordinates for processor receiving WTI
     1700    unsigned int procid = _get_procid();
     1701    unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
     1702    unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
     1703    unsigned int p      = procid & ((1<<P_WIDTH)-1);
     1704    _tim_channel_wti[channel] = x<<24 | y<<16 | p<<8 | wti_id;
     1705   
     1706    // update CTX_TIM_ID in thread context
     1707    _set_context_slot( CTX_TIM_ID, channel );
     1708
     1709    return GIET_SYSCALL_OK;
     1710
     1711#else
     1712
     1713    _printf("\n[GIET ERROR] in _sys_tim_alloc() : NB_TIM_CHANNELS = 0\n");
     1714    return -1111;
     1715
     1716#endif
     1717}  // end _sys_tim_alloc()
     1718
     1719
     1720//////////////////////
     1721int _sys_tim_release()     // NOTE: not a syscall
     1722{
     1723
     1724#if NB_TIM_CHANNELS
     1725
     1726    unsigned int channel = _get_context_slot( CTX_TIM_ID );
     1727
     1728    if ( channel == -1 )
     1729    {
     1730        unsigned int trdid = _get_thread_trdid();
     1731        _printf("\n[GIET_ERROR] in _sys_tim_release() : "
     1732                "TIMER channel already released for thread %x\n", trdid );
     1733        return -1111;
     1734    }
     1735
     1736    // reset CTX_TIM_ID for the calling thread
     1737    _set_context_slot( CTX_TIM_ID , 0xFFFFFFFF );
     1738
     1739    // reset the _tim_channel_alloc[] array
     1740    _tim_channel_alloc[channel] = 0;
     1741
     1742    // release WTI mailbox if TTY channel no more used
     1743    if ( USE_PIC )
     1744    {
     1745        _ext_irq_release( PERIPH_TYPE_TIM , channel );
     1746    }
     1747
     1748    return GIET_SYSCALL_OK;
     1749
     1750#else
     1751
     1752    _printf("\n[GIET ERROR] in _sys_tim_release() : NB_TIM_CHANNELS = 0\n");
     1753    return -1111;
     1754
     1755#endif
     1756}  // end _sys_tim_release()
    11001757
    11011758/////////////////////////////////////////
    11021759int _sys_tim_start( unsigned int period )
    11031760{
     1761
     1762#if NB_TIM_CHANNELS
     1763
    11041764    // get timer index
    11051765    unsigned int channel = _get_context_slot( CTX_TIM_ID );
     
    11071767    {
    11081768        _printf("\n[GIET_ERROR] in _sys_tim_start() : not enough TIM channels\n");
    1109         return -1;
     1769        return -1111;
    11101770    }
    11111771
     
    11131773    _timer_start( channel, period );
    11141774
    1115     return 0;
     1775    return GIET_SYSCALL_OK;
     1776
     1777#else
     1778
     1779    _printf("\n[GIET ERROR] in _sys_tim_start() : NB_TIM_CHANNELS = 0\n");
     1780    return -1111;
     1781
     1782#endif
    11161783}
    11171784
     
    11191786int _sys_tim_stop()
    11201787{
     1788
     1789#if NB_TIM_CHANNELS
     1790
    11211791    // get timer index
    11221792    unsigned int channel = _get_context_slot( CTX_TIM_ID );
     
    11241794    {
    11251795        _printf("\n[GIET_ERROR] in _sys_tim_stop() : illegal timer index\n");
    1126         return -1;
     1796        return -1111;
    11271797    }
    11281798
     
    11301800    _timer_stop( channel );
    11311801
    1132     return 0;
     1802    return GIET_SYSCALL_OK;
     1803
     1804#else
     1805
     1806    _printf("\n[GIET ERROR] in _sys_tim_stop() : NB_TIM_CHANNELS = 0\n");
     1807    return -1111;
     1808
     1809#endif
    11331810}
     1811
    11341812
    11351813//////////////////////////////////////////////////////////////////////////////
     
    11381816
    11391817#define NIC_CONTAINER_SIZE 4096
     1818
     1819#if NB_NIC_CHANNELS
    11401820
    11411821////////////////////////////////////////
     
    11441824                    unsigned int ymax )
    11451825{
     1826    mapping_header_t  *header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     1827    mapping_vspace_t  *vspace   = _get_vspace_base(header);
     1828    mapping_thread_t  *thread   = _get_thread_base(header);
     1829
     1830    // get calling thread trdid, vspace index, and number of threads
     1831    unsigned int trdid = _get_thread_trdid();
     1832    unsigned int vsid  = _get_context_slot( CTX_VSID_ID );
     1833    unsigned int users = vspace[vsid].threads;
     1834
    11461835    // check xmax / ymax parameters
    1147     if ( xmax > X_SIZE )
    1148     {
    1149         _printf("\n[GIET_ERROR] in _sys_nic_alloc() xmax argument too large\n");
    1150         return -1;
    1151     }
    1152     if ( ymax > Y_SIZE )
    1153     {
    1154         _printf("\n[GIET_ERROR] in _sys_nic_alloc() ymax argument too large\n");
    1155         return -1;
     1836    if ( (xmax > X_SIZE) || (ymax > Y_SIZE) )
     1837    {
     1838        _printf("\n[GIET_ERROR] in _sys_nic_alloc() "
     1839                "xmax or ymax argument too large for thread %x\n", trdid );
     1840        return -1111;
    11561841    }
    11571842
     
    11601845    ////////////////////////////////////////////////////////
    11611846
    1162     // get a NIC_RX or NIC_TX channel index
    1163     unsigned int nic_channel;
    1164     unsigned int cma_channel;
    1165 
    1166     if ( is_rx ) nic_channel = _atomic_increment( &_nic_rx_channel_allocator, 1 );
    1167     else         nic_channel = _atomic_increment( &_nic_tx_channel_allocator, 1 );
    1168 
     1847    unsigned int   nic_channel;
     1848    unsigned int   cma_channel;
     1849    unsigned int*  palloc;
     1850
     1851    // get a NIC_RX or NIC_TX channel
     1852    for ( nic_channel = 0 ; nic_channel < NB_NIC_CHANNELS ; nic_channel++ )
     1853    {
     1854        if ( is_rx ) palloc = &_nic_rx_channel_alloc[nic_channel];
     1855        else         palloc = &_nic_tx_channel_alloc[nic_channel];
     1856
     1857        if ( _atomic_test_and_set( palloc , users ) == 0 ) break;
     1858    }
    11691859    if ( (nic_channel >= NB_NIC_CHANNELS) )
    11701860    {
    1171         _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough NIC channels\n");
    1172         return -1;
    1173     }
    1174 
    1175     // get a CMA channel index
     1861        _printf("\n[GIET_ERROR] in _sys_nic_alloc() : "
     1862                "no NIC channel available for thread %x\n", trdid );
     1863        return -1111;
     1864    }
     1865
     1866    // get a CMA channel
    11761867    for ( cma_channel = 0 ; cma_channel < NB_CMA_CHANNELS ; cma_channel++ )
    11771868    {
    1178         if ( !_cma_channel[cma_channel] )
     1869        palloc = &_cma_channel_alloc[cma_channel];
     1870
     1871        if ( _atomic_test_and_set( palloc , users ) == 0 ) break;
     1872    }
     1873    if ( cma_channel >= NB_CMA_CHANNELS )
     1874    {
     1875        _printf("\n[GIET_ERROR] in _sys_nic_alloc() : "
     1876                "no CMA channel available for thread %x\n", trdid );
     1877        if ( is_rx )  _nic_rx_channel_alloc[nic_channel] = 0;
     1878        else          _nic_tx_channel_alloc[nic_channel] = 0;
     1879        return -1111;
     1880    }
     1881
     1882#if GIET_DEBUG_NIC
     1883_printf("\n[GIET DEBUG NIC] Thread %d enters sys_nic_alloc() at cycle %d\n"
     1884        "  nic_channel = %d / cma_channel = %d\n",
     1885        trdid , _get_proctime() , nic_channel , cma_channel );
     1886#endif
     1887
     1888    // register nic_index and cma_index in all threads
     1889    // contexts that are in the same vspace
     1890    unsigned int tid;
     1891    for (tid = vspace[vsid].thread_offset;
     1892         tid < (vspace[vsid].thread_offset + vspace[vsid].threads);
     1893         tid++)
     1894    {
     1895        unsigned int y_size        = header->y_size;
     1896        unsigned int cid           = thread[tid].clusterid;
     1897        unsigned int x             = cid / y_size;
     1898        unsigned int y             = cid % y_size;
     1899        unsigned int p             = thread[tid].proclocid;
     1900        unsigned int ltid          = thread[tid].ltid;
     1901        static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p];
     1902
     1903        if ( is_rx )
    11791904        {
    1180             _cma_channel[cma_channel] = 1;
    1181             break;
     1905            if ( (psched->context[ltid].slot[CTX_NIC_RX_ID] < NB_NIC_CHANNELS) ||
     1906                 (psched->context[ltid].slot[CTX_CMA_RX_ID] < NB_CMA_CHANNELS) )
     1907            {
     1908                _printf("\n[GIET_ERROR] in _sys_nic_alloc() : "
     1909                        "NIC_RX or CMA_RX channel already allocated for thread %x\n", trdid );
     1910                _nic_rx_channel_alloc[nic_channel] = 0;
     1911                _cma_channel_alloc[cma_channel]    = 0;
     1912                return -1111;
     1913            }
     1914            else
     1915            {
     1916                psched->context[ltid].slot[CTX_NIC_RX_ID] = nic_channel;
     1917                psched->context[ltid].slot[CTX_CMA_RX_ID] = cma_channel;
     1918            }
    11821919        }
    1183     }
    1184 
    1185     if ( cma_channel >= NB_CMA_CHANNELS )
    1186     {
    1187         _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough CMA channels\n");
    1188         return -1;
    1189     }
    1190 
    1191 #if GIET_DEBUG_NIC
    1192 unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
    1193 _printf("\n[GIET DEBUG NIC] Task %d enters sys_nic_alloc() at cycle %d\n"
    1194         "  nic_channel = %d / cma_channel = %d\n",
    1195         thread , _get_proctime() , nic_channel , cma_channel );
    1196 #endif
    1197 
    1198     // register nic_index and cma_index in task context
    1199     if ( is_rx )
    1200     {
    1201         _set_context_slot( CTX_NIC_RX_ID, nic_channel );
    1202         _set_context_slot( CTX_CMA_RX_ID, cma_channel );
    1203     }
    1204     else
    1205     {
    1206         _set_context_slot( CTX_NIC_TX_ID, nic_channel );
    1207         _set_context_slot( CTX_CMA_TX_ID, cma_channel );
    1208     }
     1920        else // is_tx
     1921        {
     1922            if ( (psched->context[ltid].slot[CTX_NIC_TX_ID] < NB_NIC_CHANNELS) ||
     1923                 (psched->context[ltid].slot[CTX_CMA_TX_ID] < NB_CMA_CHANNELS) )
     1924            {
     1925                _printf("\n[GIET_ERROR] in _sys_nic_alloc() : "
     1926                        "NIC_TX or CMA_TX channel already allocated for thread %x\n", trdid );
     1927                _nic_tx_channel_alloc[nic_channel] = 0;
     1928                _cma_channel_alloc[cma_channel]    = 0;
     1929                return -1111;
     1930            }
     1931            else
     1932            {
     1933                psched->context[ltid].slot[CTX_NIC_TX_ID] = nic_channel;
     1934                psched->context[ltid].slot[CTX_CMA_TX_ID] = cma_channel;
     1935            }
     1936        }
     1937    }  // end loop on threads
    12091938
    12101939    /////////////////////////////////////////////////////////////////////////////////
     
    12411970            if ( vaddr == 0 )  // not enough kernel heap memory in cluster[cx,cy]
    12421971            {
    1243                 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough kenel heap"
    1244                         " in cluster[%d,%d]\n", cx, cy );
    1245                 return -1;
     1972                _printf("\n[GIET_ERROR] in _sys_nic_alloc() : "
     1973                        "not enough kenel heap in cluster[%d,%d]\n", cx, cy );
     1974                return -1111;
    12461975            }
    12471976
     
    12521981            if ( cont_paddr & 0x3F )
    12531982            {
    1254                 _printf("\n[GIET ERROR] in _sys_nic_alloc() : container address of cluster[%d,%d] not aligned\n",
    1255                         cx, cy);
    1256                 return -1;
     1983                _printf("\n[GIET ERROR] in _sys_nic_alloc() : "
     1984                        "container address of cluster[%d,%d] not aligned\n", cx, cy);
     1985                return -1111;
    12571986            }
    12581987
     
    12701999            if ( vaddr == 0 )  // not enough kernel heap memory in cluster[cx,cy]
    12712000            {
    1272                 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough kenel heap"
    1273                         " in cluster[%d,%d]\n", cx, cy );
    1274                 return -1;
     2001                _printf("\n[GIET_ERROR] in _sys_nic_alloc() : "
     2002                        "not enough kernel heap in cluster[%d,%d]\n", cx, cy );
     2003                return -1111;
    12752004            }
    12762005
     
    12812010            if ( sts_paddr & 0x3F )
    12822011            {
    1283                 _printf("\n[GIET ERROR] in _sys_nic_alloc() : status address of cluster[%d,%d] not aligned\n",
    1284                         cx, cy);
    1285                 return -1;
     2012                _printf("\n[GIET ERROR] in _sys_nic_alloc() : "
     2013                        "status address of cluster[%d,%d] not aligned\n", cx, cy);
     2014                return -1111;
    12862015            }
    12872016
     
    13852114#endif
    13862115
    1387     return nic_channel;
     2116    return GIET_SYSCALL_OK;
    13882117} // end _sys_nic_alloc()
    13892118
    13902119
    1391 ////////////////////////////////////////
    1392 // NOTE: not a syscall
    1393 int _sys_nic_release( unsigned int is_rx )
    1394 {
    1395     if ( is_rx )
    1396         _atomic_increment( &_nic_rx_channel_allocator , 0xFFFFFFFF );
    1397     else
    1398         _atomic_increment( &_nic_tx_channel_allocator , 0xFFFFFFFF );
    1399 
    1400     return 0;
    1401 }
    1402 
    1403 
    1404 ////////////////////////////////////////
    1405 int _sys_nic_start( unsigned int is_rx,
    1406                     unsigned int channel )
    1407 {
     2120//////////////////////////////////////////
     2121int _sys_nic_release( unsigned int is_rx )     // NOTE: not a syscall
     2122{
     2123    unsigned int trdid = _get_thread_trdid();
     2124
    14082125    unsigned int nic_channel;
    14092126    unsigned int cma_channel;
    1410 
    1411     // get NIC channel index and CMA channel index from task context
     2127   
     2128    // update the kernel tables
    14122129    if ( is_rx )
    14132130    {
    14142131        nic_channel = _get_context_slot( CTX_NIC_RX_ID );
    14152132        cma_channel = _get_context_slot( CTX_CMA_RX_ID );
    1416     }
     2133
     2134        if ( (nic_channel >= NB_NIC_CHANNELS) )
     2135        {
     2136            _printf("\n[GIET ERROR] in _sys_nic_release() : "
     2137                    "NIC_RX channel already released for thread %x\n", trdid );
     2138            return -1111;
     2139        }
     2140        if ( (cma_channel >= NB_CMA_CHANNELS) )
     2141        {
     2142            _printf("\n[GIET ERROR] in _sys_nic_release() : "
     2143                    "CMA_RX channel already released for thread %x\n", trdid );
     2144            return -1111;
     2145        }
     2146
     2147        // atomically decrement the NIC and CMA channel allocators
     2148        _atomic_increment( &_nic_rx_channel_alloc[nic_channel] , -1 );
     2149        _atomic_increment( &_cma_channel_alloc[cma_channel] , -1 );
     2150   
     2151        // stop the NIC and CMA peripherals channels if no more users
     2152        if ( (_nic_rx_channel_alloc[nic_channel] == 0) &&
     2153             (_cma_channel_alloc[cma_channel] == 0) )  _sys_nic_stop( 1 );
     2154
     2155        // reset the calling thread context slots
     2156        _set_context_slot( CTX_NIC_RX_ID , 0xFFFFFFFF );
     2157        _set_context_slot( CTX_CMA_RX_ID , 0xFFFFFFFF );
     2158    }         
    14172159    else
    14182160    {
    14192161        nic_channel = _get_context_slot( CTX_NIC_TX_ID );
    14202162        cma_channel = _get_context_slot( CTX_CMA_TX_ID );
     2163
     2164        if ( (nic_channel >= NB_NIC_CHANNELS) )
     2165        {
     2166            _printf("\n[GIET ERROR] in _sys_nic_release() : "
     2167                    "NIC_TX channel already released for thread %x\n", trdid );
     2168            return -1111;
     2169        }
     2170        if ( (cma_channel >= NB_CMA_CHANNELS) )
     2171        {
     2172            _printf("\n[GIET ERROR] in _sys_nic_release() : "
     2173                    "CMA_TX channel already released for thread %x\n", trdid );
     2174            return -1111;
     2175        }
     2176
     2177        // atomically decrement the NIC and CMA channel allocators
     2178        _atomic_increment( &_nic_tx_channel_alloc[nic_channel] , -1 );
     2179        _atomic_increment( &_cma_channel_alloc[cma_channel] , -1 );
     2180   
     2181        // stop the NIC and CMA peripherals channels if no more users
     2182        if ( (_nic_tx_channel_alloc[nic_channel] == 0) &&
     2183             (_cma_channel_alloc[cma_channel] == 0) )  _sys_nic_stop( 0 );
     2184
     2185        // reset the calling thread context slots
     2186        _set_context_slot( CTX_NIC_TX_ID , 0xFFFFFFFF );
     2187        _set_context_slot( CTX_CMA_TX_ID , 0xFFFFFFFF );
     2188    }
     2189
     2190    return GIET_SYSCALL_OK;
     2191}  // end sys_nic_release()
     2192
     2193
     2194////////////////////////////////////////
     2195int _sys_nic_start( unsigned int is_rx )
     2196{
     2197    unsigned int trdid  = _get_context_slot( CTX_TRDID_ID );
     2198
     2199    unsigned int nic_channel;
     2200    unsigned int cma_channel;
     2201
     2202    // get NIC channel index and CMA channel index from thread context
     2203    if ( is_rx )
     2204    {
     2205        nic_channel = _get_context_slot( CTX_NIC_RX_ID );
     2206        cma_channel = _get_context_slot( CTX_CMA_RX_ID );
     2207    }
     2208    else
     2209    {
     2210        nic_channel = _get_context_slot( CTX_NIC_TX_ID );
     2211        cma_channel = _get_context_slot( CTX_CMA_TX_ID );
    14212212    }
    14222213
    14232214#if GIET_DEBUG_NIC
    1424 unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
    1425 _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_start() at cycle %d\n"
     2215_printf("\n[GIET DEBUG NIC] Thread %x in _sys_nic_start() at cycle %d\n"
    14262216        "  get NIC channel = %d / CMA channel = %d\n",
    1427         thread, _get_proctime(), nic_channel, cma_channel );
     2217        trdid, _get_proctime(), nic_channel, cma_channel );
    14282218#endif
    14292219
    14302220    // check NIC and CMA channels index
    1431     if ( nic_channel != channel )
    1432     {
    1433         _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal NIC channel\n");
    1434         return -1;
     2221    if ( nic_channel >= NB_NIC_CHANNELS )
     2222    {
     2223        _printf("\n[GIET_ERROR] in _sys_nic_start() : "
     2224                "illegal NIC channel for thread %x\n", trdid );
     2225        return -1111;
    14352226    }
    14362227    if ( cma_channel >= NB_CMA_CHANNELS )
    14372228    {
    1438         _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal CMA channel\n");
    1439         return -1;
     2229        _printf("\n[GIET_ERROR] in _sys_nic_start() : "
     2230                "illegal CMA channel for thread %x\n", trdid );
     2231        return -1111;
    14402232    }
    14412233
     
    14502242#if GIET_DEBUG_NIC
    14512243    _printf("\n[GIET DEBUG NIC] Task %d exit _sys_nic_start() at cycle %d\n",
    1452             thread , _get_proctime() );
    1453 #endif
    1454 
    1455     return 0;
     2244            trdid , _get_proctime() );
     2245#endif
     2246
     2247    return GIET_SYSCALL_OK;
    14562248}  // end _sys_nic_start()
    14572249
     
    14592251//////////////////////////////////////
    14602252int _sys_nic_move( unsigned int is_rx,
    1461                    unsigned int channel,
    14622253                   void*        buffer )
    14632254{
     2255    unsigned int trdid  = _get_context_slot( CTX_TRDID_ID );
     2256
     2257    unsigned int channel;
    14642258
    14652259#if GIET_DEBUG_NIC
    1466 unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
    14672260_printf("\n[GIET DEBUG NIC] Task %d enters _sys_nic_move() at cycle %d\n",
    1468         thread , _get_proctime() );
    1469 #endif
     2261        trdid , _get_proctime() );
     2262#endif
     2263
     2264    // get NIC channel index from thread context
     2265    if ( is_rx )  channel = _get_context_slot( CTX_NIC_RX_ID );
     2266    else          channel = _get_context_slot( CTX_NIC_TX_ID );
    14702267
    14712268    // check NIC channel index
    14722269    if ( channel >= NB_NIC_CHANNELS )
    14732270    {
    1474         _printf("\n[GIET_ERROR] in _sys_nic_move() : illegal NIC channel index\n");
    1475         return -1;
     2271        _printf("\n[GIET_ERROR] in _sys_nic_move() : "
     2272                "illegal NIC channel index for thread %x\n", trdid );
     2273        return -1111;
    14762274    }
    14772275
     
    14852283    unsigned int ymax = ker_chbuf->ymax;
    14862284
    1487     // get cluster coordinates for the processor running the calling task
     2285    // get cluster coordinates for the processor running the calling thread
    14882286    unsigned int  procid = _get_procid();
    14892287    unsigned int  cx     = procid >> (Y_WIDTH + P_WIDTH);
     
    14952293        _printf("\n[GIET_ERROR] in _sys_nic_move() : processor X coordinate = %d"
    14962294                " / xmax = %d\n", cx , xmax );
    1497         return -1;
     2295        return -1111;
    14982296    }
    14992297    if ( cy >= ymax )
     
    15012299        _printf("\n[GIET_ERROR] in _sys_nic_move() : processor Y coordinate = %d"
    15022300                " / ymax = %d\n", cy , ymax );
    1503         return -1;
     2301        return -1111;
    15042302    }
    15052303   
     
    15182316    {
    15192317        _printf("\n[GIET ERROR] in _sys_nic_tx_move() : illegal user buffer address\n");
    1520         return -1;
     2318        return -1111;
    15212319    }
    15222320
     
    16062404#endif
    16072405
    1608     return 0;
     2406    return GIET_SYSCALL_OK;
    16092407} // end _sys_nic_move()
    16102408
    16112409
    1612 ////////////////////////////////////////
    1613 int _sys_nic_stop( unsigned int is_rx,
    1614                    unsigned int channel )
    1615 {
     2410///////////////////////////////////////
     2411int _sys_nic_stop( unsigned int is_rx )
     2412{
     2413    unsigned int trdid  = _get_context_slot( CTX_TRDID_ID );
     2414
    16162415    unsigned int nic_channel;
    16172416    unsigned int cma_channel;
     
    16302429
    16312430    // check NIC and CMA channels index
    1632     if ( nic_channel != channel )
    1633     {
    1634         _printf("\n[GIET_ERROR] in _sys_nic_stop(): illegal NIC channel\n");
    1635         return -1;
     2431    if ( nic_channel >= NB_NIC_CHANNELS )
     2432    {
     2433        _printf("\n[GIET_ERROR] in _sys_nic_stop() : "
     2434                "illegal NIC channel for thread %x\n", trdid );
     2435        return -1111;
    16362436    }
    16372437    if ( cma_channel >= NB_CMA_CHANNELS )
    16382438    {
    1639         _printf("\n[GIET_ERROR] in _sys_nic_stop(): illegal CMA channel\n");
    1640         return -1;
    1641     }
     2439        _printf("\n[GIET_ERROR] in _sys_nic_stop() : "
     2440                "illegal CMA channel for thread %x\n", trdid );
     2441        return -1111;
     2442    }
     2443
     2444    // desactivates the CMA channel
     2445    _cma_set_register( cma_channel, CHBUF_RUN , 0 );
     2446
     2447    // wait until CMA channel IDLE
     2448    unsigned int volatile status;
     2449    do
     2450    {
     2451         status = _cma_get_register( cma_channel, CHBUF_STATUS );
     2452    } while ( status );
    16422453
    16432454    // desactivates the NIC channel
    16442455    _nic_channel_stop( nic_channel, is_rx );
    16452456
    1646     // desactivates the CMA channel
    1647     _cma_set_register( cma_channel, CHBUF_RUN , 0 );
    1648 
    1649     return 0;
     2457    return GIET_SYSCALL_OK;
    16502458}  // end _sys_nic_stop()
    16512459
    16522460////////////////////////////////////////
    1653 int _sys_nic_clear( unsigned int is_rx,
    1654                     unsigned int channel )
    1655 {
    1656     unsigned int nic_channel;
     2461int _sys_nic_clear( unsigned int is_rx )
     2462{
     2463    unsigned int trdid  = _get_context_slot( CTX_TRDID_ID );
     2464
     2465    unsigned int channel;
    16572466
    16582467    // get NIC channel
    1659     if ( is_rx )  nic_channel = _get_context_slot( CTX_NIC_RX_ID );
    1660     else          nic_channel = _get_context_slot( CTX_NIC_TX_ID );
    1661 
    1662     if ( nic_channel != channel )
    1663     {
    1664         _printf("\n[GIET_ERROR] in _sys_nic_clear(): illegal NIC channel\n");
    1665         return -1;
     2468    if ( is_rx )  channel = _get_context_slot( CTX_NIC_RX_ID );
     2469    else          channel = _get_context_slot( CTX_NIC_TX_ID );
     2470
     2471    if ( channel >= NB_NIC_CHANNELS )
     2472    {
     2473        _printf("\n[GIET_ERROR] in _sys_nic_clear() : "
     2474                "illegal NIC channel for thread %x\n", trdid );
     2475        return -1111;
    16662476    }
    16672477
     
    16882498        _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_BROADCAST , 0 );
    16892499    }
    1690     return 0;
     2500    return GIET_SYSCALL_OK;
    16912501}  // en _sys_nic_clear()
    16922502
    16932503////////////////////////////////////////
    1694 int _sys_nic_stats( unsigned int is_rx,
    1695                     unsigned int channel )
    1696 {
     2504int _sys_nic_stats( unsigned int is_rx )
     2505{
     2506    unsigned int trdid  = _get_context_slot( CTX_TRDID_ID );
     2507
    16972508    unsigned int nic_channel;
    16982509
     
    17012512    else          nic_channel = _get_context_slot( CTX_NIC_TX_ID );
    17022513
    1703     if ( nic_channel != channel )
    1704     {
    1705         _printf("\n[GIET_ERROR] in _sys_nic_stats(): illegal NIC channel\n");
    1706         return -1;
     2514    if ( nic_channel >= NB_NIC_CHANNELS )
     2515    {
     2516        _printf("\n[GIET_ERROR] in _sys_nic_stats() : "
     2517                "illegal NIC channel for thread %x\n", trdid );
     2518        return -1111;
    17072519    }
    17082520
     
    17592571                broadcast );
    17602572    }
    1761     return 0;
     2573    return GIET_SYSCALL_OK;
    17622574}  // end _sys_nic_stats()
     2575
     2576#endif
    17632577
    17642578/////////////////////////////////////////////////////////////////////////////////////////
     
    17742588    memcpy( fbf_address, buffer, length);
    17752589
    1776     return 0;
     2590    return GIET_SYSCALL_OK;
    17772591}
    17782592
     
    17852599    memcpy( buffer, fbf_address, length);
    17862600
    1787     return 0;
     2601    return GIET_SYSCALL_OK;
    17882602}
    17892603
     
    17912605int _sys_fbf_cma_alloc()
    17922606{
     2607    unsigned int trdid = _get_thread_trdid();
     2608
    17932609    if ( _get_context_slot( CTX_CMA_FB_ID ) < NB_CMA_CHANNELS )
    17942610    {
    1795         _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : CMA channel already allocated\n");
    1796         return 0;
    1797     }
    1798 
    1799     // get a new CMA channel index
     2611        _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : "
     2612                "CMA channel already allocated for thread %x\n", trdid );
     2613        return GIET_SYSCALL_OK;
     2614    }
     2615
     2616    // get a CMA channel
    18002617    unsigned int channel;
    1801 
    18022618    for ( channel = 0 ; channel < NB_CMA_CHANNELS ; channel++ )
    18032619    {
    1804         if ( !_cma_channel[channel] )
    1805         {
    1806             _cma_channel[channel] = 1;
    1807             break;
    1808         }
    1809     }
    1810 
     2620        unsigned int*  palloc = &_cma_channel_alloc[channel];
     2621        if ( _atomic_test_and_set( palloc , 1 ) == 0 ) break;
     2622    }
    18112623    if ( channel >= NB_CMA_CHANNELS )
    18122624    {
    18132625        _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : no CMA channel available\n");
    1814         return -1;
     2626        return -1111;
    18152627    }
    18162628    else
    18172629    {
    18182630        _set_context_slot( CTX_CMA_FB_ID, channel );
    1819         return 0;
     2631        return GIET_SYSCALL_OK;
    18202632    }
    18212633} // end sys_fbf_cma_alloc()
    18222634
    1823 ////////////////////////
    1824 // NOTE: not a syscall
    1825 int _sys_fbf_cma_release()
     2635//////////////////////////
     2636int _sys_fbf_cma_release()  // Not a syscall
    18262637{
    18272638    unsigned int channel = _get_context_slot( CTX_CMA_FB_ID );
     2639    unsigned int trdid   = _get_thread_trdid();
    18282640
    18292641    if ( channel >= NB_CMA_CHANNELS )
    18302642    {
    1831         _printf("\n[GIET_ERROR] in _sys_fbf_cma_release() : CMA channel already released\n");
    1832         return -1;
    1833     }
    1834 
    1835     // stop fb
     2643        _printf("\n[GIET_ERROR] in _sys_fbf_cma_release() : "
     2644                "CMA_FB channel already releasedifor thread %x\n", trdid );
     2645        return -1111;
     2646    }
     2647
     2648    // stop CMA transfer
    18362649    _sys_fbf_cma_stop();
    18372650
    1838     // reset CTX_CMA_FB_ID for task
    1839     _set_context_slot( CTX_CMA_FB_ID, -1 );
     2651    // reset CTX_CMA_FB_ID for thread
     2652    _set_context_slot( CTX_CMA_FB_ID, 0xFFFFFFFF );
    18402653
    18412654    // release CMA channel
    1842     _cma_channel[channel] = 0;
    1843 
    1844     return 0;
     2655    _cma_channel_alloc[channel] = 0;
     2656
     2657    return GIET_SYSCALL_OK;
    18452658}
    18462659
     
    18682681    {
    18692682        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : CMA channel index too large\n");
    1870         return -1;
     2683        return -1111;
    18712684    }
    18722685
     
    18902703    {
    18912704        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : user buffer not aligned\n");
    1892         return -1;
     2705        return -1111;
    18932706    }
    18942707
     
    18982711    {
    18992712        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : user status not aligned\n");
    1900         return -1;
     2713        return -1111;
    19012714    }
    19022715
     
    19172730    {
    19182731        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : buf0 not in user space\n");
    1919         return -1;
     2732        return -1111;
    19202733    }
    19212734
     
    19252738    {
    19262739        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : sts0 not in user space\n");
    1927         return -1;
     2740        return -1111;
    19282741    }
    19292742
     
    19382751    {
    19392752        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : buf1 not in user space\n");
    1940         return -1;
     2753        return -1111;
    19412754    }
    19422755
     
    19462759    {
    19472760        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : sts1 not in user space\n");
    1948         return -1;
     2761        return -1111;
    19492762    }
    19502763
     
    19742787#endif
    19752788
    1976     return 0;
     2789    return GIET_SYSCALL_OK;
    19772790
    19782791#else
    19792792
    19802793    _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : NB_CMA_CHANNELS = 0\n");
    1981     return -1;
     2794    return -1111;
    19822795
    19832796#endif 
     
    19952808    {
    19962809        _printf("\n[GIET ERROR] in _fbf_cma_start() : CMA channel index too large\n");
    1997         return -1;
     2810        return -1111;
    19982811    }
    19992812
     
    20052818        _printf("\n[GIET ERROR] in _sys_fbf_cma_start() :\n"
    20062819                "Buffer initialization has not been done\n");
    2007         return -1;
     2820        return -1111;
    20082821    }
    20092822
     
    20342847    _cma_set_register( channel, CHBUF_RUN      , 1 );
    20352848
    2036     return 0;
     2849    return GIET_SYSCALL_OK;
    20372850
    20382851#else
    20392852
    20402853    _printf("\n[GIET ERROR] in _sys_fbf_cma_start() : NB_CMA_CHANNELS = 0\n");
    2041     return -1;
     2854    return -1111;
    20422855
    20432856#endif
     
    20582871        _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : "
    20592872                "CMA channel index too large\n");
    2060         return -1;
     2873        return -1111;
    20612874    }
    20622875
     
    21382951    _mmc_sync( fbf_sts_paddr, 4 );
    21392952
    2140     return 0;
     2953    return GIET_SYSCALL_OK;
    21412954
    21422955#else
    21432956
    21442957    _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : no CMA channel allocated\n");
    2145     return -1;
     2958    return -1111;
    21462959
    21472960#endif
     
    21592972    {
    21602973        _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : CMA channel index too large\n");
    2161         return -1;
     2974        return -1111;
    21622975    }
    21632976
     
    21652978    _cma_set_register( channel, CHBUF_RUN, 0 );
    21662979
    2167     return 0;
     2980    return GIET_SYSCALL_OK;
    21682981
    21692982#else
    21702983
    21712984    _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : no CMA channel allocated\n");
    2172     return -1;
     2985    return -1111;
    21732986
    21742987#endif
     
    21842997{
    21852998    _printf("\n[GIET ERROR] Undefined System Call / EPC = %x\n", _get_epc() );
    2186     return -1;
     2999    return GIET_SYSCALL_UNDEFINED_SYSTEM_CALL;
    21873000}
    21883001
     
    21983011    *p = gpid & ((1<<P_WIDTH)-1);
    21993012
    2200     return 0;
    2201 }
    2202 
    2203 //////////////////////////////////
    2204 int _sys_task_exit( char* string )
    2205 {
    2206     unsigned int date       = _get_proctime();
    2207 
    2208     unsigned int gpid       = _get_procid();
    2209     unsigned int cluster_xy = gpid >> P_WIDTH;
    2210     unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    2211     unsigned int x          = cluster_xy >> Y_WIDTH;
    2212     unsigned int p          = gpid & ((1<<P_WIDTH)-1);
    2213 
    2214     unsigned int ltid       = _get_context_slot(CTX_LTID_ID);
    2215 
    2216     // print exit message
    2217     _printf("\n[GIET] Exit task %d on processor[%d,%d,%d] at cycle %d"
    2218             "\n       Cause : %s\n\n",
    2219             ltid, x, y, p, date, string );
    2220 
    2221     // set NORUN_MASK_TASK bit (non runnable state)
    2222     static_scheduler_t*  psched  = (static_scheduler_t*)_schedulers[x][y][p];
    2223     unsigned int*        ptr     = &psched->context[ltid][CTX_NORUN_ID];
    2224     _atomic_or( ptr , NORUN_MASK_TASK );
    2225 
    2226     // deschedule
    2227     _sys_context_switch();
    2228 
    2229     return 0;
    2230 }
    2231 
    2232 /////////////////////////
    2233 int _sys_context_switch()
    2234 {
    2235     unsigned int save_sr;
    2236 
    2237     _it_disable( &save_sr );
    2238     _ctx_switch();
    2239     _it_restore( &save_sr );
    2240 
    2241     return 0;
    2242 }
    2243 
    2244 ////////////////////////
    2245 int _sys_local_task_id()
    2246 {
    2247     return _get_context_slot(CTX_LTID_ID);
    2248 }
    2249 
    2250 /////////////////////////
    2251 int _sys_global_task_id()
    2252 {
    2253     return _get_context_slot(CTX_GTID_ID);
    2254 }
    2255 
    2256 ////////////////////
    2257 int _sys_thread_id()
    2258 {
    2259     return _get_context_slot(CTX_TRDID_ID);
     3013    return GIET_SYSCALL_OK;
    22603014}
    22613015
     
    23123066        *nprocs = 0;
    23133067    }
    2314     return 0;
     3068    return GIET_SYSCALL_OK;
    23153069}
    23163070
     
    23403094                {
    23413095                    *vbase = vseg[vseg_id].vbase;
    2342                     return 0;
     3096                    return GIET_SYSCALL_OK;
    23433097                }
    23443098            }
    23453099        }
    23463100    }
    2347     return -1;    // not found
     3101    return GIET_SYSCALL_VSEG_NOT_FOUND;
    23483102}
    23493103
     
    23733127                {
    23743128                    *length = vseg[vseg_id].length;
    2375                     return 0;
     3129                    return GIET_SYSCALL_OK;
    23763130                }
    23773131            }
    23783132        }
    23793133    }
    2380     return -1;    // not found
     3134    return GIET_SYSCALL_VSEG_NOT_FOUND;
    23813135}
    23823136
     
    23923146    *y = (paddr>>32) & 0xF;
    23933147
    2394     return 0;
     3148    return GIET_SYSCALL_OK;
    23953149}
    23963150
     
    24013155                    unsigned int  y )
    24023156{
     3157    // checking parameters
     3158    if ( (x >= X_SIZE) || (y >= Y_SIZE) ) 
     3159    {
     3160        *vaddr  = 0;
     3161        *length = 0;
     3162        _printf("\n[GIET ERROR] in _sys_heap_info() : "
     3163                "illegal (%d,%d) coordinates\n", x , y );
     3164        return GIET_SYSCALL_ILLEGAL_CLUSTER_COORDINATES;
     3165    }
     3166
    24033167    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    2404     mapping_task_t *   task    = _get_task_base(header);
     3168    mapping_thread_t * thread  = _get_thread_base(header);
    24053169    mapping_vseg_t *   vseg    = _get_vseg_base(header);
    24063170    mapping_vspace_t * vspace  = _get_vspace_base(header);
    24073171
    2408     unsigned int task_id;
     3172    unsigned int thread_id;
    24093173    unsigned int vspace_id;
    24103174    unsigned int vseg_id = 0xFFFFFFFF;
    24113175
    2412     // searching the heap vseg
    2413     if ( (x < X_SIZE) && (y < Y_SIZE) )  // searching a task in cluster(x,y)
    2414     {
    2415         // get vspace global index
    2416         vspace_id = _get_context_slot(CTX_VSID_ID);
    2417 
    2418         // scan all tasks in vspace
    2419         unsigned int min = vspace[vspace_id].task_offset ;
    2420         unsigned int max = min + vspace[vspace_id].tasks ;
    2421         for ( task_id = min ; task_id < max ; task_id++ )
     3176    // get calling thread vspace index
     3177    vspace_id = _get_context_slot(CTX_VSID_ID);
     3178
     3179    // scan all threads in vspace to find one in clyster[x,y]
     3180    unsigned int min = vspace[vspace_id].thread_offset ;
     3181    unsigned int max = min + vspace[vspace_id].threads ;
     3182    for ( thread_id = min ; thread_id < max ; thread_id++ )
     3183    {
     3184        if ( thread[thread_id].clusterid == (x * Y_SIZE + y) )
    24223185        {
    2423             if ( task[task_id].clusterid == (x * Y_SIZE + y) )
    2424             {
    2425                 vseg_id = task[task_id].heap_vseg_id;
    2426                 if ( vseg_id != 0xFFFFFFFF ) break;
    2427             }
     3186            vseg_id = thread[thread_id].heap_vseg_id;
     3187            break;
    24283188        }
    2429     }
    2430     else                                // searching in the calling task
    2431     {
    2432         task_id = _get_context_slot(CTX_GTID_ID);
    2433         vseg_id = task[task_id].heap_vseg_id;
    24343189    }
    24353190
     
    24393194        *vaddr  = vseg[vseg_id].vbase;
    24403195        *length = vseg[vseg_id].length;
    2441         return 0;
    24423196    }
    24433197    else
     
    24453199        *vaddr  = 0;
    24463200        *length = 0;
    2447         return -1;
    2448     }
     3201        _printf("error in _sys_heap_info() : no heap in cluster (%d,%d)\n", x , y );
     3202    }
     3203    return GIET_SYSCALL_OK;
    24493204}  // end _sys_heap_info()
    2450 
    2451 
    2452 ///////////////////////
    2453 int _sys_tasks_status()
    2454 {
    2455     mapping_header_t *  header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    2456     mapping_task_t *    task    = _get_task_base(header);
    2457     mapping_vspace_t *  vspace  = _get_vspace_base(header);
    2458     mapping_cluster_t * cluster = _get_cluster_base(header);
    2459 
    2460     unsigned int task_id;
    2461     unsigned int vspace_id;
    2462 
    2463     // scan all vspaces
    2464     for( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ )
    2465     {
    2466         _printf("\n*** vspace %s\n", vspace[vspace_id].name );
    2467 
    2468         // scan all tasks in vspace
    2469         unsigned int min = vspace[vspace_id].task_offset ;
    2470         unsigned int max = min + vspace[vspace_id].tasks ;
    2471         for ( task_id = min ; task_id < max ; task_id++ )
    2472         {
    2473             unsigned int         clusterid = task[task_id].clusterid;
    2474             unsigned int         p         = task[task_id].proclocid;
    2475             unsigned int         x         = cluster[clusterid].x;
    2476             unsigned int         y         = cluster[clusterid].y;
    2477             unsigned int         ltid      = task[task_id].ltid;
    2478             static_scheduler_t*  psched    = (static_scheduler_t*)_schedulers[x][y][p];
    2479             unsigned int         norun     = psched->context[ltid][CTX_NORUN_ID];
    2480             unsigned int         current   = psched->current;
    2481 
    2482             if ( current == ltid )
    2483             _printf(" - task %s on P[%d,%d,%d] : running\n", task[task_id].name, x, y, p );
    2484             else if ( norun == 0 )
    2485             _printf(" - task %s on P[%d,%d,%d] : runable\n", task[task_id].name, x, y, p );
    2486             else
    2487             _printf(" - task %s on P[%d,%d,%d] : blocked\n", task[task_id].name, x, y, p );
    2488         }
    2489     }
    2490     return 0;
    2491 }  // end _sys_tasks_status()
    2492 
    2493 int _sys_fat_read( unsigned int fd_id,
    2494                    unsigned int buffer,
    2495                    unsigned int count )
    2496 {
    2497     return _fat_read(fd_id, buffer, count, 0);
    2498 }
    2499 
    25003205
    25013206
  • soft/giet_vm/giet_kernel/sys_handler.h

    r707 r709  
    1616#include "kernel_locks.h"
    1717#include "stdio.h"
     18
     19///////////////////////////////////////////////////////////////////////////////
     20// Define the possible command values for the giet_pthread_control() syscall
     21///////////////////////////////////////////////////////////////////////////////
     22
     23#define THREAD_CMD_PAUSE        0
     24#define THREAD_CMD_RESUME       1
     25#define THREAD_CMD_CONTEXT      2
     26
     27///////////////////////////////////////////////////////////////////////////////
     28// Define the error codes for the thread related syscalls
     29///////////////////////////////////////////////////////////////////////////////
     30
     31#define GIET_SYSCALL_OK                               ( 0 )
     32#define GIET_SYSCALL_VSPACE_NOT_FOUND                 (-1 )
     33#define GIET_SYSCALL_THREAD_NOT_FOUND                 (-2 )
     34#define GIET_SYSCALL_NOT_IN_SAME_VSPACE               (-3 )
     35#define GIET_SYSCALL_UNCOHERENT_THREAD_CONTEXT        (-4 )
     36#define GIET_SYSCALL_ILLEGAL_THREAD_COMMAND_TYPE      (-5 )
     37#define GIET_SYSCALL_CANNOT_LOAD_DATA_SEGMENT         (-6 )
     38#define GIET_SYSCALL_THREAD_ALREADY_ACTIVE            (-7 )
     39#define GIET_SYSCALL_MAIN_NOT_FOUND                   (-8 )
     40#define GIET_SYSCALL_APPLI_CANNOT_BE_KILLED           (-9 )
     41#define GIET_SYSCALL_PTHREAD_ARGUMENT_NOT_SUPPORTED   (-10)
     42#define GIET_SYSCALL_ILLEGAL_CLUSTER_COORDINATES      (-11)
     43#define GIET_SYSCALL_VSEG_NOT_FOUND                   (-12)
     44#define GIET_SYSCALL_UNDEFINED_SYSTEM_CALL            (-13)
     45#define GIET_SYSCALL_COPROCESSOR_NOT_FOUND            (-14)
     46#define GIET_SYSCALL_COPROCESSOR_ILLEGAL_MODE         (-15)
    1847
    1948///////////////////////////////////////////////////////////////////////////////
     
    86115
    87116
    88 
    89 
    90 ///////////////////////////////////////////////////////////////////////////////
    91 //    Coprocessors related syscall handlers
    92 ///////////////////////////////////////////////////////////////////////////////
    93 
    94 int _sys_coproc_register_set( unsigned int cluster_xy,
    95                               unsigned int reg_index,
    96                               unsigned int value );
    97 
    98 int _sys_coproc_register_get( unsigned int  cluster_xy,
    99                               unsigned int  reg_index,
    100                               unsigned int* buffer );
    101 
    102 int _sys_coproc_alloc( unsigned int   coproc_type,
    103                        unsigned int*  coproc_info );
    104 
    105 int _sys_coproc_release( unsigned int coproc_reg_index );
    106 
    107 int _sys_coproc_channel_init( unsigned int            channel,
    108                               giet_coproc_channel_t*  desc );
    109 
    110 int _sys_coproc_run( unsigned int coproc_reg_index );
    111 
    112 int _sys_coproc_completed();
     117//////////////////////////////////////////////////////////////////////////////
     118//           Applications related syscall handlers
     119//////////////////////////////////////////////////////////////////////////////
     120
     121extern int _sys_kill_application( char* name );
     122
     123extern int _sys_exec_application( char* name );
     124
     125extern int _sys_applications_status();
     126
     127/////////////////////////////////////////////////////////////////////////////
     128//          Threads related syscall handlers
     129/////////////////////////////////////////////////////////////////////////////
     130
     131extern int _sys_pthread_create( unsigned int*  buffer,
     132                                void*          attr,
     133                                void*          function,
     134                                void*          arg );
     135
     136extern int _sys_pthread_join( unsigned int  trdid,
     137                              void*         ptr );
     138
     139extern int _sys_pthread_kill( unsigned int  trdid,
     140                              int           signal );
     141
     142extern int _sys_pthread_exit( void* string);
     143
     144extern int _sys_pthread_yield();
     145
     146extern int _sys_pthread_control( unsigned int  command,
     147                                 char*         vspace_name,
     148                                 char*         thread_name );
     149
     150///////////////////////////////////////////////////////////////////////////////
     151//          Coprocessors related syscall handlers
     152///////////////////////////////////////////////////////////////////////////////
     153
     154extern int _sys_coproc_alloc( unsigned int   coproc_type,
     155                              unsigned int*  coproc_info );
     156
     157extern int _sys_coproc_release( unsigned int coproc_reg_index );
     158
     159extern int _sys_coproc_channel_init( unsigned int            channel,
     160                                     giet_coproc_channel_t*  desc );
     161
     162extern int _sys_coproc_run( unsigned int coproc_reg_index );
     163
     164extern int _sys_coproc_completed();
    113165
    114166///////////////////////////////////////////////////////////////////////////////
     
    116168///////////////////////////////////////////////////////////////////////////////
    117169
    118 int _sys_tty_alloc( unsigned int shared );
    119 
    120 int _sys_tty_release();
    121 
    122 int _sys_tty_write( const char*  buffer,
     170extern int _sys_tty_alloc( unsigned int shared );
     171
     172extern int _sys_tty_release();
     173
     174extern int _sys_tty_write( const char*  buffer,
    123175                    unsigned int length,
    124176                    unsigned int channel );
    125177
    126 int _sys_tty_read(  char*        buffer,
     178extern int _sys_tty_read(  char*        buffer,
    127179                    unsigned int length,
    128180                    unsigned int channel );
     
    132184//////////////////////////////////////////////////////////////////////////////
    133185
    134 int _sys_tim_alloc();
    135 
    136 int _sys_tim_release();
    137 
    138 int _sys_tim_start( unsigned int period );
    139 
    140 int _sys_tim_stop();
     186extern int _sys_tim_alloc();
     187
     188extern int _sys_tim_release();
     189
     190extern int _sys_tim_start( unsigned int period );
     191
     192extern int _sys_tim_stop();
    141193
    142194//////////////////////////////////////////////////////////////////////////////
     
    144196//////////////////////////////////////////////////////////////////////////////
    145197
    146 int _sys_nic_alloc( unsigned int is_rx,
    147                     unsigned int xmax,
    148                     unsigned int ymax );
    149 
    150 int _sys_nic_release( unsigned int is_rx );
    151 
    152 int _sys_nic_start( unsigned int is_rx,
    153                     unsigned int channel );
    154 
    155 int _sys_nic_move( unsigned int is_rx,
    156                    unsigned int channel,
    157                    void*        buffer );
    158 
    159 int _sys_nic_stop( unsigned int is_rx,
    160                    unsigned int channel );
    161 
    162 int _sys_nic_clear( unsigned int is_rx,
    163                     unsigned int channel );
    164 
    165 int _sys_nic_stats( unsigned int is_rx,
    166                     unsigned int channel );
     198extern int _sys_nic_alloc( unsigned int is_rx,
     199                           unsigned int xmax,
     200                           unsigned int ymax );
     201
     202extern int _sys_nic_release( unsigned int is_rx );
     203
     204extern int _sys_nic_start( unsigned int is_rx );
     205
     206extern int _sys_nic_move( unsigned int is_rx,
     207                          void*        buffer );
     208
     209extern int _sys_nic_stop( unsigned int is_rx );
     210
     211extern int _sys_nic_clear( unsigned int is_rx );
     212
     213extern int _sys_nic_stats( unsigned int is_rx );
    167214
    168215//////////////////////////////////////////////////////////////////////////////
     
    170217//////////////////////////////////////////////////////////////////////////////
    171218
    172 int _sys_fbf_sync_write( unsigned int offset,
     219extern int _sys_fbf_sync_write( unsigned int offset,
    173220                         void*        buffer,
    174221                         unsigned int length );
    175222
    176 int _sys_fbf_sync_read(  unsigned int offset,
     223extern int _sys_fbf_sync_read(  unsigned int offset,
    177224                         void*        buffer,
    178225                         unsigned int length );
    179226
    180 int _sys_fbf_cma_alloc();
    181 
    182 int _sys_fbf_cma_release();
    183 
    184 int _sys_fbf_cma_init_buf(void*        buf0_vbase,
     227extern int _sys_fbf_cma_alloc();
     228
     229extern int _sys_fbf_cma_release();
     230
     231extern int _sys_fbf_cma_init_buf(void*        buf0_vbase,
    185232                          void*        buf1_vbase,
    186233                          void*        sts0_vaddr,
    187234                          void*        sts1_vaddr );
    188235
    189 int _sys_fbf_cma_start( unsigned int length );
    190 
    191 int _sys_fbf_cma_display( unsigned int buffer_index );
    192 
    193 int _sys_fbf_cma_stop();
     236extern int _sys_fbf_cma_start( unsigned int length );
     237
     238extern int _sys_fbf_cma_display( unsigned int buffer_index );
     239
     240extern int _sys_fbf_cma_stop();
    194241
    195242//////////////////////////////////////////////////////////////////////////////
     
    197244//////////////////////////////////////////////////////////////////////////////
    198245
    199 int _sys_ukn();
    200 
    201 int _sys_proc_xyp( unsigned int* x,
     246extern int _sys_ukn();
     247
     248extern int _sys_proc_xyp( unsigned int* x,
    202249                   unsigned int* y,
    203250                   unsigned int* p );
    204251
    205 int _sys_task_exit( char* string );
    206 
    207 int _sys_kill_application( char* name );
    208 
    209 int _sys_exec_application( char* name );
    210 
    211 int _sys_context_switch();
    212 
    213 int _sys_local_task_id();
    214 
    215 int _sys_global_task_id();
    216 
    217 int _sys_thread_id();
    218 
    219 int _sys_procs_number( unsigned int* x_size,
     252extern int _sys_procs_number( unsigned int* x_size,
    220253                       unsigned int* y_size,
    221254                       unsigned int* nprocs );
    222255
    223 int _sys_vseg_get_vbase( char*         vspace_name,
     256extern int _sys_vseg_get_vbase( char*         vspace_name,
    224257                         char*         vseg_name,
    225258                         unsigned int* vbase );
    226259
    227 int _sys_vseg_get_length( char*         vspace_name,
     260extern int _sys_vseg_get_length( char*         vspace_name,
    228261                          char*         vseg_name,
    229262                          unsigned int* length );
    230263
    231 int _sys_xy_from_ptr( void*          ptr,
     264extern int _sys_xy_from_ptr( void*          ptr,
    232265                      unsigned int*  x,
    233266                      unsigned int*  y );
    234267
    235 int _sys_heap_info( unsigned int* vaddr,
     268extern int _sys_heap_info( unsigned int* vaddr,
    236269                    unsigned int* length,
    237270                    unsigned int  x,
    238271                    unsigned int  y );
    239 
    240 int _sys_tasks_status();
    241 
    242 int _sys_fat_read( unsigned int fd_id,
    243                    unsigned int buffer,
    244                    unsigned int count );
    245272
    246273#endif
  • soft/giet_vm/giet_libs/malloc.c

    r686 r709  
    9898
    9999    // checking heap segment constraints
    100     if ( heap_size == 0 )                                    // heap segment exist
    101     {
    102         giet_exit("ERROR in malloc() : heap not found \n");
    103     }
    104     if ( heap_size != (1<<heap_index) )                      // heap size power of 2
    105     {
    106         giet_exit("ERROR in malloc() : heap size must be power of 2\n");
    107     }
    108     if ( heap_base % heap_size )                             // heap segment aligned
    109     {
    110         giet_exit("ERROR in malloc() : heap segment must be aligned\n");
    111     }
     100    giet_pthread_assert( (heap_size != 0) ,
     101                         "error in heap_init() : heap not found");
     102    giet_pthread_assert( (heap_size == (1<<heap_index)) ,
     103                         "error in heap_init() : heap size must be power of 2");
     104    giet_pthread_assert( (heap_base%heap_size == 0) ,
     105                         "error in heap_init() : heap segment must be aligned\n");
    112106
    113107    // compute size of block containin alloc[] array
     
    231225
    232226    // checking arguments
    233     if (size == 0)
    234     {
    235         giet_exit("\nERROR in remote_malloc() : requested size = 0 \n");
    236     }
    237     if ( x >= X_SIZE )
    238     {
    239         giet_exit("\nERROR in remote_malloc() : x coordinate too large\n");
    240     }
    241     if ( y >= Y_SIZE )
    242     {
    243         giet_exit("\nERROR in remote_malloc() : y coordinate too large\n");
    244     }
    245 
    246     // checking initialization
    247     if ( heap[x][y].init != HEAP_INITIALIZED )
    248     {
    249         giet_exit("\nERROR in remote_malloc() : heap not initialized\n");
    250     }
     227    giet_pthread_assert( (size != 0) ,
     228                         "error in remote_malloc() : requested size = 0 \n");
     229    giet_pthread_assert( (x < X_SIZE) ,
     230                         "error in remote_malloc() : x coordinate too large\n");
     231    giet_pthread_assert( (y < Y_SIZE) ,
     232                         "error in remote_malloc() : y coordinate too large\n");
     233    giet_pthread_assert( (heap[x][y].init == HEAP_INITIALIZED) ,
     234                         "error in remote_malloc() : heap not initialized\n");
    251235
    252236    // normalize size
     
    265249
    266250    // check block found
    267     if ( base == 0 )
     251    if (base == 0)
    268252    {
    269253        lock_release( &heap[x][y].lock );
    270         giet_exit("\nERROR in remote_malloc() : no more space\n");
     254        giet_pthread_assert( 0 , "error in remote_malloc() : no more space\n" );
    271255    }
    272256
     
    279263    {
    280264        lock_release( &heap[x][y].lock );
    281         giet_exit("\nERROR in remote_malloc() : block already allocated ???\n");
     265        giet_pthread_assert( 0 , "error in remote_malloc() : block already allocated");
    282266    }
    283267
     
    390374    // check ptr value
    391375    unsigned int base = (unsigned int)ptr;
    392     if ( (base < heap[x][y].heap_base) ||
    393          (base >= (heap[x][y].heap_base + heap[x][y].heap_size)) )
    394     {
    395         giet_exit("ERROR in free() : illegal pointer for released block");
    396     }
     376    giet_pthread_assert( (base >= heap[x][y].heap_base) &&
     377                         (base < (heap[x][y].heap_base + heap[x][y].heap_size)) ,
     378                         "error in free() : illegal pointer for released block" );
    397379 
    398380    // get the lock protecting heap[x][y]
     
    410392    {
    411393        lock_release( &heap[x][y].lock );
    412         giet_exit("\nERROR in free() : released block not allocated ???\n");
     394        giet_pthread_assert( 0 , "error in free() : released block not allocated");
    413395    }
    414396
     
    416398    if ( base % (1 << size_index) )
    417399    {
    418         giet_exit("\nERROR in free() : released block not aligned\n");
     400        lock_release( &heap[x][y].lock );
     401        giet_pthread_assert( 0 , "error in free() : released block not aligned");
    419402    }
    420403
  • soft/giet_vm/giet_libs/malloc.h

    r686 r709  
    6868#define HEAP_INITIALIZED    0xDEADBEEF
    6969
    70 #define MIN_BLOCK_SIZE      0x80
     70#define MIN_BLOCK_SIZE      0x40
    7171
    7272////////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/giet_libs/stdio.c

    r689 r709  
    1111
    1212//////////////////////////////////////////////////////////////////////////////
    13 /////////////////////  MIPS32     related system calls ///////////////////////
     13//                     MIPS32 related system calls
    1414//////////////////////////////////////////////////////////////////////////////
    1515
     
    4949
    5050//////////////////////////////////////////////////////////////////////////////
    51 ///////////////////// Task related  system calls /////////////////////////////
     51//                    Threads related  system calls
    5252//////////////////////////////////////////////////////////////////////////////
    5353
    54 ////////////////////////////////
    55 unsigned int giet_proc_task_id()
    56 {
    57     return (unsigned int)sys_call( SYSCALL_LOCAL_TASK_ID,
    58                                    0, 0, 0, 0 );
    59 }
    60 
    61 //////////////////////////////////
    62 unsigned int giet_global_task_id()
    63 {
    64     return (unsigned int)sys_call( SYSCALL_GLOBAL_TASK_ID,
    65                                    0, 0, 0, 0 );
    66 }
    67 
    68 /////////////////////////////
    69 unsigned int giet_thread_id()
    70 {
    71     return (unsigned int)sys_call( SYSCALL_THREAD_ID,
    72                                    0, 0, 0, 0 );
    73 }
    74 
    75 //////////////////////////////
    76 void giet_exit( char* string )
    77 {
    78     sys_call( SYSCALL_EXIT,
     54#define THREAD_CMD_PAUSE     0
     55#define THREAD_CMD_RESUME    1
     56#define THREAD_CMD_CONTEXT   2
     57
     58//////////////////////////////////////////////////////////
     59int giet_pthread_create( pthread_t*       buffer,
     60                         pthread_attr_t*  attr,
     61                         void*            function,
     62                         void*            arg )
     63{
     64    return sys_call( SYSCALL_PTHREAD_CREATE,
     65                     (unsigned int)buffer,
     66                     (unsigned int)attr,
     67                     (unsigned int)function,
     68                     (unsigned int)arg );
     69}             
     70
     71//////////////////////////////////////
     72void giet_pthread_exit( void* string )
     73{
     74    sys_call( SYSCALL_PTHREAD_EXIT,
    7975              (unsigned int)string,
    8076              0, 0, 0 );
    8177}
    8278
    83 /////////////////////////////////////////
    84 void giet_assert( unsigned int condition,
    85                   char*        string )
    86 {
    87     if ( condition == 0 ) giet_exit( string );
    88 }
    89 
    90 //////////////////////////
    91 void giet_context_switch()
    92 {
    93     sys_call( SYSCALL_CTX_SWITCH,
     79////////////////////////////////////////
     80int giet_pthread_join( pthread_t  trdid,
     81                       void**     ptr )
     82{
     83    return sys_call( SYSCALL_PTHREAD_JOIN,
     84                     trdid,
     85                     (unsigned int)ptr,
     86                     0, 0 );
     87}
     88
     89///////////////////////////////////////
     90int giet_pthread_kill( pthread_t trdid,
     91                       int       signal )
     92{
     93    return sys_call( SYSCALL_PTHREAD_KILL,
     94                     trdid,
     95                     signal,
     96                     0, 0 );
     97}
     98
     99/////////////////////////
     100void giet_pthread_yield()
     101{
     102    sys_call( SYSCALL_PTHREAD_YIELD,
    94103              0, 0, 0, 0 );
    95104}
    96105
    97 ////////////////////////
    98 void giet_tasks_status()
    99 {
    100     sys_call( SYSCALL_TASKS_STATUS,
    101               0, 0, 0, 0 );
    102 }
     106/////////////////////////////////////////////////
     107void giet_pthread_assert( unsigned int condition,
     108                          char*        string )
     109{
     110    if ( condition == 0 ) giet_pthread_exit( string );
     111}
     112
     113//////////////////////////////////////////////
     114int giet_pthread_pause( char*     vspace_name,
     115                        char*     thread_name )
     116{
     117    return sys_call( SYSCALL_PTHREAD_CONTROL,
     118                     THREAD_CMD_PAUSE,
     119                     (unsigned int) vspace_name,
     120                     (unsigned int) thread_name,
     121                     0 );
     122}
     123
     124///////////////////////////////////////////////
     125int giet_pthread_resume( char*     vspace_name,
     126                         char*     thread_name )
     127{
     128    return sys_call( SYSCALL_PTHREAD_CONTROL,
     129                     THREAD_CMD_RESUME,
     130                     (unsigned int) vspace_name,
     131                     (unsigned int) thread_name,
     132                     0 );
     133}
     134
     135///////////////////////////////////////////////
     136int giet_pthread_context( char*     vspace_name,
     137                          char*     thread_name )
     138{
     139    return sys_call( SYSCALL_PTHREAD_CONTROL,
     140                     THREAD_CMD_CONTEXT,
     141                     (unsigned int) vspace_name,
     142                     (unsigned int) thread_name,
     143                     0 );
     144}
     145
    103146
    104147//////////////////////////////////////////////////////////////////////////////
    105 ///////////////////// Applications  system calls /////////////////////////////
     148//                    Applications related system calls
    106149//////////////////////////////////////////////////////////////////////////////
    107150
     
    122165}
    123166
     167///////////////////////////////
     168void giet_applications_status()
     169{
     170    sys_call( SYSCALL_APPS_STATUS,
     171              0, 0, 0, 0 );
     172}
     173
    124174//////////////////////////////////////////////////////////////////////////////
    125 ///////////////////// Coprocessors  system calls  ////////////////////////////
     175//                    Coprocessors related system calls
    126176//////////////////////////////////////////////////////////////////////////////
    127177
     
    134184                   (unsigned int)coproc_info,
    135185                   0, 0 ) ) 
    136         giet_exit("error in giet_coproc_alloc()");
     186        giet_pthread_exit("error in giet_coproc_alloc()");
    137187}
    138188
     
    143193                   coproc_reg_index,
    144194                   0, 0, 0 ) ) 
    145         giet_exit("error in giet_coproc_release()");
     195        giet_pthread_exit("error in giet_coproc_release()");
    146196}
    147197
     
    154204                   (unsigned int)desc,
    155205                   0, 0 ) )
    156         giet_exit("error in giet_coproc_channel_init()");
     206        giet_pthread_exit("error in giet_coproc_channel_init()");
    157207}
    158208
     
    163213                   coproc_reg_index,
    164214                   0, 0, 0 ) )
    165         giet_exit("error in giet_coproc_run()");
     215        giet_pthread_exit("error in giet_coproc_run()");
    166216}
    167217
     
    171221    if ( sys_call( SYSCALL_COPROC_COMPLETED,
    172222                   0, 0, 0, 0 ) )
    173         giet_exit("error in giet_coproc_completed");
     223        giet_pthread_exit("error in giet_coproc_completed");
    174224}
    175225
    176226
    177227//////////////////////////////////////////////////////////////////////////////
    178 /////////////////////  TTY device related system calls ///////////////////////
     228//                    TTY device related system calls
    179229//////////////////////////////////////////////////////////////////////////////
    180230
     
    184234    if ( sys_call( SYSCALL_TTY_ALLOC,
    185235                   shared,
    186                    0, 0, 0 ) )  giet_exit("error in giet_tty_alloc()");
     236                   0, 0, 0 ) )  giet_pthread_exit("error in giet_tty_alloc()");
    187237}
    188238
     
    516566    if (ret)
    517567    {
    518         giet_exit("ERROR in giet_tty_printf()");
     568        giet_pthread_exit("error in giet_tty_printf()");
    519569    }
    520570} // end giet_tty_printf()
     
    532582                      0xFFFFFFFF,          // channel index from task context
    533583                      0);
    534         if ( ret < 0 ) giet_exit("error in giet_tty_getc()");
     584        if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getc()");
    535585    }
    536586    while (ret != 1);
     
    556606                           0xFFFFFFFF,        // channel index from task context
    557607                           0);
    558             if ( ret < 0 ) giet_exit("error in giet_tty_gets()");
     608            if ( ret < 0 ) giet_pthread_exit("error in giet_tty_gets()");
    559609        }
    560610        while (ret != 1);
     
    578628                                0XFFFFFFFF,        // channel index from task context
    579629                                0 );
    580                 if ( ret < 0 ) giet_exit("error in giet_tty_gets()");
     630                if ( ret < 0 ) giet_pthread_exit("error in giet_tty_gets()");
    581631            }
    582632        }
     
    595645                            0XFFFFFFFF,        // channel index from task context
    596646                            0 );
    597             if ( ret < 0 ) giet_exit("error in giet_tty_gets()");
     647            if ( ret < 0 ) giet_pthread_exit("error in giet_tty_gets()");
    598648     
    599649        }
     
    628678                            0xFFFFFFFF,    // channel index from task context
    629679                            0);
    630             if ( ret < 0 ) giet_exit("error in giet_tty_getw()");
     680            if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getw()");
    631681        }
    632682        while (ret != 1);
     
    644694                            0xFFFFFFFF,    // channel index from task context
    645695                            0 );
    646             if ( ret < 0 ) giet_exit("error in giet_tty_getw()");
     696            if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getw()");
    647697        }
    648698        else if (string_byte == 0x0A)                     // LF character
     
    662712                                0xFFFFFFFF,    // channel index from task context
    663713                                0 );
    664                 if ( ret < 0 ) giet_exit("error in giet_tty_getw()");
     714                if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getw()");
    665715            }
    666716        }
     
    701751                            0xFFFFFFFF,    // channel index from task context
    702752                            0 );
    703             if ( ret < 0 ) giet_exit("error in giet_tty_getw()");
     753            if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getw()");
    704754        }
    705755        // echo character '0'
     
    710760                        0xFFFFFFFF,    // channel index from task context
    711761                        0 );
    712         if ( ret < 0 ) giet_exit("error in giet_tty_getw()");
     762        if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getw()");
    713763
    714764        // return 0 value
     
    719769
    720770//////////////////////////////////////////////////////////////////////////////////
    721 /////////////////////  TIMER related system calls ////////////////////////////////
     771//                     TIMER related system calls
    722772//////////////////////////////////////////////////////////////////////////////////
    723773
     
    726776{
    727777    if ( sys_call( SYSCALL_TIM_ALLOC,
    728                    0, 0, 0, 0 ) ) giet_exit("error in giet_timer_alloc()");
     778                   0, 0, 0, 0 ) ) giet_pthread_exit("error in giet_timer_alloc()");
    729779}
    730780
     
    734784    if ( sys_call( SYSCALL_TIM_START,
    735785                   period,
    736                    0, 0, 0 ) ) giet_exit("error in giet_timer_start()");
     786                   0, 0, 0 ) ) giet_pthread_exit("error in giet_timer_start()");
    737787}
    738788
     
    741791{
    742792    if ( sys_call( SYSCALL_TIM_STOP,
    743                    0, 0, 0, 0 ) ) giet_exit("error in giet_timer_stop()");
     793                   0, 0, 0, 0 ) ) giet_pthread_exit("error in giet_timer_stop()");
    744794}
    745795
    746796
    747797//////////////////////////////////////////////////////////////////////////////////
    748 ///////////////  Frame buffer device related system calls  ///////////////////////
     798//                   Frame buffer related system calls 
    749799//////////////////////////////////////////////////////////////////////////////////
    750800
     
    753803{
    754804    if ( sys_call( SYSCALL_FBF_CMA_ALLOC,
    755                    0, 0, 0, 0 ) )    giet_exit("error in giet_fbf_cma_alloc()");
     805                   0, 0, 0, 0 ) )    giet_pthread_exit("error in giet_fbf_cma_alloc()");
    756806}
    757807
     
    766816                   (unsigned int)buf1_vbase,
    767817                   (unsigned int)sts0_vaddr,
    768                    (unsigned int)sts1_vaddr ) )   giet_exit("error in giet_fbf_cma_init_buf()");
     818                   (unsigned int)sts1_vaddr ) )   giet_pthread_exit("error in giet_fbf_cma_init_buf()");
    769819}
    770820
     
    774824    if ( sys_call( SYSCALL_FBF_CMA_START,
    775825                   length,
    776                    0, 0, 0 ) )   giet_exit("error in giet_fbf_cma_start()");
     826                   0, 0, 0 ) )   giet_pthread_exit("error in giet_fbf_cma_start()");
    777827}
    778828
     
    782832    if ( sys_call( SYSCALL_FBF_CMA_DISPLAY,
    783833                   buffer,
    784                    0, 0, 0 ) )   giet_exit("error in giet_fbf_cma_display()");
     834                   0, 0, 0 ) )   giet_pthread_exit("error in giet_fbf_cma_display()");
    785835}
    786836
     
    789839{
    790840    if ( sys_call( SYSCALL_FBF_CMA_STOP,
    791                    0, 0, 0, 0 ) )    giet_exit("error in giet_fbf_cma_stop()");
     841                   0, 0, 0, 0 ) )    giet_pthread_exit("error in giet_fbf_cma_stop()");
    792842}
    793843
     
    801851                   (unsigned int)buffer,
    802852                   length,
    803                    0 ) )  giet_exit("error in giet_fbf_sync_write()");
     853                   0 ) )  giet_pthread_exit("error in giet_fbf_sync_write()");
    804854}
    805855
     
    813863                   (unsigned int)buffer,
    814864                   length,
    815                    0 ) )   giet_exit("error in giet_fbf_sync_read()");
     865                   0 ) )   giet_pthread_exit("error in giet_fbf_sync_read()");
    816866}
    817867
    818868
    819869//////////////////////////////////////////////////////////////////////////////////
    820 /////////////////////// NIC related system calls /////////////////////////////////
     870//                      NIC related system calls 
    821871//////////////////////////////////////////////////////////////////////////////////
    822872
    823 ////////////////////////////////////////////////////
    824 unsigned int giet_nic_rx_alloc( unsigned int xmax,
    825                                 unsigned int ymax )
    826 {
    827     int channel = sys_call( SYSCALL_NIC_ALLOC,
    828                             1,
    829                             xmax,
    830                             ymax,
    831                             0 );
    832     if ( channel < 0 ) giet_exit("error in giet_nic_rx_alloc()");
    833 
    834     return (unsigned int)channel;
    835 }
    836 
    837 ////////////////////////////////////////////////////
    838 unsigned int giet_nic_tx_alloc( unsigned int xmax,
    839                                 unsigned int ymax )
    840 {
    841     int channel = sys_call( SYSCALL_NIC_ALLOC,
    842                             0,
    843                             xmax,
    844                             ymax,
    845                             0 );
    846     if ( channel < 0 ) giet_exit("error in giet_nic_tx_alloc()");
    847 
    848     return (unsigned int)channel;
    849 }
    850 
    851 //////////////////////////////////////////////
    852 void giet_nic_rx_start( unsigned int channel )
     873//////////////////////////////////////////
     874void giet_nic_rx_alloc( unsigned int xmax,
     875                        unsigned int ymax )
     876{
     877    if ( sys_call( SYSCALL_NIC_ALLOC,
     878                   1,                    // RX
     879                   xmax,
     880                   ymax,
     881                   0 ) ) giet_pthread_exit("error in giet_nic_rx_alloc()");
     882}
     883
     884//////////////////////////////////////////
     885void giet_nic_tx_alloc( unsigned int xmax,
     886                        unsigned int ymax )
     887{
     888    if ( sys_call( SYSCALL_NIC_ALLOC,
     889                   0,                    // TX
     890                   xmax,
     891                   ymax,
     892                   0 ) ) giet_pthread_exit("error in giet_nic_tx_alloc()");
     893}
     894
     895////////////////////////
     896void giet_nic_rx_start()
    853897{
    854898    if ( sys_call( SYSCALL_NIC_START,
    855                    1,
    856                    channel,
    857                    0, 0 ) ) giet_exit("error in giet_nic_rx_start()");
    858 }
    859 
    860 //////////////////////////////////////////////
    861 void giet_nic_tx_start( unsigned int channel )
     899                   1,                    // RX
     900                   0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_rx_start()");
     901}
     902
     903////////////////////////
     904void giet_nic_tx_start()
    862905{
    863906    if ( sys_call( SYSCALL_NIC_START,
    864                    0,
    865                    channel,
    866                    0, 0 ) ) giet_exit("error in giet_nic_tx_start()");
    867 }
    868 
    869 ///////////////////////////////////////////////////////////
    870 void giet_nic_rx_move( unsigned int channel, void* buffer )
     907                   0,                    // TX
     908                   0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_tx_start()");
     909}
     910
     911/////////////////////////////////////
     912void giet_nic_rx_move( void* buffer )
    871913{
    872914    if ( sys_call( SYSCALL_NIC_MOVE,
    873                    1,
    874                    channel,
     915                   1,                    // RX
    875916                   (unsigned int)buffer,
    876                    0 ) )  giet_exit("error in giet_nic_rx_move()");
    877 }
    878 
    879 ///////////////////////////////////////////////////////////
    880 void giet_nic_tx_move( unsigned int channel, void* buffer )
     917                   0, 0 ) )  giet_pthread_exit("error in giet_nic_rx_move()");
     918}
     919
     920/////////////////////////////////////
     921void giet_nic_tx_move( void* buffer )
    881922{
    882923    if ( sys_call( SYSCALL_NIC_MOVE,
    883                    0,
    884                    channel,
     924                   0,                    // TX
    885925                   (unsigned int)buffer,
    886                    0 ) )  giet_exit("error in giet_nic_tx_move()");
    887 }
    888 
    889 /////////////////////////////////////////////
    890 void giet_nic_rx_stop( unsigned int channel )
     926                   0, 0 ) )  giet_pthread_exit("error in giet_nic_tx_move()");
     927}
     928
     929///////////////////////
     930void giet_nic_rx_stop()
    891931{
    892932    if ( sys_call( SYSCALL_NIC_STOP,
    893                    1,
    894                    channel,
    895                    0, 0 ) ) giet_exit("error in giet_nic_rx_stop()");
    896 }
    897 
    898 /////////////////////////////////////////////
    899 void giet_nic_tx_stop( unsigned int channel )
     933                   1,                    // RX
     934                   0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_rx_stop()");
     935}
     936
     937///////////////////////
     938void giet_nic_tx_stop()
    900939{
    901940    if ( sys_call( SYSCALL_NIC_STOP,
    902                    0,
    903                    channel,
    904                    0, 0 ) ) giet_exit("error in giet_nic_tx_stop()");
    905 }
    906 
    907 //////////////////////////////////////////////
    908 void giet_nic_rx_stats( unsigned int channel )
     941                   0,                   // TX
     942                   0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_tx_stop()");
     943}
     944
     945////////////////////////
     946void giet_nic_rx_stats()
    909947{
    910948    if ( sys_call( SYSCALL_NIC_STATS,
    911                    1,
    912                    channel,
    913                    0, 0 ) ) giet_exit("error in giet_nic_rx_stats()");
    914 }
    915 
    916 //////////////////////////////////////////////
    917 void giet_nic_tx_stats( unsigned int channel )
     949                   1,                   // RX
     950                   0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_rx_stats()");
     951}
     952
     953////////////////////////
     954void giet_nic_tx_stats()
    918955{
    919956    if ( sys_call( SYSCALL_NIC_STATS,
    920                    0,
    921                    channel,
    922                    0, 0 ) ) giet_exit("error in giet_nic_tx_stats()");
    923 }
    924 
    925 //////////////////////////////////////////////
    926 void giet_nic_rx_clear( unsigned int channel )
     957                   0,                   // TX
     958                   0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_tx_stats()");
     959}
     960
     961////////////////////////
     962void giet_nic_rx_clear()
    927963{
    928964    if ( sys_call( SYSCALL_NIC_CLEAR,
    929                    1,
    930                    channel,
    931                    0, 0 ) ) giet_exit("error in giet_nic_rx_clear()");
    932 }
    933 
    934 //////////////////////////////////////////////
    935 void giet_nic_tx_clear( unsigned int channel )
     965                   1,                   // RX
     966                   0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_rx_clear()");
     967}
     968
     969////////////////////////
     970void giet_nic_tx_clear()
    936971{
    937972    if ( sys_call( SYSCALL_NIC_CLEAR,
    938                    0,
    939                    channel,
    940                    0, 0 ) ) giet_exit("error in giet_nic_tx_clear()");
     973                   0,                   // TX
     974                   0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_tx_clear()");
    941975}
    942976
     
    944978
    945979///////////////////////////////////////////////////////////////////////////////////
    946 ///////////////////// FAT related system calls ////////////////////////////////////
     980//                   FAT related system calls
    947981///////////////////////////////////////////////////////////////////////////////////
    948982
     
    9841018                     (unsigned int)buffer,
    9851019                     count,
    986                      0 );
     1020                     0 );      // no physical addressing required
    9871021}
    9881022
     
    9961030                     (unsigned int)buffer,
    9971031                     count,
    998                      0 );
     1032                     0 );      // no physical addressing required
    9991033}
    10001034
     
    10681102
    10691103//////////////////////////////////////////////////////////////////////////////////
    1070 ///////////////////// Miscellaneous system calls /////////////////////////////////
     1104//                      Miscellaneous system calls
    10711105//////////////////////////////////////////////////////////////////////////////////
    10721106
     
    10801114                   (unsigned int)y_size,
    10811115                   (unsigned int)nprocs,
    1082                    0 ) )  giet_exit("ERROR in giet_procs_number()");
     1116                   0 ) )  giet_pthread_exit("error in giet_procs_number()");
    10831117}
    10841118
     
    10921126                   (unsigned int) vobj_name,
    10931127                   (unsigned int) vbase,
    1094                    0 ) )  giet_exit("ERROR in giet_vobj_get_vbase()");
     1128                   0 ) )  giet_pthread_exit("error in giet_vobj_get_vbase()");
    10951129}
    10961130
     
    11041138                   (unsigned int) vobj_name,
    11051139                   (unsigned int) length,
    1106                    0 ) )  giet_exit("ERROR in giet_vobj_get_length()");
     1140                   0 ) )  giet_pthread_exit("error in giet_vobj_get_length()");
    11071141}
    11081142
     
    11131147                     unsigned int  y )
    11141148{
    1115     if ( sys_call( SYSCALL_HEAP_INFO,
    1116                    (unsigned int)vaddr,
    1117                    (unsigned int)length,
    1118                    x,
    1119                    y ) )  giet_exit("ERROR in giet_heap_info()");
     1149    sys_call( SYSCALL_HEAP_INFO,
     1150              (unsigned int)vaddr,
     1151              (unsigned int)length,
     1152              x,
     1153              y );
    11201154}
    11211155
     
    11291163                   (unsigned int)px,
    11301164                   (unsigned int)py,
    1131                    0 ) )  giet_exit("ERROR in giet_get_xy()");
     1165                   0 ) )  giet_pthread_exit("error in giet_get_xy()");
    11321166}
    11331167
  • soft/giet_vm/giet_libs/stdio.h

    r689 r709  
    1414
    1515#include "giet_fat32/fat32_shared.h"
     16#include "giet_common/mips32_registers.h"
    1617
    1718// These define must be synchronised with
     
    2021#define SYSCALL_PROC_XYP             0x00
    2122#define SYSCALL_PROC_TIME            0x01
    22 #define SYSCALL_TTY_WRITE            0x02
    23 #define SYSCALL_TTY_READ             0x03
    24 #define SYSCALL_TTY_ALLOC            0x04
    25 #define SYSCALL_TASKS_STATUS         0x05
     23#define SYSCALL_PROCS_NUMBER         0x02
     24#define SYSCALL_GET_XY               0x03
     25//                                   0x04
     26//                                   0x05
    2627//                                   0x06
    2728#define SYSCALL_HEAP_INFO            0x07
    28 #define SYSCALL_LOCAL_TASK_ID        0x08
    29 #define SYSCALL_GLOBAL_TASK_ID       0x09
     29#define SYSCALL_VOBJ_GET_VBASE       0x08
     30#define SYSCALL_VOBJ_GET_LENGTH      0x09
    3031#define SYSCALL_FBF_CMA_ALLOC        0x0A
    3132#define SYSCALL_FBF_CMA_INIT_BUF     0x0B
     
    3334#define SYSCALL_FBF_CMA_DISPLAY      0x0D
    3435#define SYSCALL_FBF_CMA_STOP         0x0E
    35 #define SYSCALL_EXIT                 0x0F
    36 
    37 #define SYSCALL_PROCS_NUMBER         0x10
     36//                                   0x0F
     37
     38#define SYSCALL_APPS_STATUS          0x10
    3839#define SYSCALL_FBF_SYNC_WRITE       0x11
    3940#define SYSCALL_FBF_SYNC_READ        0x12
    40 #define SYSCALL_THREAD_ID            0x13
     41//                                   0x13
    4142#define SYSCALL_TIM_ALLOC            0x14
    4243#define SYSCALL_TIM_START            0x15
     
    4445#define SYSCALL_KILL_APP             0x17
    4546#define SYSCALL_EXEC_APP             0x18
    46 #define SYSCALL_CTX_SWITCH           0x19
    47 #define SYSCALL_VOBJ_GET_VBASE       0x1A
    48 #define SYSCALL_VOBJ_GET_LENGTH      0x1B
    49 #define SYSCALL_GET_XY               0x1C
    50 //                                   0x1D
    51 //                                   0x1E
    52 //                                   0x1F
     47//                                   0x19
     48#define SYSCALL_PTHREAD_CONTROL      0x1A
     49#define SYSCALL_PTHREAD_YIELD        0x1B
     50#define SYSCALL_PTHREAD_KILL         0x1C
     51#define SYSCALL_PTHREAD_CREATE       0x1D
     52#define SYSCALL_PTHREAD_JOIN         0x1E
     53#define SYSCALL_PTHREAD_EXIT         0x1F
    5354
    5455#define SYSCALL_FAT_OPEN             0x20
     
    7576#define SYSCALL_NIC_STATS            0x34
    7677#define SYSCALL_NIC_CLEAR            0x35
    77 //                                   0x36
    78 //                                   0x37
    79 //                                   0x38
     78#define SYSCALL_TTY_WRITE            0x36
     79#define SYSCALL_TTY_READ             0x37
     80#define SYSCALL_TTY_ALLOC            0x38
    8081//                                   0x39
    8182//                                   0x3A
     
    152153
    153154//////////////////////////////////////////////////////////////////////////
    154 //              Task related system calls
    155 //////////////////////////////////////////////////////////////////////////
    156 
    157 extern unsigned int giet_proc_task_id();
    158 
    159 extern unsigned int giet_global_task_id();
    160 
    161 extern unsigned int giet_thread_id();
    162 
    163 extern void giet_exit( char* string );
    164 
    165 extern void giet_assert( unsigned int condition,
    166                          char*        string );
    167 
    168 extern void giet_context_switch();
    169 
    170 extern void giet_tasks_status();
     155//              Threads related system calls
     156//////////////////////////////////////////////////////////////////////////
     157
     158typedef unsigned int pthread_t;
     159
     160typedef unsigned int pthread_attr_t;
     161
     162extern int giet_pthread_create( pthread_t*       trdid,
     163                                pthread_attr_t*  attr,
     164                                void*            function,
     165                                void*            ptr );
     166
     167extern void giet_pthread_exit( void* string );
     168
     169extern int giet_pthread_join( pthread_t  trdid,
     170                              void**     ptr );
     171
     172extern int giet_pthread_kill( pthread_t thread_id,
     173                              int       signal );
     174
     175extern void giet_pthread_yield();
     176
     177extern void giet_pthread_assert( unsigned int condition,
     178                                 char*        string );
     179
     180extern int giet_pthread_pause( char*      vspace,
     181                               char*      thread );
     182
     183extern int giet_pthread_resume( char*      vspace,
     184                                char*      thread );
     185
     186extern int giet_pthread_context( char*      vspace,
     187                                 char*      thread );
    171188
    172189//////////////////////////////////////////////////////////////////////////
     
    177194
    178195extern int giet_exec_application( char* name );
     196
     197extern void giet_applications_status();
    179198
    180199//////////////////////////////////////////////////////////////////////////
     
    258277//////////////////////////////////////////////////////////////////////////
    259278
    260 extern unsigned int giet_nic_rx_alloc( unsigned int xmax, unsigned int ymax );
    261 
    262 extern unsigned int giet_nic_tx_alloc( unsigned int xmax, unsigned int ymax );
    263 
    264 extern void giet_nic_rx_start( unsigned int channel );
    265 
    266 extern void giet_nic_tx_start( unsigned int channel );
    267 
    268 extern void giet_nic_rx_move( unsigned int channel, void* buffer );
    269 
    270 extern void giet_nic_tx_move( unsigned int channel, void* buffer );
    271 
    272 extern void giet_nic_rx_stop( unsigned int channel );
    273 
    274 extern void giet_nic_tx_stop( unsigned int channel );
    275 
    276 extern void giet_nic_rx_stats( unsigned int channel );
    277 
    278 extern void giet_nic_tx_stats( unsigned int channel );
    279 
    280 extern void giet_nic_rx_clear( unsigned int channel );
    281 
    282 extern void giet_nic_tx_clear( unsigned int channel );
     279extern void giet_nic_rx_alloc( unsigned int xmax, unsigned int ymax );
     280
     281extern void giet_nic_tx_alloc( unsigned int xmax, unsigned int ymax );
     282
     283extern void giet_nic_rx_start();
     284
     285extern void giet_nic_tx_start();
     286
     287extern void giet_nic_rx_move( void* buffer );
     288
     289extern void giet_nic_tx_move( void* buffer );
     290
     291extern void giet_nic_rx_stop();
     292
     293extern void giet_nic_tx_stop();
     294
     295extern void giet_nic_rx_stats();
     296
     297extern void giet_nic_tx_stats();
     298
     299extern void giet_nic_rx_clear();
     300
     301extern void giet_nic_tx_clear();
    283302
    284303//////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/giet_libs/user_barrier.c

    r693 r709  
    208208{
    209209    // check parameters
    210     if ( x_size > 16 ) giet_exit("SQT BARRIER ERROR : x_size too large");
    211     if ( y_size > 16 ) giet_exit("SQT BARRIER ERROR : y_size too large");
    212     if ( ntasks > 8  ) giet_exit("SQT BARRIER ERROR : ntasks too large");
     210    giet_pthread_assert( (x_size <= 16) , "SQT BARRIER ERROR : x_size too large" );
     211    giet_pthread_assert( (y_size <= 16) , "SQT BARRIER ERROR : y_size too large" );
     212    giet_pthread_assert( (ntasks <= 8 ) , "SQT BARRIER ERROR : ntasks too large" );
    213213   
    214214    // compute SQT levels
  • soft/giet_vm/giet_libs/user_lock.c

    r693 r709  
    99
    1010#include "user_lock.h"
     11#include "malloc.h"
    1112#include "giet_config.h"
    1213#include "stdio.h"
    1314
    1415//////////////////////////////////////////////////////////////////////////////////
    15 // This function uses LL/SC to make an atomic increment.
     16//                atomic access functions
    1617//////////////////////////////////////////////////////////////////////////////////
     18
     19//////////////////////////////////////////////////
    1720unsigned int atomic_increment( unsigned int*  ptr,
    1821                               unsigned int   increment )
     
    3740
    3841///////////////////////////////////////////////////////////////////////////////////
    39 // This blocking function returns only when the lock has been taken.
    40 ///////////////////////////////////////////////////////////////////////////////////
     42//               simple lock access functions
     43///////////////////////////////////////////////////////////////////////////////////
     44
     45//////////////////////////////////////
    4146void lock_acquire( user_lock_t* lock )
    4247{
     
    4954unsigned int    lpid;
    5055giet_proc_xyp( &x, &y, &lpid );
    51 giet_tty_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] get ticket = %d"
     56giet_tty_printf("\n[USER_LOCK DEBUG] lock_acquire() : P[%d,%d,%d] get ticket = %d"
    5257                " for lock %x at cycle %d (current = %d / free = %d)\n",
    5358                x, y, lpid, ticket,
     
    6570               
    6671#if GIET_DEBUG_USER_LOCK
    67 giet_tty_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] get lock %x"
     72giet_tty_printf("\n[USER_LOCK DEBUG] lock_acquire() : P[%d,%d,%d] get lock %x"
    6873                " at cycle %d (current = %d / free = %d)\n",
    6974                x, y, lpid, (unsigned int)lock,
     
    7378}
    7479
    75 //////////////////////////////////////////////////////////////////////////////
    76 // This function releases the lock.
    77 //////////////////////////////////////////////////////////////////////////////
     80//////////////////////////////////////
    7881void lock_release( user_lock_t* lock )
    7982{
     
    8790unsigned int    lpid;
    8891giet_proc_xyp( &x, &y, &lpid );
    89 giet_tty_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] release lock %x"
     92giet_tty_printf("\n[USER_LOCK DEBUG] lock_release() : P[%d,%d,%d] release lock %x"
    9093                " at cycle %d (current = %d / free = %d)\n",
    9194                x, y, lpid, (unsigned int)lock,
     
    9598}
    9699
    97 //////////////////////////////////////////////////////////////////////////////
    98 // This function initializes the lock.
    99 //////////////////////////////////////////////////////////////////////////////
     100///////////////////////////////////
    100101void lock_init( user_lock_t* lock )
    101102{
     
    108109unsigned int    lpid;
    109110giet_proc_xyp( &x, &y, &lpid );
    110 giet_tty_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] init lock %x"
     111giet_tty_printf("\n[USER_LOCK DEBUG] lock_init() : P[%d,%d,%d] init lock %x"
    111112                " at cycle %d (current = %d / free = %d)\n",
    112113                x, y, lpid, (unsigned int)lock,
     
    114115#endif
    115116
     117}
     118
     119///////////////////////////////////////////////////////////////////////////////////
     120//               SQT lock access functions
     121///////////////////////////////////////////////////////////////////////////////////
     122
     123//////////////////////////////////////////////////
     124static void sqt_lock_build( sqt_lock_t*      lock,      // pointer on the SQT lock
     125                            unsigned int     x,         // node X coordinate
     126                            unsigned int     y,         // node Y coordinate
     127                            unsigned int     level,     // node level
     128                            sqt_lock_node_t* parent,    // pointer on parent node
     129                            unsigned int     xmax,      // SQT X size
     130                            unsigned int     ymax )     // SQT Y size
     131{
     132
     133#if GIET_DEBUG_USER_LOCK
     134unsigned int    px;
     135unsigned int    py;
     136unsigned int    pl;
     137giet_proc_xyp( &px, &py, &pl );
     138#endif
     139
     140    // get target node pointer
     141    sqt_lock_node_t* node = lock->node[x][y][level];
     142   
     143    if (level == 0 )        // terminal case
     144    {
     145        // initializes target node
     146        node->current  = 0;   
     147        node->free     = 0;
     148        node->level    = 0;
     149        node->parent   = parent;
     150        node->child[0] = NULL;
     151        node->child[1] = NULL;
     152        node->child[2] = NULL;
     153        node->child[3] = NULL;
     154
     155#if GIET_DEBUG_USER_LOCK
     156giet_tty_printf("\n[USER_LOCK DEBUG] sqt_lock_build() : "
     157                "P[%d,%d,%d] initialises SQT node[%d,%d,%d] = %x :\n"
     158                " parent = %x / child0 = %x / child1 = %x / child2 = %x / child3 = %x\n",
     159                px , py , pl , x , y , level , (unsigned int)node ,
     160                (unsigned int)node->parent ,
     161                (unsigned int)node->child[0] ,
     162                (unsigned int)node->child[1] ,
     163                (unsigned int)node->child[2] ,
     164                (unsigned int)node->child[3] );
     165#endif
     166
     167    }
     168    else                   // non terminal case
     169    {
     170        unsigned int cx[4];      // x coordinate for children
     171        unsigned int cy[4];      // y coordinate for children
     172        unsigned int i;          // child index
     173
     174        // the child0 coordinates are equal to the parent coordinates
     175        // other childs coordinates are incremented depending on the level value
     176        cx[0] = x;
     177        cy[0] = y;
     178
     179        cx[1] = x + (1 << (level-1));
     180        cy[1] = y;
     181
     182        cx[2] = x;
     183        cy[2] = y + (1 << (level-1));
     184
     185        cx[3] = x + (1 << (level-1));
     186        cy[3] = y + (1 << (level-1));
     187
     188        // initializes target node
     189        for ( i = 0 ; i < 4 ; i++ )
     190        {
     191            if ( (cx[i] < xmax) && (cy[i] < ymax) )
     192                node->child[i] = lock->node[cx[i]][cy[i]][level-1];
     193            else 
     194                node->child[i] = NULL;
     195        }
     196        node->current  = 0;
     197        node->free     = 0;
     198        node->level    = level;
     199        node->parent   = parent;
     200
     201#if GIET_DEBUG_USER_LOCK
     202giet_tty_printf("\n[USER_LOCK DEBUG] sqt_lock_init() : "
     203                "P[%d,%d,%d] initialises SQT node[%d,%d,%d] : \n"
     204                " parent = %x / childO = %x / child1 = %x / child2 = %x / child3 = %x\n",
     205                px , py , pl , x , y , level ,
     206                (unsigned int)node->parent ,
     207                (unsigned int)node->child[0] ,
     208                (unsigned int)node->child[1] ,
     209                (unsigned int)node->child[2] ,
     210                (unsigned int)node->child[3] );
     211#endif
     212
     213       // recursive calls for children nodes
     214        for ( i = 0 ; i < 4 ; i++ )
     215        {
     216            if ( (cx[i] < xmax) && (cy[i] < ymax) )
     217                sqt_lock_build( lock,
     218                                 cx[i],
     219                                 cy[i],
     220                                 level-1,
     221                                 node,
     222                                 xmax,
     223                                 ymax );
     224        }
     225    }
     226}  // end _sqt_lock_build()
     227
     228
     229
     230//////////////////////////////////////
     231void sqt_lock_init( sqt_lock_t*  lock,
     232                    unsigned int x_size,      // number of clusters in a row
     233                    unsigned int y_size,      // number of clusters in a col
     234                    unsigned int nthreads )   // threads per clusters
     235{
     236    // check parameters
     237    if ( x_size > 16  ) giet_pthread_exit("SQT LOCK ERROR : x_size too large");
     238    if ( y_size > 16  ) giet_pthread_exit("SQT LOCK ERROR : y_size too large");
     239    if ( nthreads > 8 ) giet_pthread_exit("SQT LOCK ERROR : nthreads too large");
     240   
     241    // compute SQT levels
     242    unsigned int levels;
     243    unsigned int z = (x_size > y_size) ? x_size : y_size;
     244    levels = (z < 2) ? 1 : (z < 3) ? 2 : (z < 5) ? 3 : (z < 9) ? 4 : 5;
     245
     246#if GIET_DEBUG_USER_LOCK
     247unsigned int    px;
     248unsigned int    py;
     249unsigned int    pp;
     250giet_proc_xyp(&px, &py, &pp);
     251unsigned int side   = (z < 2) ? 1 : (z < 3) ? 2 : (z < 5) ? 4 : (z < 9) ? 8 : 16;
     252giet_tty_printf("\n[USER_LOCK DEBUG] sqt_lock_init() : "
     253                "P[%d,%d%d] makes sqt_nodes allocation for lock %x\n"
     254                " x_size = %d / y_size = %d / levels = %d / side = %d\n",
     255                px, py, pp, (unsigned int) lock, x_size , y_size , levels , side );
     256#endif
     257
     258   
     259    unsigned int x;              // x coordinate for one SQT node
     260    unsigned int y;              // y coordinate for one SQT node
     261    unsigned int l;              // level for one SQT node
     262
     263    for ( x = 0 ; x < x_size ; x++ )
     264    {
     265        for ( y = 0 ; y < y_size ; y++ )
     266        {
     267            for ( l = 0 ; l < levels ; l++ )             // level 0 nodes
     268            {
     269               
     270                if ( ( (l == 0) && ((x&0x00) == 0) && ((y&0x00) == 0) ) ||
     271                     ( (l == 1) && ((x&0x01) == 0) && ((y&0x01) == 0) ) ||
     272                     ( (l == 2) && ((x&0x03) == 0) && ((y&0x03) == 0) ) ||
     273                     ( (l == 3) && ((x&0x07) == 0) && ((y&0x07) == 0) ) ||
     274                     ( (l == 4) && ((x&0x0F) == 0) && ((y&0x0F) == 0) ) )
     275                 {
     276                     lock->node[x][y][l] =
     277                     (sqt_lock_node_t*)remote_malloc( sizeof(sqt_lock_node_t),
     278                                                       x, y );
     279
     280#if GIET_DEBUG_USER_LOCK
     281giet_tty_printf("\n[USER_LOCK DEBUG] squt_lock_init() : "
     282                "P[%d,%d,%d] allocates SQT node[%d,%d,%d] = %x\n",
     283                px , py , pp , x , y , l , (unsigned int)lock->node[x][y][l] );
     284#endif
     285                 }
     286            }
     287        }
     288    }
     289           
     290    // recursively initialize all SQT nodes from root to bottom
     291    sqt_lock_build( lock,
     292                     0,
     293                     0,
     294                     levels-1,
     295                     NULL,
     296                     x_size,
     297                     y_size );
     298
     299    asm volatile ("sync" ::: "memory");
     300
     301#if GIET_DEBUG_USER_LOCK
     302giet_tty_printf("\n[USER_LOCK DEBUG] sqt_lock_init() : "
     303                "P[%d,%d,%d] completes SQT nodes initialisation\n", px, py, pp);
     304#endif
     305
     306} // end sqt_lock_init()
     307
     308
     309//////////////////////////////////////////////////
     310static void sqt_lock_take( sqt_lock_node_t* node )
     311{
     312    // get next free ticket from local lock
     313    unsigned int ticket = atomic_increment( &node->free, 1 );
     314
     315#if GIET_DEBUG_USER_LOCK
     316unsigned int    x;
     317unsigned int    y;
     318unsigned int    l;
     319giet_proc_xyp(&x, &y, &l);
     320giet_tty_printf("\n[USER_LOCK DEBUG] sqt_lock_take() : "
     321                "P[%d,%d,%d] get ticket %d for SQT lock %x"
     322                " / level = %d / current = %d / free = %d\n",
     323                x , y , l , ticket , (unsigned int)node ,
     324                node->level , node->current , node->free );
     325#endif
     326
     327    // poll the local lock current index
     328    while ( (*(volatile unsigned int *)( &node->current )) != ticket ) asm volatile( "nop" );
     329
     330#if GIET_DEBUG_USER_LOCK
     331giet_tty_printf("\n[DEBUG SQT_LOCK] sqt_lock_take() : "
     332                "P[%d,%d,%d] get SQT lock %x"
     333                " / level = %d / current = %d / free = %d\n",
     334                x , y , l , (unsigned int)node ,
     335                node->level , node->current , node->free );
     336#endif
     337
     338    // try to take the parent node lock until top is reached
     339    if ( node->parent != NULL ) sqt_lock_take( node->parent );
     340
     341} // end _sqt_lock_take()
     342
     343
     344//////////////////////////////////////////
     345void sqt_lock_acquire( sqt_lock_t*  lock )
     346{
     347    unsigned int x;
     348    unsigned int y;
     349    unsigned int p;
     350
     351    // get cluster coordinates
     352    giet_proc_xyp( &x, &y, &p );
     353
     354#if GIET_DEBUG_USER_LOCK
     355giet_tty_printf("\n[DEBUG SQT_LOCK] sqt_lock_acquire() : "
     356                "P[%d,%d,%d] try to take lock = %x / lock_node = %x\n",
     357                x, y, p, lock, lock->node[x][y][0] );
     358#endif
     359
     360    // try to recursively take the distributed locks (from bottom to top)
     361    sqt_lock_take( lock->node[x][y][0] );
     362}
     363
     364//////////////////////////////////////////////////
     365static void sqt_lock_give( sqt_lock_node_t* node )
     366{
     367    // release the local lock
     368    node->current = node->current + 1;
     369
     370#if GIET_DEBUG_USER_LOCK
     371unsigned int    x;
     372unsigned int    y;
     373unsigned int    l;
     374giet_proc_xyp(&x, &y, &l);
     375giet_tty_printf("\n[USER_LOCK DEBUG] sqt_lock_give() : "
     376                "P[%d,%d,%d] release SQT lock_node %x"
     377                " / level = %d / current = %d / free = %d\n",
     378                x , y , l , (unsigned int)node,
     379                node->level , node->current , node->free );
     380#endif
     381
     382    // reset parent node until top is reached
     383    if ( node->parent != NULL ) sqt_lock_give( node->parent );
     384
     385} // end _sqt_lock_give()
     386
     387//////////////////////////////////////////
     388void sqt_lock_release( sqt_lock_t*  lock )
     389{
     390    asm volatile ( "sync" );   // for consistency
     391
     392    unsigned int x;
     393    unsigned int y;
     394    unsigned int p;
     395    // get cluster coordinates
     396    giet_proc_xyp( &x, &y, &p );
     397
     398    // recursively reset the distributed locks (from bottom to top)
     399    sqt_lock_give( lock->node[x][y][0] );
    116400}
    117401
  • soft/giet_vm/giet_libs/user_lock.h

    r461 r709  
    88///////////////////////////////////////////////////////////////////////////////////
    99
    10 #ifndef _GIET_FILE_LOCK_H_
    11 #define _GIET_FILE_LOCK_H_
     10#ifndef _USER_LOCK_H_
     11#define _USER_LOCK_H_
     12
     13#include "hard_config.h"
    1214
    1315///////////////////////////////////////////////////////////////////////////////////
    14 //  lock structure
     16//  simple lock structure
    1517///////////////////////////////////////////////////////////////////////////////////
    1618
     
    2325
    2426///////////////////////////////////////////////////////////////////////////////////
    25 //  access functions
     27//  simple lock access functions
    2628///////////////////////////////////////////////////////////////////////////////////
    2729
     
    3537extern void lock_init( user_lock_t * lock );
    3638
     39///////////////////////////////////////////////////////////////////////////////////
     40//      SQT lock structures
     41///////////////////////////////////////////////////////////////////////////////////
     42
     43typedef struct sqt_lock_node_s
     44{
     45    unsigned int            current;         // current ticket index
     46    unsigned int            free;            // next free ticket index
     47    unsigned int            level;           // hierarchical level (0 is bottom)
     48    struct sqt_lock_node_s* parent;          // parent node (NULL for root)
     49    struct sqt_lock_node_s* child[4];        // children node
     50    unsigned int            padding[8];      // for 64 bytes alignment         
     51} sqt_lock_node_t;
     52
     53typedef struct sqt_lock_s
     54{
     55    sqt_lock_node_t* node[X_SIZE][Y_SIZE][5];  // array of pointers on SBT nodes
     56} sqt_lock_t;
     57
     58//////////////////////////////////////////////////////////////////////////////////
     59//      SQT lock access functions
     60//////////////////////////////////////////////////////////////////////////////////
     61
     62
     63extern void sqt_lock_init( sqt_lock_t*  lock,
     64                       unsigned int         x_size,
     65                       unsigned int         y_size,
     66                       unsigned int         ntasks );
     67
     68extern void sqt_lock_acquire( sqt_lock_t*  lock );
     69
     70extern void sqt_lock_release( sqt_lock_t*  lock );
     71
    3772#endif
    3873
  • soft/giet_vm/giet_python/mapping.py

    r642 r709  
    1010#  This file contains the classes required to define a mapping for the GIET_VM.
    1111# - A 'Mapping' contains a set of 'Cluster'   (hardware architecture)
    12 #                        a set of 'Vseg'      (kernel glogals virtual segments)
     12#                        a set of 'Vseg'      (kernel global virtual segments)
    1313#                        a set of 'Vspace'    (one or several user applications)
    1414# - A 'Cluster' contains a set of 'Pseg'      (physical segments in cluster)
     
    1616#                        a set of 'Periph'    (peripherals in cluster)
    1717# - A 'Vspace' contains  a set of 'Vseg'      (user virtual segments)
    18 #                        a set of 'Task'      (user parallel tasks)
     18#                        a set of 'Thread'    (POSIX thread)
    1919# - A 'Periph' contains  a set of 'Irq'       (only for XCU and PIC types )
    2020###################################################################################
     
    2222# The objects used to describe a mapping are distributed in the PYTHON structure:
    2323# For example the psegs set is split in several subsets (one subset per cluster),
    24 # or the tasks set is split in several subsets (one subset per vspace), etc...
     24# or the threads set is split in several subsets (one subset per vspace), etc...
    2525# In the C binary data structure used by the giet_vm, all objects of same type
    2626# are stored in a linear array (one single array for all psegs for example).
     
    192192        self.total_psegs    = 0
    193193        self.total_vsegs    = 0
    194         self.total_tasks    = 0
     194        self.total_threads  = 0
    195195        self.total_procs    = 0
    196196        self.total_irqs     = 0
     
    406406        return vseg
    407407
    408     ################################    add a task in a vspace
    409     def addTask( self,
    410                  vspace,                # vspace containing task
    411                  name,                  # task name
    412                  trdid,                 # task index in vspace
    413                  x,                     # destination x coordinate
    414                  y,                     # destination y coordinate
    415                  lpid,                  # destination processor local index
    416                  stackname,             # name of vseg containing stack
    417                  heapname,              # name of vseg containing heap
    418                  startid ):             # index in start_vector
    419 
    420         assert (x < self.x_size) and (y < self.y_size)
    421         assert lpid < self.nprocs
    422 
    423         # add one task into mapping
    424         task = Task( name, trdid, x, y, lpid, stackname, heapname, startid )
    425         vspace.tasks.append( task )
    426         task.index = self.total_tasks
    427         self.total_tasks += 1
    428 
    429         return task
     408    ################################    add a thread in a vspace
     409    def addThread( self,
     410                   vspace,                # vspace containing thread
     411                   name,                  # thread name
     412                   is_main,               # Boolean (one thread per vspace)
     413                   x,                     # destination x coordinate
     414                   y,                     # destination y coordinate
     415                   p,                     # destination processor local index
     416                   stackname,             # name of vseg containing stack
     417                   heapname,              # name of vseg containing heap
     418                   startid ):             # index in start_vector
     419
     420        assert x < self.x_size
     421        assert y < self.y_size
     422        assert p < self.nprocs
     423
     424        # add one thread into mapping
     425        thread = Thread( name, is_main, x, y, p, stackname, heapname, startid )
     426        vspace.threads.append( thread )
     427        thread.index = self.total_threads
     428        self.total_threads += 1
     429
     430        return thread
    430431
    431432    #################################
     
    497498
    498499        # header
    499         byte_stream += self.int2bytes(4,  self.signature)
    500         byte_stream += self.int2bytes(4,  self.x_size)
    501         byte_stream += self.int2bytes(4,  self.y_size)
    502         byte_stream += self.int2bytes(4,  self.x_width)
    503         byte_stream += self.int2bytes(4,  self.y_width)
    504         byte_stream += self.int2bytes(4,  self.x_io)
    505         byte_stream += self.int2bytes(4,  self.y_io)
    506         byte_stream += self.int2bytes(4,  self.irq_per_proc)
    507         byte_stream += self.int2bytes(4,  self.use_ramdisk)
    508         byte_stream += self.int2bytes(4,  self.total_globals)
    509         byte_stream += self.int2bytes(4,  self.total_vspaces)
    510         byte_stream += self.int2bytes(4,  self.total_psegs)
    511         byte_stream += self.int2bytes(4,  self.total_vsegs)
    512         byte_stream += self.int2bytes(4,  self.total_tasks)
    513         byte_stream += self.int2bytes(4,  self.total_procs)
    514         byte_stream += self.int2bytes(4,  self.total_irqs)
    515         byte_stream += self.int2bytes(4,  self.total_periphs)
    516         byte_stream += self.str2bytes(64, self.name)
     500        byte_stream += self.int2bytes(4,   self.signature)
     501        byte_stream += self.int2bytes(4,   self.x_size)
     502        byte_stream += self.int2bytes(4,   self.y_size)
     503        byte_stream += self.int2bytes(4,   self.x_width)
     504        byte_stream += self.int2bytes(4,   self.y_width)
     505        byte_stream += self.int2bytes(4,   self.x_io)
     506        byte_stream += self.int2bytes(4,   self.y_io)
     507        byte_stream += self.int2bytes(4,   self.irq_per_proc)
     508        byte_stream += self.int2bytes(4,   self.use_ramdisk)
     509        byte_stream += self.int2bytes(4,   self.total_globals)
     510        byte_stream += self.int2bytes(4,   self.total_vspaces)
     511        byte_stream += self.int2bytes(4,   self.total_psegs)
     512        byte_stream += self.int2bytes(4,   self.total_vsegs)
     513        byte_stream += self.int2bytes(4,   self.total_threads)
     514        byte_stream += self.int2bytes(4,   self.total_procs)
     515        byte_stream += self.int2bytes(4,   self.total_irqs)
     516        byte_stream += self.int2bytes(4,   self.total_periphs)
     517        byte_stream += self.str2bytes(256, self.name)
    517518
    518519        if ( verbose ):
     
    531532            print 'total_psegs   = %d' % self.total_psegs
    532533            print 'total_vsegs   = %d' % self.total_vsegs
    533             print 'total_tasks   = %d' % self.total_tasks
     534            print 'total_threads   = %d' % self.total_threads
    534535            print 'total_procs   = %d' % self.total_procs
    535536            print 'total_irqs    = %d' % self.total_irqs
     
    574575        if ( verbose ): print '\n'
    575576
    576         # tasks array
     577        # threads array
    577578        index = 0
    578579        for vspace in self.vspaces:
    579             for task in vspace.tasks:
    580                 byte_stream += task.cbin( self, verbose, index, vspace )
     580            for thread in vspace.threads:
     581                byte_stream += thread.cbin( self, verbose, index, vspace )
    581582                index += 1
    582583
     
    985986        if ( (boot_stack_found == False) or (boot_stack_identity == False) ):
    986987             print '[genmap error] in giet_vsegs()'
    987              print '    seg_boot_stask missing or not identity mapping'
     988             print '    seg_boot_stack missing or not identity mapping'
    988989             sys.exit()
    989990
     
    19261927        self.active    = active         # active at boot if true
    19271928        self.vsegs     = []
    1928         self.tasks     = []
     1929        self.threads   = []
    19291930
    19301931        return
     
    19361937                            %(self.name , self.startname , self.active)
    19371938        for vseg in self.vsegs: s += vseg.xml()
    1938         for task in self.tasks: s += task.xml()
     1939        for thread in self.threads: s += thread.xml()
    19391940        s += '        </vspace>\n'
    19401941
     
    19651966            sys.exit(1)
    19661967
    1967         # compute first vseg and first task global index
     1968        # compute first vseg and first thread global index
    19681969        first_vseg_id = self.vsegs[0].index
    1969         first_task_id = self.tasks[0].index
    1970 
    1971         # compute number of tasks and number of vsegs
     1970        first_thread_id = self.threads[0].index
     1971
     1972        # compute number of threads and number of vsegs
    19721973        nb_vsegs = len( self.vsegs )
    1973         nb_tasks = len( self.tasks )
     1974        nb_threads = len( self.threads )
    19741975
    19751976        byte_stream = bytearray()
     
    19771978        byte_stream += mapping.int2bytes(4, vseg_start_id)     # vseg start_vector
    19781979        byte_stream += mapping.int2bytes(4, nb_vsegs)          # number of vsegs
    1979         byte_stream += mapping.int2bytes(4, nb_tasks)          # number of tasks
     1980        byte_stream += mapping.int2bytes(4, nb_threads)        # number of threads
    19801981        byte_stream += mapping.int2bytes(4, first_vseg_id)     # global index
    1981         byte_stream += mapping.int2bytes(4, first_task_id)     # global index
     1982        byte_stream += mapping.int2bytes(4, first_thread_id)     # global index
    19821983        byte_stream += mapping.int2bytes(4, self.active)       # always active if non zero
    19831984
     
    19851986            print 'start_id   = %d' %  vseg_start_id
    19861987            print 'nb_vsegs   = %d' %  nb_vsegs
    1987             print 'nb_tasks   = %d' %  nb_tasks
     1988            print 'nb_threads = %d' %  nb_threads
    19881989            print 'vseg_id    = %d' %  first_vseg_id
    1989             print 'task_id    = %d' %  first_task_id
     1990            print 'thread_id  = %d' %  first_thread_id
    19901991            print 'active     = %d' %  self.active
    19911992
     
    19931994
    19941995##################################################################################
    1995 class Task( object ):
     1996class Thread( object ):
    19961997##################################################################################
    19971998    def __init__( self,
    19981999                  name,
    1999                   trdid,
     2000                  is_main,
    20002001                  x,
    20012002                  y,
     
    20052006                  startid ):
    20062007
    2007         self.index     = 0             # global index value set by addTask()
    2008         self.name      = name          # tsk name
    2009         self.trdid     = trdid         # task index (unique in vspace)
     2008        self.index     = 0             # global index value set by addThread()
     2009        self.name      = name          # thread name
     2010        self.is_main   = is_main       # Boolean (one main per vspace)
    20102011        self.x         = x             # cluster x coordinate
    20112012        self.y         = y             # cluster y coordinate
     
    20162017        return
    20172018
    2018     ######################################
    2019     def xml( self ):    # xml for one task
    2020 
    2021         s =  '            <task name="%s"' % self.name
    2022         s += ' trdid="%d"'                 % self.trdid
     2019    ########################################
     2020    def xml( self ):    # xml for one thread
     2021
     2022        s =  '            <thread name="%s"' % self.name
     2023        s += ' is_main="%d"'               % self.is_main
    20232024        s += ' x="%d"'                     % self.x
    20242025        s += ' y="%d"'                     % self.y
     
    20322033        return s
    20332034
    2034     ##########################################################################
    2035     def cbin( self, mapping, verbose, expected, vspace ):  # C binary for Task
     2035    ############################################################################
     2036    def cbin( self, mapping, verbose, expected, vspace ):  # C binary for Thread
    20362037
    20372038        if ( verbose ):
    2038             print '*** cbin for task %s in vspace %s' \
     2039            print '*** cbin for thread %s in vspace %s' \
    20392040                     % (self.name, vspace.name)
    20402041
    20412042        # check index
    20422043        if (self.index != expected):
    2043             print '[genmap error] in Task.cbin()'
    2044             print '    task global index = %d / expected = %d' \
     2044            print '[genmap error] in Thread.cbin()'
     2045            print '    thread global index = %d / expected = %d' \
    20452046                        %(self.index,expected)
    20462047            sys.exit(1)
     
    20552056
    20562057        if ( vseg_stack_id == 0xFFFFFFFF ):
    2057             print '[genmap error] in Task.cbin()'
    2058             print '    stackname %s not found for task %s in vspace %s' \
     2058            print '[genmap error] in Thread.cbin()'
     2059            print '    stackname %s not found for thread %s in vspace %s' \
    20592060                  % ( self.stackname, self.name, vspace.name )
    20602061            sys.exit(1)
     
    20692070
    20702071            if ( vseg_heap_id == 0xFFFFFFFF ):
    2071                 print '[genmap error] in Task.cbin()'
    2072                 print '    heapname %s not found for task %s in vspace %s' \
     2072                print '[genmap error] in Thread.cbin()'
     2073                print '    heapname %s not found for thread %s in vspace %s' \
    20732074                      % ( self.heapname, self.name, vspace.name )
    20742075                sys.exit(1)
    20752076
    20762077        byte_stream = bytearray()
    2077         byte_stream += mapping.str2bytes(32,self.name)     # task name in vspace
     2078        byte_stream += mapping.str2bytes(32,self.name)     # thread name in vspace
    20782079        byte_stream += mapping.int2bytes(4, cluster_id)    # cluster global index
    20792080        byte_stream += mapping.int2bytes(4, self.p)        # processor local index
    2080         byte_stream += mapping.int2bytes(4, self.trdid)    # thread index in vspace
     2081        byte_stream += mapping.int2bytes(4, self.is_main)  # main if non zero
    20812082        byte_stream += mapping.int2bytes(4, vseg_stack_id) # stack vseg local index
    20822083        byte_stream += mapping.int2bytes(4, vseg_heap_id)  # heap vseg local index
     
    20872088            print 'clusterid  = %d' %  cluster_id
    20882089            print 'lpid       = %d' %  self.p
    2089             print 'trdid      = %d' %  self.trdid
     2090            print 'is_main    = %d' %  self.is_main
    20902091            print 'stackid    = %d' %  vseg_stack_id
    20912092            print 'heapid     = %d' %  vseg_heap_id
  • soft/giet_vm/giet_xml/mapping_info.h

    r645 r709  
    1414//
    1515// 2/ a description of the applications (called vspaces) to be - statically -
    16 // launched on the platform. The number of parallel tasks per application is
     16// mapped on the platform. The number of parallel threads per application is
    1717// variable (can be one). Each vspace contains a variable number
    1818// of virtual segments (called vsegs).
    1919//
    20 // 3/ the mapping directives: both tasks on processors, and software objects
    21 // (vsegs) on the physical memory banks (psegs).
     20// 3/ the mapping directives: both threads on processors, and software objects
     21// (vsegs) on physical memory banks (psegs).
    2222//
    2323// The mapping_info data structure is organised as the concatenation of
     
    2828// - mapping_vspace_t   vspace[] 
    2929// - mapping_vseg_t     vseg[]     
    30 // - mapping_task_t     task[] 
     30// - mapping_thread_t   thread[] 
    3131// - mapping_proc_t     proc[] 
    3232// - mapping_irq_t      irq[]   
     
    4444#define MAPPING_VSEG_SIZE     sizeof(mapping_vseg_t)
    4545#define MAPPING_PSEG_SIZE     sizeof(mapping_pseg_t)
    46 #define MAPPING_TASK_SIZE     sizeof(mapping_task_t)
     46#define MAPPING_THREAD_SIZE   sizeof(mapping_thread_t)
    4747#define MAPPING_PROC_SIZE     sizeof(mapping_proc_t)
    4848#define MAPPING_IRQ_SIZE      sizeof(mapping_irq_t)
     
    152152    unsigned int    psegs;           // total number of physical segments
    153153    unsigned int    vsegs;           // total number of virtual segments
    154     unsigned int    tasks;           // total number of tasks
     154    unsigned int    threads;         // total number of threads
    155155    unsigned int    procs;           // total number of processors
    156156    unsigned int    irqs;            // total number of irqs
    157157    unsigned int    periphs;         // total number of peripherals
    158     char name[64];                   // mapping name
     158    char name[256];                  // mapping name
    159159} mapping_header_t;
    160160
     
    183183    unsigned int    start_vseg_id;   // vseg containing start vector index
    184184    unsigned int    vsegs;           // number of vsegs in vspace
    185     unsigned int    tasks;           // number of tasks in vspace
     185    unsigned int    threads;         // number of threads in vspace
    186186    unsigned int    vseg_offset;     // global index of first vseg in vspace
    187     unsigned int    task_offset;     // global index of first task in vspace
     187    unsigned int    thread_offset;   // global index of first thread in vspace
    188188    unsigned int    active;          // always active if non zero
    189189} mapping_vspace_t;
     
    220220
    221221
    222 //////////////////////////////////////////////////////
    223 typedef struct __attribute__((packed))  mapping_task_s
    224 {
    225     char            name[32];        // task name (unique in vspace)
     222////////////////////////////////////////////////////////
     223typedef struct __attribute__((packed))  mapping_thread_s
     224{
     225    char            name[32];        // thread name (unique in vspace)
    226226    unsigned int    clusterid;       // global index in clusters set
    227227    unsigned int    proclocid;       // processor local index (inside cluster)
    228     unsigned int    trdid;           // thread index in vspace
     228    unsigned int    is_main;         // this thread is the application entry point
    229229    unsigned int    stack_vseg_id;   // global index for vseg containing stack
    230230    unsigned int    heap_vseg_id;    // global index for vseg containing heap
    231231    unsigned int    startid;         // index in start_vector
    232     unsigned int    ltid;            // task index in scheduler (dynamically defined)
    233 } mapping_task_t;
     232    unsigned int    ltid;            // thread index in scheduler (dynamically defined)
     233} mapping_thread_t;
    234234
    235235
  • soft/giet_vm/giet_xml/xml_driver.c

    r645 r709  
    126126    unsigned int pseg_id;
    127127    unsigned int vseg_id;
    128     unsigned int task_id;
     128    unsigned int thread_id;
    129129    unsigned int proc_id;
    130130    unsigned int irq_id;
     
    135135    mapping_vspace_t * vspace;
    136136    mapping_vseg_t * vseg;
    137     mapping_task_t * task;
     137    mapping_thread_t * thread;
    138138    mapping_irq_t * irq;   
    139139    mapping_periph_t * periph;
     
    161161            MAPPING_VSPACE_SIZE * header->vspaces);
    162162
    163     // computes the base address for tasks array
    164     task = (mapping_task_t *) ((char *) header +
     163    // computes the base address for threads array
     164    thread = (mapping_thread_t *) ((char *) header +
    165165            MAPPING_HEADER_SIZE +
    166166            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
     
    176176            MAPPING_VSPACE_SIZE * header->vspaces +
    177177            MAPPING_VSEG_SIZE * header->vsegs +
    178             MAPPING_TASK_SIZE * header->tasks +
     178            MAPPING_THREAD_SIZE * header->threads +
    179179            MAPPING_PROC_SIZE * header->procs);
    180180
     
    186186            MAPPING_VSPACE_SIZE * header->vspaces +
    187187            MAPPING_VSEG_SIZE * header->vsegs +
    188             MAPPING_TASK_SIZE * header->tasks +
     188            MAPPING_THREAD_SIZE * header->threads +
    189189            MAPPING_PROC_SIZE * header->procs +
    190190            MAPPING_IRQ_SIZE * header->irqs);
     
    342342        }
    343343
    344         //////////////////// tasks //////////////////////////////////////////////
    345 
    346         for (task_id = vspace[vspace_id].task_offset;
    347              task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
    348              task_id++)
     344        //////////////////// threads //////////////////////////////////////////////
     345
     346        for (thread_id = vspace[vspace_id].thread_offset;
     347             thread_id < (vspace[vspace_id].thread_offset + vspace[vspace_id].threads);
     348             thread_id++)
    349349        {
    350             unsigned int stack_vseg_id = task[task_id].stack_vseg_id;
    351             unsigned int heap_vseg_id  = task[task_id].heap_vseg_id;
    352             unsigned int cluster_id    = task[task_id].clusterid;
    353 
    354             fprintf(fpout, "            <task name=\"%s\"", task[task_id].name);
    355             fprintf(fpout, " trdid=\"%d\"", task[task_id].trdid);
     350            unsigned int stack_vseg_id = thread[thread_id].stack_vseg_id;
     351            unsigned int heap_vseg_id  = thread[thread_id].heap_vseg_id;
     352            unsigned int cluster_id    = thread[thread_id].clusterid;
     353
     354            fprintf(fpout, "            <thread name=\"%s\"", thread[thread_id].name);
     355            fprintf(fpout, " trdid=\"%d\"", thread[thread_id].trdid);
    356356            fprintf(fpout, " x=\"%d\"", cluster[cluster_id].x);
    357357            fprintf(fpout, " y=\"%d\"", cluster[cluster_id].y);
    358             fprintf(fpout, " p=\"%d\"", task[task_id].proclocid);
     358            fprintf(fpout, " p=\"%d\"", thread[thread_id].proclocid);
    359359            fprintf(fpout, "\n                 ");     
    360360            fprintf(fpout, " stackname=\"%s\"", vseg[stack_vseg_id].name);
    361361            if (heap_vseg_id != -1)
    362362            fprintf(fpout, " heapname=\"%s\"", vseg[heap_vseg_id].name);
    363             fprintf(fpout, " startid = \"%d\"", task[task_id].startid);
     363            fprintf(fpout, " startid = \"%d\"", thread[thread_id].startid);
    364364            fprintf(fpout, " />\n");
    365365        }
  • soft/giet_vm/giet_xml/xml_parser.c

    r645 r709  
    1111// 1) the multi-cluster/multi-processors hardware architecture description
    1212// 2) the various multi-threaded software applications
    13 // 3) the mapping directives bor both the tasks and the virtual segments.
     13// 3) the mapping directives bor both the threads and the virtual segments.
    1414// The corresponding C structures are defined in the "mapping_info.h" file.
    1515///////////////////////////////////////////////////////////////////////////////////////
     
    3131#define MAX_PSEGS      4096
    3232#define MAX_VSPACES    1024
    33 #define MAX_TASKS      4096
     33#define MAX_THREADS      4096
    3434#define MAX_VSEGS      4096
    3535#define MAX_PROCS      1024
     
    4848mapping_vspace_t *   vspace[MAX_VSPACES];    // vspace array
    4949mapping_vseg_t *     vseg[MAX_VSEGS];        // vseg array
    50 mapping_task_t *     task[MAX_TASKS];        // task array
     50mapping_thread_t *   thread[MAX_THREADS];      // thread array
    5151mapping_proc_t *     proc[MAX_PROCS];        // proc array
    5252mapping_irq_t *      irq[MAX_IRQS];          // irq array
     
    7272unsigned int vseg_loc_index = 0;
    7373
    74 unsigned int task_index = 0;
    75 unsigned int task_loc_index = 0;
     74unsigned int thread_index = 0;
     75unsigned int thread_loc_index = 0;
    7676
    7777
     
    275275
    276276
    277 //////////////////////////////////////
    278 void taskNode(xmlTextReaderPtr reader)
     277////////////////////////////////////////
     278void threadNode(xmlTextReaderPtr reader)
    279279{
    280280    unsigned int ok;
     
    285285    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
    286286
    287     if (task_index >= MAX_TASKS)
    288     {
    289         printf("[XML ERROR] The number of tasks is larger than %d\n", MAX_TASKS);
    290         exit(1);
    291     }
    292 
    293 #if XML_PARSER_DEBUG
    294 printf("   task %d\n", task_loc_index);
    295 #endif
    296 
    297     task[task_index] = (mapping_task_t *) malloc(sizeof(mapping_task_t));
     287    if (thread_index >= MAX_THREADS)
     288    {
     289        printf("[XML ERROR] The number of threads is larger than %d\n", MAX_THREADS);
     290        exit(1);
     291    }
     292
     293#if XML_PARSER_DEBUG
     294printf("   thread %d\n", thread_loc_index);
     295#endif
     296
     297    thread[thread_index] = (mapping_thread_t *) malloc(sizeof(mapping_thread_t));
    298298
    299299    ////////// get name attribute
     
    304304printf("      name      = %s\n", str);
    305305#endif
    306         strncpy( task[task_index]->name, str, 31 );
    307     }
    308     else
    309     {
    310         printf("[XML ERROR] illegal or missing <name> attribute for task (%d,%d)\n",
    311                 vspace_index, task_loc_index);
    312         exit(1);
    313     }
    314 
    315     ///////// get trdid attribute (optional)
    316     value = getIntValue(reader, "trdid", &ok);
    317 #if XML_PARSER_DEBUG
    318 printf("      trdid     = %d\n", value );
    319 #endif
    320     if ( ok ) task[task_index]->trdid = value;
    321     else      task[task_index]->trdid = task_loc_index;
     306        strncpy( thread[thread_index]->name, str, 31 );
     307    }
     308    else
     309    {
     310        printf("[XML ERROR] illegal or missing <name> for thread %d in vspace %d\n",
     311                thread_loc_index, vspace_index);
     312        exit(1);
     313    }
     314
     315    ///////// get is_main attribute
     316    value = getIntValue(reader, "is_main", &ok);
     317    if ( ok )
     318    {
     319#if XML_PARSER_DEBUG
     320printf("      is_main   = %d\n", value );
     321#endif
     322        thread[thread_index]->is_main = value;
     323    }
     324    else
     325    {
     326        printf("[XML ERROR] illegal or missing <is_main> for thread %d in vspace %d\n",
     327                thread_loc_index, vspace_index);
     328    }
    322329
    323330    ///////// get x coordinate
     
    328335    if ( !(ok && (x < header->x_size)) )
    329336    {
    330         printf("[XML ERROR] illegal or missing < x > attribute for task (%d,%d)\n",
    331                 vspace_index, task_loc_index);
     337        printf("[XML ERROR] illegal or missing < x > for thread %d in vspace %d)\n",
     338                thread_loc_index, vspace_index);
    332339        exit(1);
    333340    } 
     
    340347    if ( !(ok && (y < header->y_size)) )
    341348    {
    342         printf("[XML ERROR] illegal or missing < y > attribute for task (%d,%d)\n",
    343                 vspace_index, task_loc_index);
     349        printf("[XML ERROR] illegal or missing < y > for thread %d in vspace %d)\n",
     350                thread_loc_index, vspace_index);
    344351        exit(1);
    345352    } 
     
    352359    if( index >= 0 )
    353360    {
    354         task[task_index]->clusterid = index;
     361        thread[thread_index]->clusterid = index;
    355362    }
    356363    else
    357364    {
    358         printf("[XML ERROR] <clusterid> not found for task (%d,%d)\n",
    359                 vspace_index, task_loc_index);
     365        printf("[XML ERROR] <clusterid> not found for thread %d in vspace %d)\n",
     366                thread_loc_index, vspace_index);
    360367        exit(1);
    361368    }
     
    368375printf("      proclocid = %x\n", value);
    369376#endif
    370         if (value >= cluster[task[task_index]->clusterid]->procs)
    371         {
    372             printf("[XML ERROR] <proclocid> too large for task (%d,%d)\n",
    373                     vspace_index, task_loc_index);
     377        if (value >= cluster[thread[thread_index]->clusterid]->procs)
     378        {
     379            printf("[XML ERROR] <proclocid> too large for thread %d in vspace %d\n",
     380                    thread_loc_index, vspace_index);
    374381            exit(1);
    375382        }
    376         task[task_index]->proclocid = value;
     383        thread[thread_index]->proclocid = value;
    377384    } 
    378385    else
    379386    {
    380         printf("[XML ERROR] illegal or missing <p> attribute for task (%d,%d)\n",
    381                 vspace_index, task_loc_index);
     387        printf("[XML ERROR] illegal or missing < p > for thread %d in vspace %d)\n",
     388                thread_loc_index, vspace_index);
    382389        exit(1);
    383390    }
     
    396403printf("      stack_id  = %d\n", index);
    397404#endif
    398             task[task_index]->stack_vseg_id = index;
     405            thread[thread_index]->stack_vseg_id = index;
    399406        }
    400407        else
    401408        {
    402             printf("[XML ERROR] illegal or missing <stackname> for task (%d,%d)\n",
    403                     vspace_index, task_loc_index);
     409            printf("[XML ERROR] illegal or missing <stackname> for thread %d in vspace %d)\n",
     410                    thread_loc_index, vspace_index);
    404411            exit(1);
    405412        }
     
    407414    else
    408415    {
    409         printf("[XML ERROR] illegal or missing <stackname> for task (%d,%d)\n",
    410                 vspace_index, task_loc_index);
     416        printf("[XML ERROR] illegal or missing <stackname> for thread %d in vspace %d)\n",
     417                thread_loc_index, vspace_index);
    411418        exit(1);
    412419    }
     
    425432printf("      heap_id   = %d\n", index );
    426433#endif
    427             task[task_index]->heap_vseg_id = index;
     434            thread[thread_index]->heap_vseg_id = index;
    428435        }
    429436        else
    430437        {
    431             printf("[XML ERROR] illegal or missing <heapname> for task (%d,%d)\n",
    432                    vspace_index, task_loc_index);
     438            printf("[XML ERROR] illegal or missing <heapname> for thread %d in vspace %d)\n",
     439                   thread_loc_index, vspace_index);
    433440            exit(1);
    434441        }
     
    436443    else
    437444    {
    438         task[task_index]->heap_vseg_id = -1;
     445        thread[thread_index]->heap_vseg_id = -1;
    439446    }
    440447
     
    446453printf("      startid   = %x\n", value);
    447454#endif
    448         task[task_index]->startid = value;
     455        thread[thread_index]->startid = value;
    449456    } 
    450457    else
    451458    {
    452         printf("[XML ERROR] illegal or missing <startid> attribute for task (%d,%d)\n",
    453                 vspace_index, task_loc_index);
    454         exit(1);
    455     }
    456 
    457     task_index++;
    458     task_loc_index++;
    459 } // end taskNode()
     459        printf("[XML ERROR] illegal or missing <startid> for thread %d in vspace %d\n",
     460                thread_loc_index, vspace_index);
     461        exit(1);
     462    }
     463
     464    thread_index++;
     465    thread_loc_index++;
     466} // end threadNode()
    460467
    461468
     
    698705    unsigned int ok;
    699706
    700     vseg_loc_index = 0;
    701     task_loc_index = 0;
     707    vseg_loc_index   = 0;
     708    thread_loc_index = 0;
    702709
    703710    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
     
    727734    else    vspace[vspace_index]->active = 0;
    728735   
    729     ////////// set vseg_offset and task_offset attributes
     736    ////////// set vseg_offset and thread_offset attributes
    730737    vspace[vspace_index]->vseg_offset = vseg_index;
    731     vspace[vspace_index]->task_offset = task_index;
    732 
    733     ////////// initialise vsegs and tasks attributes
     738    vspace[vspace_index]->thread_offset = thread_index;
     739
     740    ////////// initialise vsegs and threads attributes
    734741    vspace[vspace_index]->vsegs = 0;
    735     vspace[vspace_index]->tasks = 0;
     742    vspace[vspace_index]->threads = 0;
    736743
    737744    ////////// get startname attribute
     
    754761            vspace[vspace_index]->vsegs += 1;
    755762        }
    756         else if (strcmp(tag, "task") == 0)
    757         {
    758             taskNode(reader);
    759             vspace[vspace_index]->tasks += 1;
     763        else if (strcmp(tag, "thread") == 0)
     764        {
     765            threadNode(reader);
     766            vspace[vspace_index]->threads += 1;
    760767        }
    761768        else if (strcmp(tag, "#text")    == 0) { }
     
    777784
    778785#if XML_PARSER_DEBUG
    779 printf("      vsegs       = %d\n", vspace[vspace_index]->vsegs );
    780 printf("      tasks       = %d\n", vspace[vspace_index]->tasks );
    781 printf("      vseg_offset = %d\n", vspace[vspace_index]->vseg_offset );
    782 printf("      task_offset = %d\n", vspace[vspace_index]->task_offset );
    783 printf("      start_id    = %d\n", vspace[vspace_index]->start_vseg_id );
    784 printf("      active      = %x\n", vspace[vspace_index]->active );
     786printf("      vsegs         = %d\n", vspace[vspace_index]->vsegs );
     787printf("      threads       = %d\n", vspace[vspace_index]->threads );
     788printf("      vseg_offset   = %d\n", vspace[vspace_index]->vseg_offset );
     789printf("      thread_offset = %d\n", vspace[vspace_index]->thread_offset );
     790printf("      start_id      = %d\n", vspace[vspace_index]->start_vseg_id );
     791printf("      active        = %x\n", vspace[vspace_index]->active );
    785792printf("  end vspace %d\n\n", vspace_index);
    786793#endif
     
    14881495        {
    14891496            header->vsegs = vseg_index;
    1490             header->tasks = task_index;
     1497            header->threads = thread_index;
    14911498            return;
    14921499        }
     
    16681675    header->psegs     = 0;
    16691676    header->vsegs     = 0;
    1670     header->tasks     = 0;
     1677    header->threads   = 0;
    16711678    header->procs     = 0;
    16721679    header->irqs      = 0;
     
    17651772printf("psegs     = %d\n", header->psegs);
    17661773printf("vsegs     = %d\n", header->vsegs);
    1767 printf("tasks     = %d\n", header->tasks);
     1774printf("threads   = %d\n", header->threads);
    17681775printf("procs     = %d\n", header->procs);
    17691776printf("irqs      = %d\n", header->irqs);
     
    17871794    // write vsegs
    17881795    BuildTable(fdout, "vseg", vseg_index, sizeof(mapping_vseg_t), (char **) vseg);
    1789     // write tasks array
    1790     BuildTable(fdout, "task", task_index, sizeof(mapping_task_t), (char **) task);
     1796    // write threads array
     1797    BuildTable(fdout, "thread", thread_index, sizeof(mapping_thread_t), (char **) thread);
    17911798    //building procs array
    17921799    BuildTable(fdout, "proc", proc_index, sizeof(mapping_proc_t), (char **) proc);
Note: See TracChangeset for help on using the changeset viewer.