Changeset 295


Ignore:
Timestamp:
Mar 26, 2014, 6:44:44 PM (11 years ago)
Author:
alain
Message:

Introducing a major release, to suppoort the tsar_generic_leti platform
and the various (external or internal) peripherals configurations.
The map.xml format has been modified, in order to support the new
vci_iopic componentand a new policy for peripherals initialisation.
The IRQs are nom described in the XICU and IOPIC components
(and not anymore in the processors).
To enforce this major change, the map.xml file signature changed:
The signature value must be: 0xDACE2014

This new release has been tested on the tsar_generic_leti platform
for the following mappings:

  • 4c_4p_sort_leti
  • 4c_4p_sort_leti_ext
  • 4c_4p_transpose_leti
  • 4c_4p_transpose_leti_ext
  • 4c_1p_four_leti_ext
Location:
soft/giet_vm
Files:
9 added
47 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/Makefile

    r289 r295  
    1111### partition sectors    = 524832
    1212
    13 MAP_XML      = mappings/4c_1p_iob_four.xml
     13MAP_XML      = mappings/4c_4p_sort_leti_ext.xml
    1414
    1515### Objects to be linked for kernel.elf
     
    1818               build/fat32/fat32.o        \
    1919               build/drivers/dma_driver.o \
     20               build/drivers/cma_driver.o \
    2021               build/drivers/fbf_driver.o \
    2122               build/drivers/xcu_driver.o \
     
    2627               build/drivers/sdc_driver.o \
    2728               build/drivers/spi_driver.o \
     29               build/drivers/rdk_driver.o \
    2830               build/drivers/iob_driver.o \
    2931               build/drivers/mmc_driver.o \
     
    3234               build/drivers/tim_driver.o \
    3335               build/drivers/tty_driver.o \
     36               build/drivers/pic_driver.o \
    3437               build/kernel/giet.o        \
    3538               build/kernel/switch.o      \
     
    4447               build/common/vmem.o        \
    4548               build/fat32/fat32.o        \
     49               build/drivers/dma_driver.o \
    4650               build/drivers/tty_driver.o \
     51               build/drivers/pic_driver.o \
    4752               build/drivers/xcu_driver.o \
    48                build/drivers/dma_driver.o \
    49                build/drivers/mwr_driver.o \
    5053               build/drivers/ioc_driver.o \
    5154               build/drivers/bdv_driver.o \
    52                build/drivers/hba_driver.o \
    5355               build/drivers/sdc_driver.o \
    5456               build/drivers/spi_driver.o \
    55                build/drivers/nic_driver.o \
     57               build/drivers/rdk_driver.o \
    5658               build/drivers/mmc_driver.o \
     59               build/drivers/mwr_driver.o \
    5760               build/kernel/ctx_handler.o \
    5861               build/kernel/switch.o      \
     
    9699              build/libs/barrier.o
    97100
     101### Objects to be linked for transpose.elf
     102TRANSPOSE_OBJS = build/transpose/main.o  \
     103                 build/libs/stdio.o      \
     104                 build/libs/malloc.o     \
     105                 build/libs/spin_lock.o  \
     106                 build/libs/barrier.o
    98107
    99108CFLAGS = -Wall -ffreestanding -mno-gpopt -mips32
     
    123132     build/gameoflife/gameoflife.elf \
    124133     build/sort/sort.elf             \
     134     build/transpose/transpose.elf   \
    125135     hdd/virt_hdd.dmg
    126136
     
    128138### This requires the generic LINUX/MacOS script "create_dmg" script
    129139### written by C.Fuguet. (should be installed in GIET-VM root directory).
    130 hdd/virt_hdd.dmg: map.bin                   \
    131          build/boot/boot.elf            \
    132          build/kernel/kernel.elf        \
    133          build/display/display.elf      \
    134          build/hello/hello.elf          \
    135          build/pgcd/pgcd.elf            \
    136          build/router/router.elf        \
    137          build/dhrystone/dhrystone.elf  \
    138          build/gameoflife/gameoflife.elf
     140hdd/virt_hdd.dmg: map.bin                \
     141         build/boot/boot.elf             \
     142         build/kernel/kernel.elf         \
     143         build/display/display.elf       \
     144         build/hello/hello.elf           \
     145         build/pgcd/pgcd.elf             \
     146         build/router/router.elf         \
     147         build/dhrystone/dhrystone.elf   \
     148         build/gameoflife/gameoflife.elf \
     149         build/sort/sort.elf             \
     150         build/transpose/transpose.elf
     151
    139152### remove all content of virtual disk virt_hdd
    140153        rm -rf hdd/virt_hdd/*
     
    162175
    163176### drivers compilation
     177build/drivers/cma_driver.o: giet_drivers/cma_driver.c  \
     178                            giet_drivers/cma_driver.h  \
     179                            giet_config.h              \
     180                            $(MAP_XML)
     181        $(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
     182
    164183build/drivers/dma_driver.o: giet_drivers/dma_driver.c  \
    165184                            giet_drivers/dma_driver.h  \
     
    216235        $(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
    217236
     237build/drivers/rdk_driver.o: giet_drivers/rdk_driver.c  \
     238                            giet_drivers/rdk_driver.h  \
     239                            giet_config.h              \
     240                            $(MAP_XML)
     241        $(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
     242
    218243build/drivers/iob_driver.o: giet_drivers/iob_driver.c  \
    219244                            giet_drivers/iob_driver.h  \
     
    248273build/drivers/tty_driver.o: giet_drivers/tty_driver.c  \
    249274                            giet_drivers/tty_driver.h  \
     275                            giet_config.h              \
     276                            $(MAP_XML)
     277        $(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
     278
     279build/drivers/pic_driver.o: giet_drivers/pic_driver.c  \
     280                            giet_drivers/pic_driver.h  \
    250281                            giet_config.h              \
    251282                            $(MAP_XML)
     
    399430
    400431build/sort/main.o: sort/main.c
     432        $(CC) $(USER_INCLUDE) $(CFLAGS) -c -o $@ $<
     433
     434### transpose compilation
     435build/transpose/transpose.elf: $(TRANSPOSE_OBJS) transpose/transpose.ld
     436        $(LD) -o $@ -T transpose/transpose.ld $(TRANSPOSE_OBJS)
     437        $(DU) -D $@ > $@.txt
     438
     439build/transpose/main.o: transpose/main.c
    401440        $(CC) $(USER_INCLUDE) $(CFLAGS) -c -o $@ $<
    402441
     
    419458        rm -rf build/dhrystone/*
    420459        rm -rf build/sort/*
     460        rm -rf build/transpose/*
    421461        rm -rf build/map.bin
    422462        rm -rf hdd/virt_hdd/*
  • soft/giet_vm/display/main.c

    r258 r295  
    1 #include <stdio.h>
     1#include "stdio.h"
     2#include "hard_config.h"
    23
    34#define NBLOCKS 32   // (128 * 128) / 512
     
    78__attribute__((constructor)) void main()
    89
    9     int           fd;
    10     int           blocks;
    11     unsigned int  ko;
    12     unsigned int  blocks_to_skip = 8*NBLOCKS;
     10    int             fd;
     11    int             blocks;
     12    unsigned int    ko;
     13    unsigned int    blocks_to_skip = 8*NBLOCKS;
    1314
    14     giet_tty_printf("\nStarting task DISPLAY on processor %d at cycle %d\n",
    15                     giet_procid(), giet_proctime() );
     15    unsigned int    procid     = giet_procid();
     16    unsigned int    cluster_xy = procid/NB_PROCS_MAX;
     17    unsigned int    lpid       = procid%NB_PROCS_MAX;
     18    unsigned int    x          = cluster_xy >> Y_WIDTH;
     19    unsigned int    y          = cluster_xy & ((1<<Y_WIDTH)-1);
     20
     21    giet_tty_printf( "*** Starting task display on processor[%d,%d,%d] at cycle %d\n\n",
     22                      x, y, lpid, giet_proctime() );
    1623
    1724    ///////////////////////////////////////////
  • soft/giet_vm/display/main_cma.c

    r258 r295  
    1 #include <stdio.h>
     1#include "stdio.h"
     2#include "hard_config.h"
    23
    34#define NBLOCKS 32
     
    89__attribute__((constructor)) void main(void)
    910{
    10     unsigned int ko;
    11     int          blocks;
    12     int          fd;
    13     unsigned int blocks_to_skip = 0;
     11    int             fd;
     12    unsigned int    blocks_to_skip = 0;
     13    unsigned int    procid         = giet_procid();
     14    unsigned int    cluster_xy     = procid/NB_PROCS_MAX;
     15    unsigned int    lpid           = procid%NB_PROCS_MAX;
     16    unsigned int    x              = cluster_xy >> Y_WIDTH;
     17    unsigned int    y              = cluster_xy & ((1<<Y_WIDTH)-1);
    1418
    15     giet_tty_printf("\nStarting task DISPLAY on processor %d at cycle %d\n",
    16                     giet_procid(), giet_proctime() );
     19    giet_tty_printf( "*** Starting task display on processor[%d,%d,%d] at cycle %d\n\n",
     20                      x, y, lpid, giet_proctime() );
    1721
    1822    //////////////////////////////////////////
     
    3034    }
    3135
    32     ////////////////////////////////////////////
    33     ko = giet_fb_cma_init( buf0, buf1, 128*128 );
    34     if ( ko )
    35     {
    36         giet_tty_printf("\n*** echec giet_cma_init at cycle %d\n",
     36    ////////////////////////////////////////
     37    giet_fb_cma_init( buf0, buf1, 128*128 );
     38
     39    giet_tty_printf("\ngiet_cma_init completed at cycle %d\n",
    3740                        giet_proctime() );
    38         giet_exit();
    39     }
    40     else
    41     {
    42         giet_tty_printf("\ngiet_cma_init completed at cycle %d\n",
    43                         giet_proctime() );
    44     }
    45 
    4641 
    4742    while ( blocks_to_skip < 10 * NBLOCKS )
    4843    {
    49         ////////////////////////////////////////////////////////////
    50         blocks = giet_fat_read( fd, buf0, NBLOCKS, blocks_to_skip );
    51         if ( blocks != NBLOCKS )
    52         {
    53             giet_tty_printf("\nechec giet_fat_read to buf0 at cycle %d\n",
     44        ///////////////////////////////////////////////////
     45        giet_fat_read( fd, buf0, NBLOCKS, blocks_to_skip );
     46
     47        giet_tty_printf("\ngiet_fat_read to buf0 completed at cycle = %d\n",
    5448                            giet_proctime() );
    55             giet_exit();
    56         }
    57         else
    58         {
    59             giet_tty_printf("\ngiet_fat_read to buf0 completed at cycle = %d\n",
     49
     50        ///////////////////////
     51        giet_fb_cma_write( 0 );
     52
     53        giet_tty_printf("giet_cma_write for buf0 completed at cycle = %d\n",
    6054                            giet_proctime() );
    61         }
    62 
    63         ///////////////////////////
    64         ko = giet_fb_cma_write( 0 );
    65         if ( ko )
    66         {
    67             giet_tty_printf("echec giet_cma_write for buf0 at cycle %d\n",
    68                             giet_proctime() );
    69             giet_exit();
    70         }
    71         else
    72         {
    73             giet_tty_printf("giet_cma_write for buf0 completed at cycle = %d\n",
    74                             giet_proctime() );
    75         }
    7655
    7756        blocks_to_skip = blocks_to_skip + NBLOCKS;
    7857
    79         ///////////////////////////////////////////////////////
    80         blocks = giet_fat_read( fd, buf1, NBLOCKS, blocks_to_skip );
    81         if ( blocks != NBLOCKS )
    82         {
    83             giet_tty_printf("echec giet_fat_read to buf1 at cycle %d\n",
     58        ///////////////////////////////////////////////////
     59        giet_fat_read( fd, buf1, NBLOCKS, blocks_to_skip );
     60
     61        giet_tty_printf("giet_fat_read to buf1 completed at cycle = %d\n",
    8462                            giet_proctime() );
    85             giet_exit();
    86         }
    87         else
    88         {
    89             giet_tty_printf("giet_fat_read to buf1 completed at cycle = %d\n",
     63
     64        ///////////////////////
     65        giet_fb_cma_write( 1 );
     66       
     67        giet_tty_printf("giet_cma_write for buf1 completed at cycle = %d\n",
    9068                            giet_proctime() );
    91         }
    9269
    93         ////////////////////////////
    94         ko = giet_fb_cma_write( 1 );
    95         if ( ko )
    96         {
    97             giet_tty_printf("echec giet_cma_write for buf1 at cycle %d\n",
    98                             giet_proctime() );
    99             giet_exit();
    100         }
    101         else
    102         {
    103             giet_tty_printf("giet_cma_write for buf1 completed at cycle = %d\n",
    104                             giet_proctime() );
    105         }
    10670        blocks_to_skip = blocks_to_skip + NBLOCKS;
    10771    }
  • soft/giet_vm/gameoflife/main.c

    r263 r295  
    2020
    2121giet_barrier_t barriers[2];
     22
     23unsigned int init_ok = 1;
    2224
    2325#define NEW 0
     
    8082}
    8183
     84//////////////////////////////////////////////////////
    8285void compute_new_gen(size_t base_line, size_t nb_line)
    8386{
    8487   size_t x,y;
    85    for (y = base_line; y < base_line + nb_line; y++){
    86       for(x = 0; x < WIDTH ; x++) {
     88   for (y = base_line; y < base_line + nb_line; y++)
     89   {
     90      for(x = 0; x < WIDTH ; x++)
     91      {
    8792         world[NEW][y][x] = compute_cell(x,y); 
    8893      }
     
    9095}
    9196
     97////////////////////////////////////////////////////
    9298void display_world(size_t base_line, size_t nb_line)
    9399{
     
    100106   }
    101107
    102    if (giet_fb_sync_write(base_line * WIDTH , &world[NEW][base_line][0], nb_line * WIDTH))
    103    {
    104       PRINTF("Echec fb_sync_write\n");
    105       giet_exit();
    106    }
    107    // TODO COLOR !
    108    /*if (giet_fb_sync_write(base_line * WIDTH + WIDTH*HEIGHT , &world_yuv[base_line][0], nb_line * WIDTH))
    109    {
    110       PRINTF("Echec fb_sync_write\n");
    111       giet_exit();
    112    }*/
     108   giet_fb_sync_write( base_line * WIDTH ,
     109                       &world[NEW][base_line][0],
     110                       nb_line * WIDTH);
    113111}
    114112
     113/////////////////////////////////////////////////////
    115114void grow_old_world(size_t base_line, size_t nb_line)
    116115{
    117116   size_t x,y;
    118    for (y = base_line; y < base_line + nb_line; y++){
    119       for(x = 0; x < WIDTH ; x++) {
     117   for (y = base_line; y < base_line + nb_line; y++)
     118   {
     119      for(x = 0; x < WIDTH ; x++)
     120      {
    120121         world[OLD][y][x] = world[NEW][y][x]; 
    121122      }
    122123   }
    123124}
    124 
    125 
    126125
    127126////////////////////////////////////////
     
    131130   unsigned int nlocal_procs  = NB_PROCS_MAX;               // processors per cluster
    132131   unsigned int nclusters     = X_SIZE*Y_SIZE;              // number of clusters
    133    unsigned int local_id      = proc_id % nlocal_procs;     // local processor id
    134    unsigned int cluster_id    = proc_id / nlocal_procs;     // cluster id
    135132   unsigned int nglobal_procs = nclusters * nlocal_procs;   // number of tasks
    136133   size_t i;
     
    142139
    143140   //  barriers initialization
    144    barrier_init(&barriers[0], nglobal_procs);
    145    barrier_init(&barriers[1], nglobal_procs);
     141   if ( proc_id == 0 )
     142   {
     143      barrier_init(&barriers[0], nglobal_procs);
     144      barrier_init(&barriers[1], nglobal_procs);
     145
     146      init_ok = 0;
     147   }
     148   else
     149   {
     150      while ( init_ok == 1 );
     151   }
     152
    146153   init_world(base_line, nb_line);
    147154
  • soft/giet_vm/giet_boot/boot.c

    r293 r295  
    6868///////////////////////////////////////////////////////////////////////////////////////
    6969
    70 // for vobjs initialisation
    7170#include <giet_config.h>
    7271#include <mwmr_channel.h>
     
    8079#include <nic_driver.h>
    8180#include <ioc_driver.h>
     81#include <pic_driver.h>
    8282#include <mwr_driver.h>
    8383#include <ctx_handler.h>
     
    874874        _putx( curr->length );
    875875        _puts(" / vbase ");
    876         _putl( curr->vbase );
     876        _putx( curr->vbase );
    877877        _puts(" / pbase ");
    878878        _putl( curr->pbase );
     
    894894        boot_vspace_pt_build(vspace_id);
    895895
    896         _puts("\n[BOOT] Page Table for vspace ");
     896        _puts("\n[BOOT] Page Table for vspace \"");
    897897        _puts( vspace[vspace_id].name );
    898         _puts(" completed at cycle ");
     898        _puts("\" completed at cycle ");
    899899        _putd( _get_proctime() );
    900900        _puts("\n");
     
    11491149    mapping_task_t*    task    = _get_task_base(header);
    11501150    mapping_vobj_t*    vobj    = _get_vobj_base(header);
    1151     mapping_proc_t*    proc    = _get_proc_base(header);
     1151    mapping_periph_t*  periph  = _get_periph_base(header);
    11521152    mapping_irq_t*     irq     = _get_irq_base(header);
    11531153
    11541154    unsigned int cluster_id;    // cluster index in mapping_info
    1155     unsigned int proc_id;       // processor index in mapping_info
     1155    unsigned int periph_id;     // peripheral index in mapping_info
    11561156    unsigned int irq_id;        // irq index in mapping_info
    11571157    unsigned int vspace_id;     // vspace index in mapping_info
     
    11631163    //   are reserved for the kernel (context switch)
    11641164
    1165     unsigned int alloc_tty_channel = 0;            // TTY channel allocator
    1166     unsigned int alloc_nic_channel = 0;            // NIC channel allocator
    1167     unsigned int alloc_cma_channel = 0;            // CMA channel allocator
    1168     unsigned int alloc_hba_channel = 0;            // IOC channel allocator
    1169     unsigned int alloc_tim_channel[X_SIZE*Y_SIZE]; // user TIMER allocators
    1170 
    1171     if (NB_TTY_CHANNELS > 1) alloc_tty_channel++;
     1165    unsigned int alloc_tty_channel = 1;             // TTY channel allocator
     1166    unsigned int alloc_nic_channel = 0;             // NIC channel allocator
     1167    unsigned int alloc_cma_channel = 0;             // CMA channel allocator
     1168    unsigned int alloc_hba_channel = 0;             // HBA channel allocator
     1169    unsigned int alloc_tim_channel[X_SIZE*Y_SIZE];  // user TIMER allocators
    11721170
    11731171    /////////////////////////////////////////////////////////////////////////
     
    11981196        alloc_tim_channel[cluster_id] = NB_PROCS_MAX;
    11991197
    1200         unsigned int  lpid;          // processor local index in cluster
    1201         unsigned int  sched_vbase;   // schedulers segment virtual base address
    1202         unsigned int  sched_length;  // schedulers segment length
    1203         unsigned int  nprocs;        // number of processors in cluster
    1204 
    1205         nprocs = cluster[cluster_id].procs;
    1206 
    12071198        // checking processors number
    1208         if ( nprocs > NB_PROCS_MAX )
     1199        if ( cluster[cluster_id].procs > NB_PROCS_MAX )
    12091200        {
    12101201            _puts("\n[BOOT ERROR] Too much processors in cluster[");
     
    12161207        }
    12171208 
    1218         // get scheduler array virtual base address and length
    1219         boot_get_sched_vaddr( cluster_id, &sched_vbase, &sched_length );
    1220 
    1221         // each processor scheduler requires 4 Kbytes
    1222         if ( sched_length < (nprocs<<12) )
    1223         {
    1224             _puts("\n[BOOT ERROR] Schedulers segment too small in cluster[");
    1225             _putd( x );
    1226             _puts(",");
    1227             _putd( y );
    1228             _puts("]\n");
    1229             _exit();
    1230         }
    1231 
    1232         // loop on processors
    1233         for ( proc_id = cluster[cluster_id].proc_offset, lpid = 0 ;
    1234               proc_id < cluster[cluster_id].proc_offset + cluster[cluster_id].procs;
    1235               proc_id++, lpid++ )
    1236         {
    1237             // current processor scheduler pointer : psched
    1238             static_scheduler_t* psched = (static_scheduler_t*)(sched_vbase+(lpid<<12));
    1239 
    1240             // set the schedulers pointers array
    1241             _schedulers[cluster_xy * NB_PROCS_MAX + lpid] = psched;
     1209        static_scheduler_t* psched;  // schedulers array base address in cluster
     1210
     1211        // no schedulers initialisation if nprocs == 0
     1212        if ( cluster[cluster_id].procs > 0 )
     1213        {
     1214            // get scheduler array virtual base address and length
     1215            unsigned int        sched_vbase;   // schedulers segment virtual base address
     1216            unsigned int        sched_length;  // schedulers segment length
     1217            boot_get_sched_vaddr( cluster_id, &sched_vbase, &sched_length );
     1218
     1219            if ( sched_length < (cluster[cluster_id].procs<<12) ) // 4 Kbytes per scheduler
     1220            {
     1221                _puts("\n[BOOT ERROR] Schedulers segment too small in cluster[");
     1222                _putd( x );
     1223                _puts(",");
     1224                _putd( y );
     1225                _puts("]\n");
     1226                _exit();
     1227            }
     1228
     1229            psched = (static_scheduler_t*)sched_vbase;
     1230
     1231            // scan cluster peripherals to find the ICU/XCU
     1232            unsigned int found = 0;
     1233            for ( periph_id = cluster[cluster_id].periph_offset ;
     1234                  periph_id < cluster[cluster_id].periph_offset + cluster[cluster_id].periphs;
     1235                  periph_id++ )
     1236            {
     1237                if( (periph[periph_id].type == PERIPH_TYPE_XCU) ||
     1238                    (periph[periph_id].type == PERIPH_TYPE_ICU) )
     1239                {
     1240                    found = 1;
     1241                    break;
     1242                }
     1243            }
     1244            if ( found == 0 )
     1245            {         
     1246                _puts("\n[BOOT ERROR] No ICU / XCU component in cluster[");
     1247                _putd( x );
     1248                _puts(",");
     1249                _putd( y );
     1250                _puts("]\n");
     1251                _exit();
     1252            }
     1253
     1254            // loop on schedulers for default values initialisation
     1255            unsigned int lpid;
     1256            for ( lpid = 0 ; lpid < cluster[cluster_id].procs ; lpid++ )
     1257            {
     1258                // set the schedulers pointers array
     1259                _schedulers[cluster_xy * NB_PROCS_MAX + lpid] =
     1260                      (static_scheduler_t*)&psched[lpid];
    12421261
    12431262#if BOOT_DEBUG_SCHED
    1244 _puts("\nProc_");
     1263_puts("\nProc[");
    12451264_putd( x );
    1246 _puts("_");
     1265_puts(",");
    12471266_putd( y );
    1248 _puts("_");
     1267_puts(",");
    12491268_putd( lpid );
    1250 _puts(" : scheduler virtual base address = ");
    1251 _putx( sched_vbase + (lpid<<12) );
    1252 _puts("\n");
    1253 #endif
    1254 
    1255             // initialise the "tasks" variable : default value is 0
    1256             psched->tasks = 0;
    1257 
    1258             // initialise the "current" variable : default value is idle_task
    1259             psched->current = IDLE_TASK_INDEX;
    1260 
    1261             // initialise interrupt_vector with default value (valid bit = 0)
    1262             unsigned int slot;
    1263             for (slot = 0; slot < 32; slot++) psched->interrupt_vector[slot] = 0;
    1264 
    1265             // initialise interrupt vector with the IRQs actually allocated
    1266             for (irq_id = proc[proc_id].irq_offset;
    1267                  irq_id < proc[proc_id].irq_offset + proc[proc_id].irqs;
    1268                  irq_id++)
     1269_puts("] : scheduler virtual base address = ");
     1270_putx( (unsigned int)&psched[lpid] );
     1271_puts("\n");
     1272#endif
     1273                // initialise the "tasks" and "current" variables default values
     1274                psched[lpid].tasks   = 0;
     1275                psched[lpid].current = IDLE_TASK_INDEX;
     1276
     1277                // initialise HWI / PTI / SWI vectors (valid bit = 0)
     1278                unsigned int slot;
     1279                for (slot = 0; slot < 32; slot++)
     1280                {
     1281                    psched[lpid].hwi_vector[slot] = 0;
     1282                    psched[lpid].pti_vector[slot] = 0;
     1283                    psched[lpid].wti_vector[slot] = 0;
     1284                }
     1285
     1286                // initializes the idle_task context in scheduler:
     1287                // - the SR slot is 0xFF03 because this task run in kernel mode.
     1288                // - it uses the page table of vspace[0]
     1289                // - it uses the kernel TTY terminal
     1290                // - slots containing addresses (SP, RA, EPC, PTAB, PTPR)
     1291                //   must be re-initialised by kernel_parallel_init()
     1292
     1293                psched[lpid].context[IDLE_TASK_INDEX][CTX_CR_ID]    = 0;
     1294                psched[lpid].context[IDLE_TASK_INDEX][CTX_SR_ID]    = 0xFF03;
     1295                psched[lpid].context[IDLE_TASK_INDEX][CTX_PTPR_ID]  = _ptabs_paddr[0]>>13;
     1296                psched[lpid].context[IDLE_TASK_INDEX][CTX_PTAB_ID]  = _ptabs_vaddr[0];
     1297                psched[lpid].context[IDLE_TASK_INDEX][CTX_TTY_ID]   = 0;
     1298                psched[lpid].context[IDLE_TASK_INDEX][CTX_LTID_ID]  = IDLE_TASK_INDEX;
     1299                psched[lpid].context[IDLE_TASK_INDEX][CTX_VSID_ID]  = 0;
     1300                psched[lpid].context[IDLE_TASK_INDEX][CTX_RUN_ID]   = 1;
     1301            }
     1302
     1303           
     1304            // loop on irqs for actual HWI / PTI / WTI vectors initialisation     
     1305            for ( irq_id = periph[periph_id].irq_offset ;
     1306                  irq_id < periph[periph_id].irq_offset + periph[periph_id].irqs ;
     1307                  irq_id++ )
    12691308            {
    1270                 unsigned int type    = irq[irq_id].type;
    1271                 unsigned int icu_id  = irq[irq_id].icuid;
    1272                 unsigned int isr_id  = irq[irq_id].isr;
     1309                unsigned int lpid    = irq[irq_id].dstid;
     1310                unsigned int dstx    = irq[irq_id].dstx;
     1311                unsigned int dsty    = irq[irq_id].dsty;
     1312                if ( (dstx != x) || (dsty != y) )
     1313                {
     1314                    _puts("\n[BOOT ERROR] Bad IRQ cluster coordinates in cluster[");
     1315                    _putd( x );
     1316                    _puts(",");
     1317                    _putd( y );
     1318                    _puts("]\n - dstx  = ");
     1319                    _putd( dstx );
     1320                    _puts("\n - dsty  = ");
     1321                    _putd( dsty );
     1322                    _puts("\n - x     = ");
     1323                    _putd( x );
     1324                    _puts("\n - y     = ");
     1325                    _putd( y );
     1326                    _puts("\n");
     1327                    _exit();
     1328                }
     1329                if ( lpid >= cluster[cluster_id].procs )
     1330                {
     1331                    _puts("\n[BOOT ERROR] Bad IRQ processor index in cluster[");
     1332                    _putd( x );
     1333                    _puts(",");
     1334                    _putd( y );
     1335                    _puts("]\n");
     1336                    _exit();
     1337                }
     1338                unsigned int type    = irq[irq_id].srctype;
     1339                unsigned int index   = irq[irq_id].srcid;
     1340                unsigned int isr     = irq[irq_id].isr;
    12731341                unsigned int channel = irq[irq_id].channel;
    12741342
    1275                 unsigned int value = ((isr_id  & 0xFF)        ) |
    1276                                      ((type    & 0xFF)   <<  8) |
     1343                unsigned int entry = ((isr & 0xFFFF)          ) |
    12771344                                     ((channel & 0x7FFF) << 16) |
    12781345                                     0x80000000;                    // Valid entry
    12791346
    1280                 psched->interrupt_vector[icu_id] = value;
     1347                if      (type == IRQ_TYPE_HWI) psched[lpid].hwi_vector[index] = entry;
     1348                else if (type == IRQ_TYPE_PTI) psched[lpid].pti_vector[index] = entry;
     1349                else if (type == IRQ_TYPE_WTI) psched[lpid].wti_vector[index] = entry;
    12811350
    12821351#if BOOT_DEBUG_SCHED
    1283 _puts("- IRQ : icu = ");
    1284 _putd(icu_id);
    1285 _puts(" / type = ");
    1286 _putd(type);
     1352_puts("- IRQ : type = ");
     1353_putd( type );
     1354_puts(" / index = ");
     1355_putd( index );
    12871356_puts(" / isr = ");
    1288 _putd(isr_id);
     1357_putd( isr );
    12891358_puts(" / channel = ");
    1290 _putd(channel);
    1291 _puts(" => vector_entry = ");
    1292 _putx( value );
    1293 _puts("\n");
    1294 #endif
    1295             }
    1296 
    1297             // initializes the idle_task context in scheduler:
    1298             // - the SR slot is 0xFF03 because this task run in kernel mode.
    1299             // - it uses the page table of vspace[0]
    1300             // - it uses the kernel TTY terminal
    1301             // - slots containing addresses (SP, RA, EPC, PTAB, PTPR)
    1302             //   must be re-initialised by kernel_parallel_init()
    1303 
    1304             psched->context[IDLE_TASK_INDEX][CTX_CR_ID]    = 0;
    1305             psched->context[IDLE_TASK_INDEX][CTX_SR_ID]    = 0xFF03;
    1306             psched->context[IDLE_TASK_INDEX][CTX_PTPR_ID]  = _ptabs_paddr[0]>>13;
    1307             psched->context[IDLE_TASK_INDEX][CTX_PTAB_ID]  = _ptabs_vaddr[0];
    1308             psched->context[IDLE_TASK_INDEX][CTX_TTY_ID]   = 0;
    1309             psched->context[IDLE_TASK_INDEX][CTX_LTID_ID]  = IDLE_TASK_INDEX;
    1310             psched->context[IDLE_TASK_INDEX][CTX_VSID_ID]  = 0;
    1311             psched->context[IDLE_TASK_INDEX][CTX_RUN_ID]   = 1;
    1312 
    1313         } // end for procs
     1359_putd( channel );
     1360_puts("\n");
     1361#endif
     1362
     1363            } // end for irqs
     1364        } // end if nprocs > 0
    13141365    } // end for clusters
    13151366
    13161367    ///////////////////////////////////////////////////////////////////
    1317     // Step 2 : loop on the vspaces and the tasks
    1318     //          to initialise the schedulers and the task contexts.
     1368    // Step 2 : loop on the vspaces and the tasks  to complete
     1369    //          the schedulers and task contexts initialisation.
    13191370
    13201371    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++)
     
    13291380             task_id++)
    13301381        {
    1331 
    1332             // compute the cluster coordinates
     1382            // compute the cluster coordinates & local processor index
    13331383            unsigned int x          = cluster[task[task_id].clusterid].x;
    13341384            unsigned int y          = cluster[task[task_id].clusterid].y;
    13351385            unsigned int cluster_xy = (x<<Y_WIDTH) + y;
     1386            unsigned int lpid       = task[task_id].proclocid;                 
    13361387
    13371388#if BOOT_DEBUG_SCHED
     
    13471398#endif
    13481399            // compute gpid (global processor index) and scheduler base address
    1349             unsigned int gpid = cluster_xy * NB_PROCS_MAX + task[task_id].proclocid;
     1400            unsigned int gpid = cluster_xy * NB_PROCS_MAX + lpid;
    13501401            static_scheduler_t* psched = _schedulers[gpid];
    13511402
     
    13601411
    13611412            // ctx_tty : TTY terminal global index provided by the global allocator
     1413            //           Each user terminal is a private ressource: the number of
     1414            //           requested terminal cannot be larger than NB_TTY_CHANNELS.             
    13621415            unsigned int ctx_tty = 0xFFFFFFFF;
    13631416            if (task[task_id].use_tty)
     
    13651418                if (alloc_tty_channel >= NB_TTY_CHANNELS)
    13661419                {
    1367                     _puts("\n[BOOT ERROR] TTY index too large for task ");
     1420                    _puts("\n[BOOT ERROR] TTY channel index too large for task ");
    13681421                    _puts(task[task_id].name);
    13691422                    _puts(" in vspace ");
     
    13731426                }
    13741427                ctx_tty = alloc_tty_channel;
    1375                 if (NB_TTY_CHANNELS > 1) alloc_tty_channel++;
    1376             }
     1428                alloc_tty_channel++;
     1429             }
     1430
    13771431            // ctx_nic : NIC channel global index provided by the global allocator
     1432            //           Each channel is a private ressource: the number of
     1433            //           requested channels cannot be larger than NB_NIC_CHANNELS.
    13781434            unsigned int ctx_nic = 0xFFFFFFFF;
    13791435            if (task[task_id].use_nic)
     
    13911447                alloc_nic_channel++;
    13921448            }
     1449
    13931450            // ctx_cma : CMA channel global index provided by the global allocator
     1451            //           Each channel is a private ressource: the number of
     1452            //           requested channels cannot be larger than NB_NIC_CHANNELS.
    13941453            unsigned int ctx_cma = 0xFFFFFFFF;
    13951454            if (task[task_id].use_cma)
     
    14071466                alloc_cma_channel++;
    14081467            }
     1468
    14091469            // ctx_hba : HBA channel global index provided by the global allocator
     1470            //           Each channel is a private ressource: the number of
     1471            //           requested channels cannot be larger than NB_NIC_CHANNELS.
    14101472            unsigned int ctx_hba = 0xFFFFFFFF;
    14111473            if (task[task_id].use_hba)
    14121474            {
    1413                 if (alloc_hba_channel >= NB_HBA_CHANNELS)
     1475                if (alloc_hba_channel >= NB_IOC_CHANNELS)
    14141476                {
    14151477                    _puts("\n[BOOT ERROR] IOC channel index too large for task ");
     
    14231485                alloc_hba_channel++;
    14241486            }
    1425             // ctx_tim : TIM local channel index provided by the cluster allocator
     1487            // ctx_tim : TIMER local channel index provided by the cluster allocator
     1488            //           Each timer is a private ressource
    14261489            unsigned int ctx_tim = 0xFFFFFFFF;
    14271490            if (task[task_id].use_tim)
     
    14381501                    _exit();
    14391502                }
    1440 
    1441                 // checking that there is an ISR_TIMER installed
    1442                 unsigned int found = 0;
    1443                 for ( irq_id = 0 ; irq_id < 32 ; irq_id++ ) 
    1444                 {
    1445                     unsigned int entry   = psched->interrupt_vector[irq_id];
    1446                     unsigned int isr     = entry & 0x000000FF;
    1447                     unsigned int channel = entry>>16;
    1448                     if ( (isr == ISR_TIMER) && (channel == alloc_tim_channel[cluster_id]) )
    1449                     {
    1450                         found     = 1;
    1451                         ctx_tim =  alloc_tim_channel[cluster_id];
    1452                         alloc_tim_channel[cluster_id]++;
    1453                         break;
    1454                     }
    1455                 }
    1456                 if (!found)
    1457                 {
    1458                     _puts("\n[BOOT ERROR] No ISR_TIMER installed for task ");
    1459                     _puts(task[task_id].name);
    1460                     _puts(" in vspace ");
    1461                     _puts(vspace[vspace_id].name);
    1462                     _puts("\n");
    1463                     _exit();
    1464                 }
     1503                ctx_tim =  alloc_tim_channel[cluster_id];
     1504                alloc_tim_channel[cluster_id]++;
    14651505            }
    14661506            // ctx_epc : Get the virtual address of the memory location containing
     
    15201560_puts("\nTask ");
    15211561_putd( task_id );
    1522 _puts(" allocated to processor ");
    1523 _putd( gpid );
    1524 _puts("\n  - ctx[LTID]   = ");
     1562_puts(" allocated to processor[");
     1563_putd( x )
     1564_puts(",");
     1565_putd( y )
     1566_puts(",");
     1567_putd( lpid )
     1568_puts("]\n  - ctx[LTID]   = ");
    15251569_putd( psched->context[ltid][CTX_LTID_ID] );
    15261570_puts("\n  - ctx[SR]     = ");
     
    15331577_putx( psched->context[ltid][CTX_PTPR_ID] );
    15341578_puts("\n  - ctx[TTY]    = ");
    1535 _putd( psched->context[ltid][CTX_TTY_ID] );
     1579_putx( psched->context[ltid][CTX_TTY_ID] );
    15361580_puts("\n  - ctx[NIC]    = ");
    1537 _putd( psched->context[ltid][CTX_NIC_ID] );
     1581_putx( psched->context[ltid][CTX_NIC_ID] );
    15381582_puts("\n  - ctx[CMA]    = ");
    1539 _putd( psched->context[ltid][CTX_CMA_ID] );
     1583_putx( psched->context[ltid][CTX_CMA_ID] );
    15401584_puts("\n  - ctx[IOC]    = ");
    1541 _putd( psched->context[ltid][CTX_HBA_ID] );
     1585_putx( psched->context[ltid][CTX_HBA_ID] );
    15421586_puts("\n  - ctx[TIM]    = ");
    1543 _putd( psched->context[ltid][CTX_TIM_ID] );
     1587_putx( psched->context[ltid][CTX_TIM_ID] );
    15441588_puts("\n  - ctx[PTAB]   = ");
    15451589_putx( psched->context[ltid][CTX_PTAB_ID] );
    15461590_puts("\n  - ctx[GTID]   = ");
    1547 _putd( psched->context[ltid][CTX_GTID_ID] );
     1591_putx( psched->context[ltid][CTX_GTID_ID] );
    15481592_puts("\n  - ctx[VSID]   = ");
    1549 _putd( psched->context[ltid][CTX_VSID_ID] );
     1593_putx( psched->context[ltid][CTX_VSID_ID] );
    15501594_puts("\n  - ctx[TRDID]  = ");
    1551 _putd( psched->context[ltid][CTX_TRDID_ID] );
     1595_putx( psched->context[ltid][CTX_TRDID_ID] );
    15521596_puts("\n");
    15531597#endif
     
    15651609    _ioc_init( 0 );
    15661610
    1567     int fd_id = _fat_open( IOC_BOOT_PA_MODE,
     1611    int fd_id = _fat_open( IOC_BOOT_MODE,
    15681612                           "map.bin",
    15691613                           0 );         // no creation
     
    15861630    if ( offset ) nblocks++;
    15871631
    1588     unsigned int ok = _fat_read( IOC_BOOT_PA_MODE,
     1632    unsigned int ok = _fat_read( IOC_BOOT_MODE,
    15891633                                 fd_id,
    15901634                                 (unsigned int*)( &seg_boot_mapping_base),
     
    17811825// The "preloader.elf" file is not loaded, because it has been burned in the ROM.
    17821826// The "boot.elf" file is not loaded, because it has been loaded by the preloader.
    1783 // It scans all vobjs defined in the map.bin data structure to collect
     1827// This function scans all vobjs defined in the map.bin data structure to collect
    17841828// all .elf files pathnames, and calls the load_one_elf_file() function to
    17851829// load all loadable segments at the virtual address found in the .elf file.
     
    18131857    }
    18141858
    1815     load_one_elf_file( IOC_BOOT_VA_MODE,
     1859    load_one_elf_file( IOC_BOOT_MODE,
    18161860                       vobj[vobj_id].binpath,
    18171861                       0 );                         // vspace 0
    18181862
    1819     _puts("\n[BOOT] File ");
     1863    _puts("\n[BOOT] File \"");
    18201864    _puts( vobj[vobj_id].binpath );
    1821     _puts(" loaded at cycle ");
     1865    _puts("\" loaded at cycle ");
    18221866    _putd( _get_proctime() );
    18231867    _puts("\n");
     
    18521896        }
    18531897
    1854         load_one_elf_file( IOC_BOOT_VA_MODE,
     1898        load_one_elf_file( IOC_BOOT_MODE,
    18551899                           vobj[vobj_id].binpath,
    18561900                           vspace_id );
    18571901
    1858         _puts("\n[BOOT] File ");
     1902        _puts("\n[BOOT] File \"");
    18591903        _puts( vobj[vobj_id].binpath );
    1860         _puts(" loaded at cycle ");
     1904        _puts("\" loaded at cycle ");
    18611905        _putd( _get_proctime() );
    18621906        _puts("\n");
     
    18821926    mapping_coproc_t * coproc   = _get_coproc_base(header);
    18831927    mapping_cp_port_t * cp_port = _get_cp_port_base(header);
     1928    mapping_irq_t * irq         = _get_irq_base(header);
    18841929
    18851930    unsigned int cluster_id;
     
    20012046                case PERIPH_TYPE_TTY:    // vci_multi_tty component
    20022047                {
     2048                    // nothing to do
    20032049#if BOOT_DEBUG_PERI
    20042050_puts("- TTY / channels = ");
     
    20252071_puts("\n");
    20262072#endif
     2073                    break;
     2074                }
     2075                case PERIPH_TYPE_PIC:    // vci_iopic component
     2076                {
     2077                         
     2078#if BOOT_DEBUG_PERI
     2079_puts("- PIC / channels = ");
     2080_putd(channels);
     2081_puts("\n");
     2082#endif
     2083                    // scan all HWI IRQs defined in mapping for PIC component,
     2084                    // and initialises addresses for WTI IRQs
     2085                    for ( channel_id = periph[periph_id].irq_offset ;
     2086                          channel_id < periph[periph_id].irq_offset + periph[periph_id].irqs ;
     2087                          channel_id++ )
     2088                    {
     2089                        unsigned int hwi_id  = irq[channel_id].srcid;  // HWI index in PIC
     2090                        unsigned int wti_id  = irq[channel_id].dstid;  // WTI index in XCU
     2091                        unsigned int x       = irq[channel_id].dstx;   // XCU X coordinate
     2092                        unsigned int y       = irq[channel_id].dsty;   // XCU Y coordinate
     2093                        unsigned int cluster = (x<<Y_WIDTH) + y;       // XCU cluster
     2094                        unsigned int vaddr;
     2095
     2096                        _xcu_get_wti_address( wti_id, &vaddr );
     2097
     2098                        _pic_init( hwi_id, vaddr, cluster );
     2099#if BOOT_DEBUG_PERI
     2100_puts("    hwi_index = ");
     2101_putd( hwi_id );
     2102_puts(" / wti_index = ");
     2103_putd( wti_id );
     2104_puts(" / vaddr = ");
     2105_putx( vaddr );
     2106_puts(" in cluster[");
     2107_putd( x );
     2108_puts(",");
     2109_putd( y );
     2110_puts("]\n");
     2111#endif
     2112                    }
    20272113                    break;
    20282114                }
     
    20892175void boot_init()
    20902176{
    2091     mapping_header_t* header     = (mapping_header_t *) & seg_boot_mapping_base;
    2092     unsigned int      gpid       = _get_procid();
    2093     unsigned int      cluster_xy = gpid / NB_PROCS_MAX;
    2094     unsigned int      lpid       = gpid % NB_PROCS_MAX;
     2177    mapping_header_t*  header     = (mapping_header_t *) & seg_boot_mapping_base;
     2178    mapping_cluster_t* cluster    = _get_cluster_base(header);
     2179    unsigned int       gpid       = _get_procid();
    20952180 
    20962181    if ( gpid == 0 )    // only Processor 0 does it
     
    21032188        boot_mapping_init();
    21042189
    2105         _puts("\n[BOOT] Mapping ");
     2190        _puts("\n[BOOT] Mapping \"");
    21062191        _puts( header->name );
    2107         _puts(" loaded at cycle ");
     2192        _puts("\" loaded at cycle ");
    21082193        _putd(_get_proctime());
    21092194        _puts("\n");
     
    21112196        // Building all page tables
    21122197        boot_pt_init();
    2113 
    2114         _puts("\n[BOOT] Page Tables initialisation completed at cycle ");
    2115         _putd(_get_proctime());
    2116         _puts("\n");
    21172198
    21182199        // Activating proc 0 MMU
     
    21342215        boot_schedulers_init();
    21352216
    2136         _puts("\n[BOOT] All schedulers initialised at cycle ");
     2217        _puts("\n[BOOT] Schedulers initialised at cycle ");
    21372218        _putd(_get_proctime());
    21382219        _puts("\n");
     
    21442225        boot_peripherals_init();
    21452226
    2146         _puts("\n[BOOT] All peripherals initialised at cycle ");
     2227        _puts("\n[BOOT] Non replicated peripherals initialised at cycle ");
    21472228        _putd(_get_proctime());
    21482229        _puts("\n");
     
    21512232        boot_elf_load();
    21522233
    2153         _puts("\n[BOOT] All ELF files loaded at cycle ");
    2154         _putd(_get_proctime());
    2155         _puts("\n");
    2156 
    21572234        // P0 starts all other processors
    2158         unsigned int x,y,p;
    2159         for (x = 0 ; x < X_SIZE ; x++)
    2160         {
    2161             for (y = 0 ; y < Y_SIZE ; y++)
     2235        unsigned int clusterid, p;
     2236
     2237        for ( clusterid = 0 ; clusterid < X_SIZE*Y_SIZE ; clusterid++ )
     2238        {
     2239            unsigned int nprocs     = cluster[clusterid].procs;
     2240            unsigned int xdest      = cluster[clusterid].x;
     2241            unsigned int ydest      = cluster[clusterid].y;
     2242            unsigned int cluster_xy = (xdest<<Y_WIDTH) + ydest;
     2243
     2244            for ( p = 0 ; p < nprocs; p++ )
    21622245            {
    2163                 for(p = 0; p < NB_PROCS_MAX; p++)
    2164                 {
    2165                     if ( (x != 0) || (y != 0) || (p != 0) )
    2166                     {
    2167                         _xcu_send_ipi( (x<<Y_WIDTH) + y,
    2168                                        p,
    2169                                        (unsigned int)boot_init );
    2170                     }
     2246                if ( (nprocs > 0) && ((clusterid != 0) || (p != 0)) )
     2247                {
     2248                    _xcu_send_wti( cluster_xy, p, (unsigned int)boot_init );
    21712249                }
    21722250            }
    21732251        }
     2252 
    21742253    }  // end monoprocessor boot
    21752254
     
    21862265        _set_mmu_ptpr( (unsigned int)(_ptabs_paddr[0]>>13) );
    21872266        _set_mmu_mode( 0xF );
    2188 
    2189         _tty_get_lock( 0 );
    2190         _puts("\n[BOOT] Processor[");
    2191         _putd( cluster_xy >> Y_WIDTH );
    2192         _puts(",");
    2193         _putd( cluster_xy & ((1<<Y_WIDTH)-1) );
    2194         _puts(",");
    2195         _putd( lpid );
    2196         _puts("] : MMU activation at cycle ");
    2197         _putd(_get_proctime());
    2198         _puts("\n");
    2199         _tty_release_lock( 0 );
    22002267    }
    22012268
    22022269    // all processors jump to kernel_init
    22032270    unsigned int kernel_entry = (unsigned int)&seg_kernel_init_base;
    2204 
    2205 #if GIET_DEBUG_INIT
    2206     _tty_get_lock( 0 );
    2207     _puts("\n[BOOT DEBUG] Processor[");
    2208     _putd( cluster_xy >> Y_WIDTH );
    2209     _puts(",");
    2210     _putd( cluster_xy & ((1<<Y_WIDTH)-1) );
    2211     _puts(",");
    2212     _putd( lpid );
    2213     _puts("] enters kernel at cycle ");
    2214     _putd( _get_proctime() );
    2215     _puts(" / kernel entry = ");
    2216     _putx( kernel_entry );
    2217     _puts("\n");
    2218     _tty_release_lock( 0 );
    2219 #endif
    2220 
    22212271    asm volatile( "jr   %0" ::"r"(kernel_entry) );
    22222272
  • soft/giet_vm/giet_common/mips32_registers.h

    r268 r295  
    5454#define CP0_PROCID     $15,1
    5555#define CP0_SCHED      $4,2
     56#define CP0_SRSAVE     $8
    5657
    5758/* CP2 registers */
  • soft/giet_vm/giet_common/utils.c

    r293 r295  
    4747                      unsigned int size )    // bytes
    4848{
    49     unsigned int*       dst = dest;
    50     const unsigned int* src = source;
     49    unsigned int* idst = (unsigned int*)dest;
     50    unsigned int* isrc = (unsigned int*)source;
    5151
    5252    // word-by-word copy
    53     if (!((unsigned int) dst & 3) && !((unsigned int) src & 3))
     53    if (!((unsigned int) idst & 3) && !((unsigned int) isrc & 3))
    5454    {
    5555        while (size > 3)
    5656        {
    57             *dst++ = *src++;
     57            *idst++ = *isrc++;
    5858            size -= 4;
    5959        }
    6060    }
    6161
    62     unsigned char * cdst = (unsigned char *) dst;
    63     unsigned char * csrc = (unsigned char *) src;
     62    unsigned char* cdst = (unsigned char*)dest;
     63    unsigned char* csrc = (unsigned char*)source;
    6464
    6565    /* byte-by-byte copy */
     
    7373// Fill a byte string with a byte value.
    7474//////////////////////////////////////////////////////////////////////////////////
    75 inline void * _memset( void*        dst,
     75inline void * _memset( void*        dest,
    7676                       int          value,
    7777                       unsigned int count )
    7878{
    79     char * a = (char *) dst;
     79    // word-by-word copy
     80    unsigned int* idst = dest;
     81    unsigned int  data = (((unsigned char)value)      ) |
     82                         (((unsigned char)value) <<  8) |
     83                         (((unsigned char)value) << 16) |
     84                         (((unsigned char)value) << 24) ;
     85
     86    if ( ! ((unsigned int)idst & 3) )
     87    {
     88        while ( count > 3 )
     89        {
     90            *idst++ = data;
     91            count -= 4;
     92        }
     93    }
     94   
     95    // byte-by-byte copy
     96    unsigned char* cdst = dest;
    8097    while (count--)
    8198    {
    82         *a++ = (char)value;
    83     }
    84     return dst;
     99        *cdst++ = (unsigned char)value;
     100    }
     101    return dest;
     102}
     103
     104//////////////////////////////////////////////////////////////////////////////////
     105// This function implements an interactive break for debug.
     106// Execution continue when typing any character on TTY0.
     107// The "str" argument is supposed to indicate the break location.
     108//////////////////////////////////////////////////////////////////////////////////
     109inline void _break( char* string )
     110{
     111    char byte;
     112
     113    _printf("\n[GIET DEBUG] break from %s / continue ?\n", string );
     114    _getc( &byte );
    85115}
    86116
     
    90120inline void _exit()
    91121{
     122    unsigned int procid     = _get_procid();
     123    unsigned int lpid       = procid % NB_PROCS_MAX;
     124    unsigned int cluster_xy = procid / NB_PROCS_MAX;
     125    unsigned int x          = cluster_xy >> Y_WIDTH;
     126    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
     127
     128
     129    _printf("\n[GIET PANIC] processor[%d,%d,%d] suicide...\n", x, y, lpid );
     130
    92131    while (1) { asm volatile ("nop"); }
    93132}
     
    103142{
    104143    unsigned int ret;
    105     asm volatile("mfc0      %0,     $4, 2\n" : "=r"(ret) );
     144    asm volatile( "mfc0      %0,     $4,2    \n"
     145                  : "=r"(ret) );
    106146    return ret;
    107147}
     
    112152{
    113153    unsigned int ret;
    114     asm volatile("mfc2      %0,     $0" : "=r"(ret));
     154    asm volatile( "mfc2      %0,     $0      \n"
     155                  : "=r"(ret) );
    115156    return ret;
    116157}
    117158///////////////////////////////////////////////////////////////////////////////////
     159// Returns MODE register content.
     160///////////////////////////////////////////////////////////////////////////////////
     161inline unsigned int _get_mmu_mode()
     162{
     163    unsigned int ret;
     164    asm volatile( "mfc2      %0,     $1      \n"
     165                  : "=r"(ret) );
     166    return ret;
     167}
     168///////////////////////////////////////////////////////////////////////////////////
    118169// Returns EPC register content.
    119170///////////////////////////////////////////////////////////////////////////////////
     
    121172{
    122173    unsigned int ret;
    123     asm volatile("mfc0      %0,     $14" : "=r"(ret));
     174    asm volatile( "mfc0      %0,    $14     \n"
     175                  : "=r"(ret) );
    124176    return ret;
    125177}
     
    130182{
    131183    unsigned int ret;
    132     asm volatile("mfc0      %0,     $8" : "=r"(ret));
     184    asm volatile( "mfc0      %0,    $8     \n"
     185                  : "=r"(ret));
    133186    return ret;
    134187}
     
    139192{
    140193    unsigned int ret;
    141     asm volatile("mfc0      %0,     $13" : "=r"(ret));
     194    asm volatile( "mfc0      %0,    $13    \n"
     195                  : "=r"(ret));
    142196    return ret;
    143197}
     
    148202{
    149203    unsigned int ret;
    150     asm volatile("mfc0      %0,     $12" : "=r"(ret));
     204    asm volatile( "mfc0      %0,     $12   \n"
     205                  : "=r"(ret));
    151206    return ret;
    152207}
     
    156211inline void _set_sr(unsigned int val)
    157212{
    158     asm volatile("mtc0      %0,     $12" ::"r" (val));
    159 }
    160 //////////////////////////////////////////////////////////////////////////////////
     213    asm volatile( "mtc0      %0,     $12    \n"
     214                  :
     215                  :"r" (val) );
     216}
     217//////////////////////////////////////////////////////////////////////////////
    161218// Returns processor index
    162 //////////////////////////////////////////////////////////////////////////////////
     219//////////////////////////////////////////////////////////////////////////////
    163220inline unsigned int _get_procid()
    164221{
    165222    unsigned int ret;
    166     asm volatile ("mfc0     %0,     $15, 1":"=r" (ret));
     223    asm volatile ( "mfc0     %0,     $15, 1  \n"
     224                   :"=r" (ret) );
    167225    return (ret & 0x3FF);
    168226}
    169 ///////////////////////////////////////////////////////////////////////////////////
     227//////////////////////////////////////////////////////////////////////////////
    170228// Returns local time (32 bits value)
    171229// boot_proctime()
    172 ///////////////////////////////////////////////////////////////////////////////////
     230//////////////////////////////////////////////////////////////////////////////
    173231inline unsigned int _get_proctime()
    174232{
    175233    unsigned int ret;
    176     asm volatile ("mfc0     %0,     $9":"=r" (ret));
     234    asm volatile ( "mfc0     %0,     $9      \n"
     235                   :"=r" (ret) );
    177236    return ret;
    178237}
    179 ///////////////////////////////////////////////////////////////////////////////////
    180 // Returns index of the currently running task from the sheduler.
    181 ///////////////////////////////////////////////////////////////////////////////////
    182 unsigned int _get_proc_task_id()
     238//////////////////////////////////////////////////////////////////////////////
     239// Returns index of the currently running task from the processor scheduler.
     240//////////////////////////////////////////////////////////////////////////////
     241unsigned int _get_current_task_id()
    183242{
    184243    static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
     
    186245}
    187246
    188 ///////////////////////////////////////////////////////////////////////////////////
    189 // Disables IRQs
    190 ///////////////////////////////////////////////////////////////////////////////////
    191 inline void _it_disable()
    192 {
    193     asm volatile(
    194             "li      $3,        0xFFFFFFFE    \n"
    195             "mfc0    $4,        $12           \n"
    196             "and     $3,        $3, $4        \n"
    197             "mtc0    $3,        $12           \n"
    198             ::: "$3", "$4");
    199 }
    200 ///////////////////////////////////////////////////////////////////////////////////
     247//////////////////////////////////////////////////////////////////////////////
     248// Save SR value into save_sr_ptr variable and disable IRQs.
     249//////////////////////////////////////////////////////////////////////////////
     250inline void _it_disable( unsigned int * save_sr_ptr)
     251{
     252    unsigned int sr;
     253    asm volatile( "li      $3,        0xFFFFFFFE    \n"
     254                  "mfc0    %0,        $12           \n"
     255                  "and     $3,        $3,   %0      \n" 
     256                  "mtc0    $3,        $12           \n"
     257                  : "=r"(sr)
     258                  :
     259                  : "$3" );
     260    *save_sr_ptr = sr;
     261}
     262//////////////////////////////////////////////////////////////////////////////
    201263// Enables IRQs
    202 ///////////////////////////////////////////////////////////////////////////////////
     264//////////////////////////////////////////////////////////////////////////////
    203265inline void _it_enable()
    204266{
    205     asm volatile(
    206             "li      $3,        0x00000001    \n"
    207             "mfc0    $4,        $12           \n"
    208             "or      $3,        $3, $4        \n"
    209             "mtc0    $3,        $12           \n"
    210             ::: "$3", "$4");
     267    asm volatile( "li      $3,        0x00000001    \n"
     268                  "mfc0    $4,        $12           \n"
     269                  "or      $3,        $3, $4        \n"
     270                  "mtc0    $3,        $12           \n" 
     271                  ::: "$3", "$4" );
     272}
     273
     274//////////////////////////////////////////////////////////////////////////////
     275// Restores previous SR value.
     276//////////////////////////////////////////////////////////////////////////////
     277inline void _it_restore( unsigned int * save_sr_ptr )
     278{
     279    unsigned int sr = *save_sr_ptr;
     280    asm volatile( "mtc0    %0,        $12           \n"
     281                  :
     282                  : "r"(sr) );
    211283}
    212284
     
    216288inline void _set_mmu_ptpr(unsigned int val)
    217289{
    218     asm volatile ("mtc2     %0,     $0"::"r" (val));
     290    asm volatile ( "mtc2     %0,     $0            \n"
     291                   :
     292                   :"r" (val) );
    219293}
    220294//////////////////////////////////////////////////////////////////////////////
     
    223297inline void _set_mmu_mode(unsigned int val)
    224298{
    225     asm volatile ("mtc2     %0,     $1"::"r" (val));
     299    asm volatile ( "mtc2     %0,     $1             \n"
     300                   :
     301                   :"r" (val) );
    226302}
    227303//////////////////////////////////////////////////////////////////////////////
     
    231307inline void _set_sched(unsigned int val)
    232308{
    233     asm volatile ("mtc0     %0,     $4, 2"::"r" (val));
     309    asm volatile ( "mtc0     %0,     $4, 2          \n"
     310                   :
     311                   :"r" (val) );
    234312}
    235313
     
    249327
    250328    asm volatile(
     329            "li     $3,     0xFFFFFFFE         \n"
     330            "mfc0   $2,     $12                \n"
     331            "and    $3,     $2,        $3      \n"
     332            "mtc0   $3,     $12                \n"     /* IRQ disabled     */
     333
    251334            "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE   */
    252335            "andi   $3,     $2,        0xb     \n"
     
    258341
    259342            "mtc2   $2,     $1                 \n"     /* restore MMU_MODE */
     343
     344            "li     $3,     0x00000001         \n"
     345            "mfc0   $2,     $12                \n"
     346            "or     $3,     $3,        $2      \n"
     347            "mtc0   $3,     $12                \n"     /* IRQ enabled      */
    260348            : "=r" (value)
    261349            : "r" (lsb), "r" (msb)
     
    268356////////////////////////////////////////////////////////////////////////////
    269357inline void _physical_write( unsigned long long paddr,
    270                       unsigned int       value )
     358                             unsigned int       value )
    271359{
    272360    unsigned int lsb = (unsigned int)paddr;
     
    274362
    275363    asm volatile(
     364            "li     $3,     0xFFFFFFFE         \n"
     365            "mfc0   $2,     $12                \n"
     366            "and    $3,     $2,        $3      \n"
     367            "mtc0   $3,     $12                \n"     /* IRQ disabled     */
     368
    276369            "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE   */
    277370            "andi   $3,     $2,        0xb     \n"
     
    283376
    284377            "mtc2   $2,     $1                 \n"     /* restore MMU_MODE */
     378
     379            "li     $3,     0x00000001         \n"
     380            "mfc0   $2,     $12                \n"
     381            "or     $3,     $3,        $2      \n"
     382            "mtc0   $3,     $12                \n"     /* IRQ enabled      */
    285383            :
    286384            : "r" (value), "r" (lsb), "r" (msb)
    287385            : "$2", "$3");
     386}
     387
     388///////////////////////////////////////////////////////////////////////////////////
     389// This function is used by all drivers (_xxx_set_register() function)
     390// If the MMU is not activated, the virtual address is extended using
     391// X_IO and Y_IO to reach the cluster_io.
     392///////////////////////////////////////////////////////////////////////////////////
     393inline void _io_extended_write( unsigned int*  vaddr,
     394                                unsigned int   value )
     395{
     396    unsigned long long paddr;
     397
     398    if ( _get_mmu_mode() & 0x4 )  // MMU activated : use virtual address
     399    {
     400        *vaddr = value;
     401    }
     402    else                          // use paddr extension for IO
     403    {
     404        paddr = (unsigned long long)(unsigned int)vaddr +
     405                (((unsigned long long)((X_IO<<Y_WIDTH) + Y_IO))<<32);
     406        _physical_write( paddr, value );
     407    }
     408    asm volatile("sync" ::: "memory");
     409}
     410
     411///////////////////////////////////////////////////////////////////////////////////
     412// This function is used by all drivers (_xxx_get_register() function)
     413// If the MMU is not activated, the virtual address is extended using
     414// X_IO and Y_IO to reach the cluster_io.
     415///////////////////////////////////////////////////////////////////////////////////
     416inline unsigned int _io_extended_read( unsigned int*  vaddr )
     417{
     418    unsigned long long paddr;
     419
     420    if ( _get_mmu_mode() & 0x4 )  // MMU activated : use virtual address
     421    {
     422        return *(volatile unsigned int*)vaddr;
     423    }
     424    else                          // use paddr extension for IO
     425    {
     426        paddr = (unsigned long long)(unsigned int)vaddr +
     427                (((unsigned long long)((X_IO<<Y_WIDTH) + Y_IO))<<32);
     428        return _physical_read( paddr );
     429    }
    288430}
    289431
     
    323465            :"$2", "$3", "$4");
    324466}
     467
    325468///////////////////////////////////////////////////////////////////////////////////
    326469// Release a previouly taken lock.
     
    328471inline void _release_lock(unsigned int * plock)
    329472{
    330     asm volatile ( "sync\n" ); // necessary because of the TSAR consistency model
     473    asm volatile ( "sync\n" ::: "memory" );
     474    // sync is necessary because of the TSAR consistency model
    331475    *plock = 0;
    332476}
    333477
    334478///////////////////////////////////////////////////////////////////////////////////
    335 // Display a string on TTY0 / used for system code debug and log.
    336 // It does not use the TTY driver, but uses the seg_tty_base variable...
    337 ///////////////////////////////////////////////////////////////////////////////////
    338 void _puts(char * buffer)
    339 {
    340     unsigned int n;
    341     for (n = 0; n < 1000; n++)
    342     {
    343         if (buffer[n] == 0)  break;
    344     }
    345     _tty_write( buffer, n, 0 );   // last argument is TTY channel
    346 }
    347 
    348 ///////////////////////////////////////////////////////////////////////////////////
    349479//           Access functions to system terminal TTY0
    350480///////////////////////////////////////////////////////////////////////////////////
    351481
    352482///////////////////////////////////////////////////////////////////////////////////
    353 // Display a 32 bits unsigned int as an hexadecimal string on TTY0
    354 ///////////////////////////////////////////////////////////////////////////////////
    355 void _putx(unsigned int val)
     483// Display "string" argument on TTY0.
     484// It uses the low level access functions from TTY driver, using a busy waiting
     485// policy if TTY buffer is full.
     486// The exclusive access lock should be taken by the caller.
     487///////////////////////////////////////////////////////////////////////////////////
     488void _puts( char* string )
     489{
     490    unsigned int n = 0;
     491
     492    while ( string[n] > 0 )
     493    {
     494        // test status register
     495        while ( (_tty_get_register( 0, TTY_STATUS ) & 0x2) );
     496
     497        // write one byte
     498        _tty_set_register( 0, TTY_WRITE, (unsigned int)string[n] );
     499        n++;
     500    }
     501}
     502
     503///////////////////////////////////////////////////////////////////////////////////
     504// Display a 32 bits unsigned int as an hexadecimal string on TTY0.
     505///////////////////////////////////////////////////////////////////////////////////
     506void _putx( unsigned int val )
    356507{
    357508    static const char HexaTab[] = "0123456789ABCDEF";
     
    368519        val = val >> 4;
    369520    }
    370     _puts(buf);
    371 }
    372 
    373 ///////////////////////////////////////////////////////////////////////////////////
    374 // Display a 64 bits unsigned long as an hexadecimal string on TTY0 
    375 ///////////////////////////////////////////////////////////////////////////////////
    376 void _putl(unsigned long long val)
     521    _puts( buf );
     522}
     523
     524///////////////////////////////////////////////////////////////////////////////////
     525// Display a 64 bits unsigned long as an hexadecimal string on TTY0.
     526///////////////////////////////////////////////////////////////////////////////////
     527void _putl( unsigned long long val )
    377528{
    378529    static const char HexaTab[] = "0123456789ABCDEF";
     
    389540        val = val >> 4;
    390541    }
    391     _puts(buf);
    392 }
    393 
    394 ///////////////////////////////////////////////////////////////////////////////////
    395 // Display a 32 bits unsigned int as a decimal string on TTY0
    396 ///////////////////////////////////////////////////////////////////////////////////
    397 void _putd(unsigned int val)
     542    _puts( buf );
     543}
     544
     545///////////////////////////////////////////////////////////////////////////////////
     546// Display a 32 bits unsigned int as a decimal string on TTY0.
     547///////////////////////////////////////////////////////////////////////////////////
     548void _putd( unsigned int val )
    398549{
    399550    static const char DecTab[] = "0123456789";
     
    414565        val /= 10;
    415566    }
    416     _puts(&buf[first]);
     567    _puts( &buf[first] );
     568}
     569
     570///////////////////////////////////////////////////////////////////////////////////
     571// Display a format on TTY0.
     572// To provide an atomic display, this function takes the lock protecting
     573// exclusive access to TTY0, entering a critical section until the lock
     574// is released.
     575// Only a limited number of formats are supported:
     576//   - %d : 32 bits signed   decimal
     577//   - %u : 32 bits unsigned decimal
     578//   - %x : 32 bits unsigned hexa
     579//   - %l : 64 bits unsigned hexa
     580//   - %c : char
     581//   - %s : string
     582///////////////////////////////////////////////////////////////////////////////////
     583void _printf( char * format, ... )
     584{
     585    va_list ap;
     586    va_start(ap, format);
     587    unsigned int save_sr;     // used to save the SR value in critical section
     588
     589    // get TTY0 lock
     590    _tty_get_lock( 0, &save_sr );
     591
     592printf_text:
     593
     594    while (*format)
     595    {
     596        unsigned int i;
     597        for (i = 0 ; format[i] && (format[i] != '%') ; i++);
     598        if (i)
     599        {
     600            if ( _tty_write( format, i, 0 ) != i ) goto return_error;
     601            format += i;
     602        }
     603        if (*format == '%')
     604        {
     605            format++;
     606            goto printf_arguments;
     607        }
     608    }
     609
     610    // release TTY0 lock
     611    _tty_release_lock( 0, &save_sr );
     612
     613    va_end(ap);
     614    return;
     615
     616printf_arguments:
     617
     618    {
     619        char buf[20];
     620        char * pbuf;
     621        unsigned int len = 0;
     622        static const char HexaTab[] = "0123456789ABCDEF";
     623        unsigned int i;
     624
     625        switch (*format++)
     626        {
     627            case ('c'):             /* char conversion */
     628            {
     629                int val = va_arg( ap, int );
     630                len = 1;
     631                buf[0] = val;
     632                pbuf = &buf[0];
     633                break;
     634            }
     635            case ('d'):             /* 32 bits decimal signed  */
     636            {
     637                int val = va_arg( ap, int );
     638                if (val < 0)
     639                {
     640                    val = -val;
     641                    if ( _tty_write( "-" , 1, 0 ) != 1 ) goto return_error;
     642                }
     643                for(i = 0; i < 10; i++)
     644                {
     645                    buf[9 - i] = HexaTab[val % 10];
     646                    if (!(val /= 10)) break;
     647                }
     648                len =  i + 1;
     649                pbuf = &buf[9 - i];
     650                break;
     651            }
     652            case ('u'):             /* 32 bits decimal unsigned  */
     653            {
     654                unsigned int val = va_arg( ap, unsigned int );
     655                for(i = 0; i < 10; i++)
     656                {
     657                    buf[9 - i] = HexaTab[val % 10];
     658                    if (!(val /= 10)) break;
     659                }
     660                len =  i + 1;
     661                pbuf = &buf[9 - i];
     662                break;
     663            }
     664            case ('x'):             /* 32 bits hexadecimal unsigned */
     665            {
     666                unsigned int val = va_arg( ap, unsigned int );
     667                if ( _tty_write( "0x" , 2, 0 ) != 2 ) goto return_error;
     668                for(i = 0; i < 8; i++)
     669                {
     670                    buf[7 - i] = HexaTab[val % 16];
     671                    if (!(val /= 16))  break;
     672                }
     673                len =  i + 1;
     674                pbuf = &buf[7 - i];
     675                break;
     676            }
     677            case ('l'):            /* 64 bits hexadecimal unsigned */
     678            {
     679                unsigned long long val = va_arg( ap, unsigned long long );
     680                if ( _tty_write( "0x" , 2, 0 ) != 2 ) goto return_error;
     681                for(i = 0; i < 16; i++)
     682                {
     683                    buf[15 - i] = HexaTab[val % 16];
     684                    if (!(val /= 16))  break;
     685                }
     686                len =  i + 1;
     687                pbuf = &buf[15 - i];
     688                break;
     689            }
     690            case ('s'):             /* string */
     691            {
     692                char* str = va_arg( ap, char* );
     693                while (str[len])
     694                {
     695                    len++;
     696                }
     697                pbuf = str;
     698                break;
     699            }
     700            default:
     701                goto return_error;
     702        }
     703
     704        if ( _tty_write( pbuf, len, 0 ) != len ) goto return_error;
     705       
     706        goto printf_text;
     707    }
     708
     709return_error:
     710
     711    {
     712        unsigned int procid     = _get_procid();
     713        unsigned int lpid       = procid % NB_PROCS_MAX;
     714        unsigned int cluster_xy = procid / NB_PROCS_MAX;
     715        unsigned int x          = cluster_xy >> Y_WIDTH;
     716        unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
     717
     718        _puts("\n\n[GIET ERROR] in _printf() for processor[");
     719        _putd( x );
     720        _puts(",");
     721        _putd( y );
     722        _puts(",");
     723        _putd( lpid );
     724        _puts("]\n");
     725
     726        // release TTY0 lock
     727        _tty_release_lock( 0, &save_sr );
     728
     729        _exit();
     730    }
     731}
     732
     733///////////////////////////////////////////////////////////////////////////////////
     734// Get a character from TTY0.
     735///////////////////////////////////////////////////////////////////////////////////
     736void _getc( char*        byte )
     737{
     738    // test status register
     739    while ( _tty_get_register( 0, TTY_STATUS ) == 0 );
     740
     741    // read one byte
     742    *byte = (char)_tty_get_register( 0, TTY_READ );
    417743}
    418744
     
    452778// register, to be more processor independant.
    453779///////////////////////////////////////////////////////////////////////////////////
    454 void _dcache_buf_invalidate( const void * buffer,
     780void _dcache_buf_invalidate( void * buffer,
    455781                             unsigned int size)
    456782{
  • soft/giet_vm/giet_common/utils.h

    r268 r295  
    2323typedef struct _ld_symbol_s _ld_symbol_t;
    2424
    25 // peripheral base addresses
     25// non replicated peripherals
    2626extern _ld_symbol_t seg_iob_base;
    2727extern _ld_symbol_t seg_nic_base;
     28extern _ld_symbol_t seg_cma_base;
     29extern _ld_symbol_t seg_tty_base;
     30extern _ld_symbol_t seg_fbf_base;
     31extern _ld_symbol_t seg_pic_base;
     32extern _ld_symbol_t seg_ioc_base;
     33extern _ld_symbol_t seg_sim_base;
     34
     35// replicated peripherals
    2836extern _ld_symbol_t seg_icu_base;
    2937extern _ld_symbol_t seg_xcu_base;
    3038extern _ld_symbol_t seg_tim_base;
    31 extern _ld_symbol_t seg_tty_base;
    32 extern _ld_symbol_t seg_gcd_base;
    3339extern _ld_symbol_t seg_dma_base;
    34 extern _ld_symbol_t seg_fbf_base;
    35 extern _ld_symbol_t seg_ioc_base;
    3640extern _ld_symbol_t seg_mmc_base;
    37 extern _ld_symbol_t seg_cma_base;
    38 extern _ld_symbol_t seg_hba_base;
    39 extern _ld_symbol_t seg_sim_base;
    4041
    4142// for replicated peripherals
     
    7071extern _ld_symbol_t seg_kernel_init_size;
    7172
    72 
     73extern _ld_symbol_t seg_ram_disk_base;
     74extern _ld_symbol_t seg_ram_disk_size;
     75
     76extern _ld_symbol_t seg_reset_code_base;
     77extern _ld_symbol_t seg_reset_code_size;
    7378
    7479///////////////////////////////////////////////////////////////////////////////////
     
    8590
    8691///////////////////////////////////////////////////////////////////////////////////
     92//     Break function
     93///////////////////////////////////////////////////////////////////////////////////
     94
     95extern void _break( char* str);
     96
     97///////////////////////////////////////////////////////////////////////////////////
    8798//     Suicide function
    8899///////////////////////////////////////////////////////////////////////////////////
     
    102113extern unsigned int _get_sched(void);
    103114extern unsigned int _get_mmu_ptpr(void);
     115extern unsigned int _get_mmu_mode(void);
    104116extern unsigned int _get_epc(void);
    105117extern unsigned int _get_bvar(void);
     
    108120extern unsigned int _get_procid(void);
    109121extern unsigned int _get_proctime(void);
    110 extern unsigned int _get_proc_task_id(void);
    111 
    112 extern void         _it_disable(void);
     122extern unsigned int _get_current_task_id(void);
     123
     124extern void         _it_disable( unsigned int* save_sr_ptr );
    113125extern void         _it_enable(void);
     126extern void         _it_restore( unsigned int* save_sr_ptr );
    114127
    115128extern void         _set_mmu_ptpr(unsigned int value);
     
    127140                                     unsigned int       value );
    128141
     142extern unsigned int _io_extended_read(  unsigned int* vaddr );
     143
     144extern void         _io_extended_write( unsigned int* vaddr,
     145                                        unsigned int  value );
     146
    129147///////////////////////////////////////////////////////////////////////////////////
    130148//     Locks access functions
     
    135153
    136154///////////////////////////////////////////////////////////////////////////////////
    137 //     Display functions
    138 ///////////////////////////////////////////////////////////////////////////////////
    139 
    140 extern void         _puts(char *string);             // display a string
    141 extern void         _putx(unsigned int val);         // display a 32 bits value (hexa)
    142 extern void         _putd(unsigned int val);         // display a 32 bits value (dec)
    143 extern void         _putl(unsigned long long val);   // display a 64 bits value (hexa)
     155//     TTY0 access functions
     156///////////////////////////////////////////////////////////////////////////////////
     157
     158extern void         _puts( char*        string );
     159
     160extern void         _putx( unsigned int val );
     161
     162extern void         _putd( unsigned int val );
     163
     164extern void         _putl( unsigned long long val );
     165
     166extern void         _printf(char* format, ...);
     167
     168extern void         _getc( char*        byte );       
    144169
    145170///////////////////////////////////////////////////////////////////////////////////
     
    158183///////////////////////////////////////////////////////////////////////////////////
    159184
    160 extern void  _dcache_buf_invalidate( const void * buffer,
     185extern void  _dcache_buf_invalidate( void * buffer,
    161186                                     unsigned int size );
    162187
  • soft/giet_vm/giet_common/vmem.c

    r258 r295  
    2525// _iommu_add_pte2()
    2626//////////////////////////////////////////////////////////////////////////////
    27 void _iommu_add_pte2(
    28         unsigned int ix1,
    29         unsigned int ix2,
    30         unsigned int ppn,
    31         unsigned int flags)
     27void _iommu_add_pte2( unsigned int ix1,
     28                      unsigned int ix2,
     29                      unsigned int ppn,
     30                      unsigned int flags )
    3231{
    3332    unsigned int ptba;
     
    4140    if ((pt->pt1[ix1] & PTE_V) == 0)
    4241    {
    43         _tty_get_lock( 0 );
    44         _puts("\n[GIET ERROR] in iommu_add_pte2 function\n");
    45         _puts("the IOMMU PT1 entry is not mapped / ix1 = ");
    46         _putx( ix1 );
    47         _puts("\n");
    48         _tty_release_lock( 0 );
     42        _printf("\n[GIET ERROR] in iommu_add_pte2() : "
     43                "IOMMU PT1 entry not mapped / ix1 = %d\n", ix1 );
    4944        _exit();
    5045    }
     
    6358// _iommu_inval_pte2()
    6459//////////////////////////////////////////////////////////////////////////////
    65 void _iommu_inval_pte2(unsigned int ix1, unsigned int ix2) {
     60void _iommu_inval_pte2( unsigned int ix1,
     61                        unsigned int ix2 )
     62{
    6663    unsigned int ptba;
    6764    unsigned int * pt_flags;
     
    7370    if ((pt->pt1[ix1] & PTE_V) == 0)
    7471    {
    75         _puts("\n[GIET ERROR] in iommu_inval_pte2 function\n");
    76         _puts("the IOMMU PT1 entry is not mapped / ix1 = ");
    77         _putx( ix1 );
    78         _puts("\n");
     72        _printf("\n[GIET ERROR] in iommu_inval_pte2() "
     73              "IOMMU PT1 entry not mapped / ix1 = %d\n", ix1 );
    7974        _exit();
    8075    }
     
    9590                             unsigned int   vpn,
    9691                             unsigned int*  ppn,
    97                              unsigned int*  flags)
     92                             unsigned int*  flags )
    9893{
    9994    unsigned long long ptba;
  • soft/giet_vm/giet_config.h

    r289 r295  
    2323
    2424#define GIET_DEBUG_INIT              0                  /* trace parallel kernel initialisation */
    25 
    2625#define GIET_DEBUG_FAT           0          /* trace fat accesses */
    27 #define GIET_DEBUG_SWITCH            0                  /* trace context switchs  */
     26#define GIET_DEBUG_SWITCH            0          /* trace context switchs  */
     27#define GIET_DEBUG_IRQS          0              /* trace interrupts */
    2828#define GIET_DEBUG_IOC_DRIVER    0          /* trace IOC accesses */
     29#define GIET_DEBUG_BDV_DRIVER    0          /* trace BDV accesses */
     30#define GIET_DEBUG_TTY_DRIVER    0          /* trace TTY accesses */
    2931#define GIET_DEBUG_DMA_DRIVER    0          /* trace DMA accesses */
    3032#define GIET_DEBUG_FBF_DRIVER    0          /* trace FBF accesses */
     
    3436/* software parameters */
    3537
    36 #define GIET_IDLE_TASK_PERIOD    10000000   /* Idle Task message period */
    37 #define GIET_IDLE_TASK_VERBOSITY 1
    38 
     38#define GIET_IDLE_TASK_PERIOD    0xFFFFFFFF /* Idle Task message period */
    3939#define GIET_MAX_ELF_FILES       20         /* max .elf files loaded by boot-loader */
    4040#define GIET_OPEN_FILES_MAX      16         /* max simultaneously open files */
    4141#define GIET_NB_VSPACE_MAX           64                 /* max number of virtual spaces */
    42 #define GIET_TICK_VALUE          100000         /* context switch period (number of cycles) */
     42#define GIET_TICK_VALUE          0x8000     /* context switch period (number of cycles) */
    4343#define GIET_USE_IOMMU           0          /* IOMMU activated when non zero */
    4444#define GIET_NO_HARD_CC          0          /* No hard cache coherence when non zero */
  • soft/giet_vm/giet_drivers/bdv_driver.c

    r289 r295  
    1010// a single channel, block oriented, external storage contrÃŽler.
    1111//
    12 // It can exist only one block-device controler in the architecture.
    13 //
    14 // The _bdv_read() and _bdv_write() functions use the _bdv_access() function,
    15 // that is always blocking, but can be called in 4 modes:
    16 //
    17 // - In BOOT_PA mode, the _bdv_access() function uses a polling policy on the
    18 //   IOC_STATUS register to detect transfer completion, as hardware interrupts
    19 //   are not activated. This mode is used by the boot code to load the map.bin
    20 //   file into memory.
    21 //
    22 // - In BOOT_VA mode, the _bdv_access() function uses a polling policy on
    23 //   IOC_STATUS register to detect transfer completion. This mode is used by
    24 //   the boot code to load the various .elf files into memory.
    25 //
    26 // - In KERNEL mode, the _bdv_access() function uses a descheduling strategy:
     12// The _bdv_read() and _bdv_write() functions are always blocking.
     13// They can be called in 3 modes:
     14//
     15// - In BOOT mode, these functions use a polling policy on the BDV STATUS
     16//   register to detect transfer completion, as interrupts are not activated.
     17//   This mode is used by the boot code to load the map.bin file into memory
     18//   (before MMU activation), or to load the .elf files (after MMU activation).
     19//
     20// - In KERNEL mode, these functions use a descheduling strategy:
    2721//   The ISR executed when transfer completes should restart the calling task.
    28 //   There is no checking of user access right to the memory buffer. This mode
    29 //   must be used to access IOC, for an "open" system call.
    30 //
    31 // - In USER mode, the _bdv_access() function uses a descheduling strategy:
     22//   There is no checking of user access right to the memory buffer.
     23//   This mode must be used, for an "open" system call.
     24//
     25// - In USER mode, these functions use a descheduling strategy:
    3226//   The ISR executed when transfer completes should restart the calling task,
    3327//   The user access right to the memory buffer must be checked.
    34 //   This mode must be used to access IOC, for a "read/write" system call.
     28//   This mode must be used for a "read/write" system call.
    3529//
    3630// As the BDV component can be used by several programs running in parallel,
    37 // the _ioc_lock variable guaranties exclusive access to the device.  The
     31// the _bdv_lock variable guaranties exclusive access to the device.  The
    3832// _bdv_read() and _bdv_write() functions use atomic LL/SC to get the lock.
    3933//
     
    4741//   if the IOMMU is not activated.
    4842// An error code is returned if these conditions are not verified.
    49 ///////////////////////////////////////////////////////////////////////////////////
    50 // The seg_ioc_base virtual base addresses must be defined in giet_vsegs.ld file.
     43//
     44// The "seg_ioc_base" must be defined in giet_vsegs.ld file.
     45///////////////////////////////////////////////////////////////////////////////////
     46// Implementation notes:
     47//
     48// 1. In order to share code, the two _bdv_read() and _bdv_write() functions
     49//    call the same _bdv_access() function.
     50//
     51// 2. All accesses to BDV registers are done by the two
     52//    _bdv_set_register() and _bdv_get_register() low-level functions,
     53//    that are handling virtual / physical extended addressing.
    5154///////////////////////////////////////////////////////////////////////////////////
    5255
    5356#include <giet_config.h>
     57#include <bdv_driver.h>
     58#include <xcu_driver.h>
    5459#include <ioc_driver.h>
    55 #include <bdv_driver.h>
    5660#include <utils.h>
    5761#include <tty_driver.h>
     
    5963
    6064///////////////////////////////////////////////////////////////////////////////
    61 //      _bdv_access()
     65// BDV global variables
     66///////////////////////////////////////////////////////////////////////////////
     67
     68#define in_unckdata __attribute__((section (".unckdata")))
     69
     70in_unckdata unsigned int          _bdv_lock = 0;
     71in_unckdata volatile unsigned int _bdv_status = 0;
     72in_unckdata volatile unsigned int _bdv_gtid;
     73
     74///////////////////////////////////////////////////////////////////////////////
     75// This low_level function returns the value contained in register (index).
     76///////////////////////////////////////////////////////////////////////////////
     77unsigned int _bdv_get_register( unsigned int index )
     78{
     79    unsigned int* vaddr = (unsigned int*)&seg_ioc_base + index;
     80    return _io_extended_read( vaddr );
     81}
     82
     83///////////////////////////////////////////////////////////////////////////////
     84// This low-level function set a new value in register (index).
     85///////////////////////////////////////////////////////////////////////////////
     86void _bdv_set_register( unsigned int index,
     87                        unsigned int value )
     88{
     89    unsigned int* vaddr = (unsigned int*)&seg_ioc_base + index;
     90    _io_extended_write( vaddr, value );
     91}
     92
     93///////////////////////////////////////////////////////////////////////////////
    6294// This function transfer data between a memory buffer and the block device.
    6395// The buffer lentgth is (count*block_size) bytes.
     
    70102// Returns 0 if success, > 0 if error.
    71103///////////////////////////////////////////////////////////////////////////////
    72 static unsigned int _bdv_access( unsigned int to_mem,
    73                                  unsigned int mode,
    74                                  unsigned int lba,
    75                                  paddr_t buf_paddr,
    76                                  unsigned int count)
    77 {
    78 
    79 #if GIET_DEBUG_IOC_DRIVER
    80 _tty_get_lock( 0 );
    81 _puts("\n[IOC DEBUG] Enter _bdv_access() at cycle ");
    82 _putd( _get_proctime() );
    83 _puts(" for processor ");
    84 _putd( _get_procid() );
    85 _puts("\n - mode    = ");
    86 _putd( mode );
    87 _puts("\n - paddr   = ");
    88 _putx( buf_paddr );
    89 _puts("\n - sectors = ");
    90 _putd( count );
    91 _puts("\n - lba     = ");
    92 _putx( lba );
    93 _puts("\n");
    94 _tty_release_lock( 0 );
     104static unsigned int _bdv_access( unsigned int       to_mem,
     105                                 unsigned int       mode,
     106                                 unsigned int       lba,
     107                                 unsigned long long buf_paddr,
     108                                 unsigned int       count)
     109{
     110
     111#if GIET_DEBUG_BDV_DRIVER
     112unsigned int procid  = _get_procid();
     113unsigned int cxy     = procid / NB_PROCS_MAX;
     114unsigned int lpid    = procid % NB_PROCS_MAX;
     115unsigned int x       = cxy >> Y_WIDTH;
     116unsigned int y       = cxy & ((1<<Y_WIDTH) - 1);
     117
     118_printf("\n[BDV DEBUG] Processor[%d,%d,%d] enters _bdv_access() at cycle %d\n"
     119        " - mode    = %d\n"
     120        " - paddr   = %l\n"
     121        " - sectors = %x\n"
     122        " - lba     = %x\n",
     123        x, y, lpid, _get_proctime(), mode, buf_paddr, count, lba );
    95124#endif
    96125
    97     volatile unsigned int * ioc_address = (unsigned int *) &seg_ioc_base ;
    98     unsigned int error = 0;
    99 
    100     // get the lock protecting IOC
    101     _get_lock(&_ioc_lock);
    102 
    103     // set the _ioc_status polling variable
    104     _ioc_status = BLOCK_DEVICE_BUSY;
    105 
    106     ioc_address[BLOCK_DEVICE_BUFFER]     = (unsigned int)buf_paddr;
    107     ioc_address[BLOCK_DEVICE_BUFFER_EXT] = (unsigned int)(buf_paddr>>32);
    108     ioc_address[BLOCK_DEVICE_COUNT]      = count;
    109     ioc_address[BLOCK_DEVICE_LBA]        = lba;
    110 
    111     // There are two policies for transfer completion
    112         // detection, depending on the mode argument:
    113 
    114     if ( (mode == IOC_BOOT_PA_MODE) ||    // We poll directly the IOC_STATUS register
    115          (mode == IOC_BOOT_VA_MODE) )     // as IRQs are masked.
     126    unsigned int       error = 0;
     127
     128    // get the lock protecting BDV
     129    _get_lock(&_bdv_lock);
     130
     131    // set device registers
     132    _bdv_set_register( BLOCK_DEVICE_BUFFER    , (unsigned int)buf_paddr );
     133    _bdv_set_register( BLOCK_DEVICE_BUFFER_EXT, (unsigned int)(buf_paddr>>32) );
     134    _bdv_set_register( BLOCK_DEVICE_COUNT     , count );
     135    _bdv_set_register( BLOCK_DEVICE_LBA       , lba );
     136
     137    // In BOOT mode, we launch transfer, and poll the BDV_STATUS
     138    // register because IRQs are masked.
     139    if ( mode == IOC_BOOT_MODE )
    116140    {
    117141        // Launch transfert
    118         if (to_mem == 0) ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_WRITE;
    119         else             ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_READ;
     142        if (to_mem == 0) _bdv_set_register( BLOCK_DEVICE_OP, BLOCK_DEVICE_WRITE );
     143        else             _bdv_set_register( BLOCK_DEVICE_OP, BLOCK_DEVICE_READ );
    120144
    121145        unsigned int status;
    122146        do
    123147        {
    124             if ( _bdv_get_status( 0, &status ) ) return 1;
    125 
    126 #if GIET_DEBUG_IOC_DRIVER
    127 _tty_get_lock( 0 );
    128 _puts("\n[IOC DEBUG] _bdv_access() : ... waiting on IOC_STATUS register ...\n");
    129 _tty_release_lock( 0 );
     148            status = _bdv_get_register( BLOCK_DEVICE_STATUS );
     149
     150#if GIET_DEBUG_BDV_DRIVER
     151_printf("\n[BDV DEBUG] _bdv_access() : ... waiting on BDV_STATUS register ...\n");
    130152#endif
    131153        }
     
    133155               (status != BLOCK_DEVICE_READ_ERROR)    &&
    134156               (status != BLOCK_DEVICE_WRITE_SUCCESS) &&
    135                (status != BLOCK_DEVICE_WRITE_ERROR)   );
     157               (status != BLOCK_DEVICE_WRITE_ERROR)   );      // busy waiting
    136158
    137159        // analyse status
     
    140162
    141163        // release lock
    142         _release_lock(&_ioc_lock);     
     164        _release_lock(&_bdv_lock);     
    143165    }
    144     else                           // in USER or KERNEL mode, we deschedule the task.
    145                                    // When the task is rescheduled by the ISR, we reset
    146                                    // the _ioc_status variable, and release the lock
     166    // in USER or KERNEL mode, we deschedule the task.
     167    // When the task is rescheduled, we check the _bdv_status variable,
     168    // and release the lock.
     169    // We need a critical section, because we must reset the RUN bit
     170        // before to launch the transfer, and we don't want to be descheduled
     171        // between these two operations.
     172    else
    147173    {
    148         // We need a critical section, because we must reset the RUN bit
    149                 // before to launch the transfer, and we want to avoid to be descheduled
    150                 // between these two operations.
    151 
    152         // Enter critical section
    153         _it_disable();
     174        unsigned int save_sr;
     175        unsigned int ltid = _get_current_task_id();
     176        unsigned int gpid = _get_procid();
     177
     178        // activates BDV interrupts
     179        _bdv_set_register( BLOCK_DEVICE_IRQ_ENABLE, 1 );
     180
     181        // set the _bdv_status variable
     182        _bdv_status = BLOCK_DEVICE_BUSY;
     183
     184        // enters critical section
     185        _it_disable( &save_sr );
    154186       
    155         // set _ioc_gtid and reset runnable
    156         unsigned int ltid = _get_proc_task_id();
    157         unsigned int pid = _get_procid();
    158         _ioc_gtid = (pid<<16) + ltid;
    159         _set_task_slot( pid, ltid, CTX_RUN_ID, 0 ); 
     187        // set _bdv_gtid and reset runnable
     188        _bdv_gtid = (gpid<<16) + ltid;
     189        _set_task_slot( gpid, ltid, CTX_RUN_ID, 0 ); 
    160190       
    161         // Launch transfert
    162         if (to_mem == 0) ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_WRITE;
    163         else             ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_READ;
     191        // launch transfer
     192        if (to_mem == 0) _bdv_set_register( BLOCK_DEVICE_OP, BLOCK_DEVICE_WRITE );
     193        else             _bdv_set_register( BLOCK_DEVICE_OP, BLOCK_DEVICE_READ  );
    164194
    165195        // deschedule task
    166196        _ctx_switch();                     
    167197
     198        // restore SR
     199        _it_restore( &save_sr );
     200
    168201        // analyse status
    169         error = ( (_ioc_status == BLOCK_DEVICE_READ_ERROR) ||
    170                   (_ioc_status == BLOCK_DEVICE_WRITE_ERROR) );
    171 
    172         // reset _ioc_status and release lock
    173         _ioc_status = BLOCK_DEVICE_IDLE;
    174         _release_lock(&_ioc_lock);     
     202        error = ( (_bdv_status == BLOCK_DEVICE_READ_ERROR) ||
     203                  (_bdv_status == BLOCK_DEVICE_WRITE_ERROR) );
     204
     205        // reset _bdv_status and release lock
     206        _bdv_status = BLOCK_DEVICE_IDLE;
     207        _release_lock(&_bdv_lock);     
    175208    }
    176209
    177 #if GIET_DEBUG_IOC_DRIVER
    178 _tty_get_lock( 0 );
    179 _puts("\n[IOC DEBUG] _bdv_access completed at cycle ");
    180 _putd( _get_proctime() );
    181 _puts(" for processor ");
    182 _putd( _get_procid() );
    183 _puts(" : error = ");
    184 _putd( (unsigned int)error );
    185 _puts("\n");
    186 _tty_release_lock( 0 );
     210#if GIET_DEBUG_BDV_DRIVER
     211_printf("\n[BDV DEBUG] Processor[%d,%d,%d] exit _bdv_access() at cycle %d\n",
     212        x, y, lpid, _get_proctime() );
    187213#endif
    188214
     
    191217
    192218///////////////////////////////////////////////////////////////////////////////
    193 //       _bdv_init()
    194 // This function cheks block size, and activates the IOC interrupts.
     219// This function cheks block size, and desactivates the interrupts.
    195220// Return 0 for success, > 0 if error
    196221///////////////////////////////////////////////////////////////////////////////
    197 unsigned int _bdv_init( unsigned int channel )
    198 {
    199     volatile unsigned int * ioc_address = (unsigned int *) &seg_ioc_base ;
    200    
    201     if ( ioc_address[BLOCK_DEVICE_BLOCK_SIZE] != 512 )
     222unsigned int _bdv_init()
     223{
     224    if ( _bdv_get_register( BLOCK_DEVICE_BLOCK_SIZE ) != 512 )
    202225    {
    203         _tty_get_lock( 0 );
    204         _puts("\n[GIET ERROR] in _bdv_init() : block size must be 512 bytes\n");
    205         _tty_release_lock( 0 );
     226        _printf("\n[GIET ERROR] in _bdv_init() : block size must be 512 bytes\n");
    206227        return 1;
    207228    }
    208229
    209     if ( channel != 0 )
    210     {
    211         _tty_get_lock( 0 );
    212         _puts("\n[GIET ERROR] in _bdv_init() : illegal channel\n");
    213         _tty_release_lock( 0 );
    214 
    215         return 1;
    216     }
    217 
    218     ioc_address[BLOCK_DEVICE_IRQ_ENABLE] = 1;
     230    _bdv_set_register( BLOCK_DEVICE_IRQ_ENABLE, 0 );
    219231    return 0;
    220232}
    221233
    222234///////////////////////////////////////////////////////////////////////////////
    223 //     _bdv_read()
    224235// Transfer data from the block device to a memory buffer.
    225236// - mode     : BOOT / KERNEL / USER
     
    229240// Returns 0 if success, > 0 if error.
    230241///////////////////////////////////////////////////////////////////////////////
    231 unsigned int _bdv_read( unsigned int mode, 
    232                         unsigned int lba,
    233                         paddr_t      buffer,
    234                         unsigned int count)
     242unsigned int _bdv_read( unsigned int       mode, 
     243                        unsigned int       lba,
     244                        unsigned long long buffer,
     245                        unsigned int       count)
    235246{
    236247    return _bdv_access( 1,        // read access
     
    242253
    243254///////////////////////////////////////////////////////////////////////////////
    244 //     _bdv_write()
    245255// Transfer data from a memory buffer to the block device.
    246256// - mode     : BOOT / KERNEL / USER
     
    250260// Returns 0 if success, > 0 if error.
    251261///////////////////////////////////////////////////////////////////////////////
    252 unsigned int _bdv_write( unsigned int mode, 
    253                          unsigned int lba,
    254                          paddr_t buffer,
    255                          unsigned int count )
     262unsigned int _bdv_write( unsigned int       mode, 
     263                         unsigned int       lba,
     264                         unsigned long long buffer,
     265                         unsigned int       count )
    256266{
    257267    return _bdv_access( 0,        // write access
     
    263273
    264274///////////////////////////////////////////////////////////////////////////////
    265 //     _bdv_get_status()
    266 // This function returns in the status variable, the transfert status, and
    267 // acknowledge the IRQ if the IOC controler is not busy.
    268 // Returns 0 if success, > 0 if error
    269 ///////////////////////////////////////////////////////////////////////////////
    270 unsigned int _bdv_get_status( unsigned int  channel,
    271                               unsigned int* status )
    272 {
    273     if ( channel != 0 )
    274     {
    275         _tty_get_lock( 0 );
    276         _puts("\n[GIET ERROR] in _bdv_get_status() : illegal channel\n");
    277         _tty_release_lock( 0 );
    278 
    279         return 1;
    280     }
    281 
    282     // get IOC base address
    283     volatile unsigned int * ioc_address = (unsigned int *) &seg_ioc_base;
    284     *status = ioc_address[BLOCK_DEVICE_STATUS];
    285 
    286     return 0;
    287 }
    288 
    289 ///////////////////////////////////////////////////////////////////////////////
    290 //     _bdv_get_block_size()
    291 // This function returns the block_size with which the IOC has been configured.
    292 ///////////////////////////////////////////////////////////////////////////////
    293 unsigned int _bdv_get_block_size()
    294 {
    295     // get IOC base address
    296     volatile unsigned int * ioc_address = (unsigned int *) &seg_ioc_base;
    297    
    298     return  ioc_address[BLOCK_DEVICE_BLOCK_SIZE];
     275// Returns device status.
     276///////////////////////////////////////////////////////////////////////////////
     277unsigned int _bdv_get_status()
     278{
     279    return _bdv_get_register( BLOCK_DEVICE_STATUS );
     280}
     281
     282///////////////////////////////////////////////////////////////////////////////
     283// Returns block size.
     284///////////////////////////////////////////////////////////////////////////////
     285unsigned int _bdv_get_block_size()
     286{
     287    return _bdv_get_register( BLOCK_DEVICE_BLOCK_SIZE );
     288}
     289
     290///////////////////////////////////////////////////////////////////////////////////
     291// This ISR save the status, acknowledge the IRQ,
     292// and activates the task waiting on IO transfer.
     293// It can be an HWI or a SWI.
     294//
     295// TODO the _set_task_slot access should be replaced by an atomic LL/SC
     296//      when the CTX_RUN bool will be replaced by a bit_vector.
     297///////////////////////////////////////////////////////////////////////////////////
     298void _bdv_isr( unsigned int irq_type,   // HWI / WTI
     299               unsigned int irq_id,     // index returned by ICU
     300               unsigned int channel )   // unused
     301{
     302    unsigned int procid     = _get_procid();
     303    unsigned int cluster_xy = procid / NB_PROCS_MAX;
     304    unsigned int lpid       = procid % NB_PROCS_MAX;
     305
     306    // acknowledge WTI in local XCU if required
     307    unsigned int value;
     308    if ( irq_type == IRQ_TYPE_WTI ) _xcu_get_wti_value( cluster_xy, irq_id, &value );
     309
     310    // save status in _bdv_status variable and reset IRQ
     311    _bdv_status = _bdv_get_register( BLOCK_DEVICE_STATUS );
     312
     313    // identify task waiting on BDV
     314    unsigned int rprocid    = _bdv_gtid>>16;
     315    unsigned int ltid       = _bdv_gtid & 0xFFFF;
     316    unsigned int remote_xy  = rprocid / NB_PROCS_MAX;
     317
     318#if GIET_DEBUG_IRQS  // we don't take the TTY lock to avoid deadlock
     319unsigned int x              = cluster_xy >> Y_WIDTH;
     320unsigned int y              = cluster_xy & ((1<<Y_WIDTH)-1);
     321unsigned int rx             = remote_xy >> Y_WIDTH;
     322unsigned int ry             = remote_xy & ((1<<Y_WIDTH)-1);
     323unsigned int rlpid          = rprocid % NB_PROCS_MAX;
     324_puts("\n[IRQS DEBUG] Processor[");
     325_putd(x );
     326_puts(",");
     327_putd(y );
     328_puts(",");
     329_putd(lpid );
     330_puts("] enters _bdv_isr() at cycle ");
     331_putd(_get_proctime() );
     332_puts("\n  for task ");
     333_putd(ltid );
     334_puts(" running on processor[");
     335_putd(rx );
     336_puts(",");
     337_putd(ry );
     338_puts(",");
     339_putd(rlpid );
     340_puts(" / bdv status = ");
     341_putx(_bdv_status );
     342_puts("\n");
     343#endif
     344
     345    // re-activates sleeping task
     346    _set_task_slot( rprocid,     // global processor index
     347                    ltid,        // local task index on processor
     348                    CTX_RUN_ID,  // CTX_RUN slot
     349                    1 );         // running
     350
     351    // requires a context switch for remote processor running the waiting task
     352    _xcu_send_wti( remote_xy,    // cluster index
     353                   lpid,         // local processor index
     354                   0 );          // don't force context switch if not idle
    299355}
    300356
  • soft/giet_vm/giet_drivers/bdv_driver.h

    r289 r295  
    77///////////////////////////////////////////////////////////////////////////////////
    88
    9 #ifndef _GIET_BDV_DRIVERS_H_
    10 #define _GIET_BDV_DRIVERS_H_
    11 
    12 #include <mapping_info.h>
     9#ifndef _GIET_BDV_DRIVER_H_
     10#define _GIET_BDV_DRIVER_H_
    1311
    1412///////////////////////////////////////////////////////////////////////////////////
    15 // BDV access functions and variables (vci_block_device)
     13// BDV global variables
    1614///////////////////////////////////////////////////////////////////////////////////
    1715
    18 extern unsigned int _bdv_init( unsigned int channel );
     16extern unsigned int          _bdv_lock;    // BDV is a shared ressource
     17extern volatile unsigned int _bdv_status;  // required for IRQ signaling
     18extern volatile unsigned int _bdv_gtid;    // descheduled task id = gpid<<16 + ltid
    1919
    20 extern unsigned int _bdv_write( unsigned int mode,
    21                                 unsigned int lba,
    22                                 paddr_t      buffer,
    23                                 unsigned int count );
     20///////////////////////////////////////////////////////////////////////////////////
     21// BDV registers, operations and status values
     22///////////////////////////////////////////////////////////////////////////////////
    2423
    25 extern unsigned int _bdv_read(  unsigned int mode,
    26                                 unsigned int lba,
    27                                 paddr_t      buffer,
    28                                 unsigned int count );
     24enum BDV_registers
     25{
     26    BLOCK_DEVICE_BUFFER,
     27    BLOCK_DEVICE_LBA,
     28    BLOCK_DEVICE_COUNT,
     29    BLOCK_DEVICE_OP,
     30    BLOCK_DEVICE_STATUS,
     31    BLOCK_DEVICE_IRQ_ENABLE,
     32    BLOCK_DEVICE_SIZE,
     33    BLOCK_DEVICE_BLOCK_SIZE,
     34    BLOCK_DEVICE_BUFFER_EXT,
     35};
    2936
    30 extern unsigned int _bdv_get_status( unsigned int  channel,
    31                                      unsigned int* status );
     37enum BDV_operations
     38{
     39    BLOCK_DEVICE_NOOP,
     40    BLOCK_DEVICE_READ,
     41    BLOCK_DEVICE_WRITE,
     42};
     43
     44enum BDV_status
     45{
     46    BLOCK_DEVICE_IDLE,
     47    BLOCK_DEVICE_BUSY,
     48    BLOCK_DEVICE_READ_SUCCESS,
     49    BLOCK_DEVICE_WRITE_SUCCESS,
     50    BLOCK_DEVICE_READ_ERROR,
     51    BLOCK_DEVICE_WRITE_ERROR,
     52    BLOCK_DEVICE_ERROR,
     53};
     54
     55///////////////////////////////////////////////////////////////////////////////////
     56// BDV access functions (vci_block_device)
     57///////////////////////////////////////////////////////////////////////////////////
     58
     59extern unsigned int _bdv_init();
     60
     61extern unsigned int _bdv_write( unsigned int       mode,
     62                                unsigned int       lba,
     63                                unsigned long long buffer,
     64                                unsigned int       count );
     65
     66extern unsigned int _bdv_read(  unsigned int       mode,
     67                                unsigned int       lba,
     68                                unsigned long long buffer,
     69                                unsigned int       count );
     70
     71extern unsigned int _bdv_get_status();
    3272
    3373extern unsigned int _bdv_get_block_size();
     74
     75extern void _bdv_isr( unsigned irq_type,
     76                      unsigned irq_id,
     77                      unsigned channel );
    3478
    3579///////////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/giet_drivers/cma_driver.h

    r258 r295  
    2929};
    3030
     31///////////////////////////////////////////////////////////////////////////////////
     32// CMA (vci_chbuf_dma) low-level access functions
     33///////////////////////////////////////////////////////////////////////////////////
     34
     35extern unsigned int _cma_get_register( unsigned int channel,
     36                                       unsigned int index );
     37
     38extern void _cma_set_register( unsigned int channel,
     39                               unsigned int index,
     40                               unsigned int value );
     41
     42extern void _cma_isr( unsigned int irq_type,
     43                      unsigned int irq_id,
     44                      unsigned int channel );
     45
     46///////////////////////////////////////////////////////////////////////////////////
     47
    3148#endif
    3249
  • soft/giet_vm/giet_drivers/dma_driver.c

    r267 r295  
    196196    unsigned int procid    = _get_procid();
    197197    unsigned int cluster_xy = procid/NB_PROCS_MAX;
     198    unsigned int x          = cluster_xy >> Y_WIDTH;
     199    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    198200    unsigned int channel_id = procid%NB_PROCS_MAX;
    199201
     
    203205
    204206#if GIET_DEBUG_DMA_DRIVER
    205 _tty_get_lock( 0 );
    206 _puts("\n[DMA DEBUG] Enter _dma_copy() at cycle ");
    207 _putd( _get_proctime() );
    208 _puts("\n - vspace_id  = ");
    209 _putx( vspace_id );
    210 _puts("\n - cluster_xy = ");
    211 _putx( cluster_xy );
    212 _puts("\n - channel_id = ");
    213 _putx( channel_id );
    214 _puts("\n - dest       = ");
    215 _putx( (unsigned int)dest );
    216 _puts("\n - source     = ");
    217 _putx( (unsigned int)source );
    218 _puts("\n - bytes      = ");
    219 _putd( size );
    220 _tty_release_lock( 0 );
     207unsigned int x          = cluster_xy >> Y_WIDTH;
     208unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
     209
     210_printf("\n[DMA DEBUG] Processor[%d,%d,%d] enters _dma_copy() at cycle %d\n"
     211        " - vspace_id  = %d\n"
     212        " - cluster_xy = %x\n"
     213        " - channel_id = %d\n"
     214        " - dest       = %x\n"
     215        " - source     = %x\n"
     216        " - bytes      = %x\n",
     217        x, y, channel_id, _get_proctime(), vspace_id, cluster_xy,
     218        (unsigned int)dest, (unsigned int)source, size );
    221219#endif
    222220
     
    226224         (size & 0x3) )
    227225    {
    228         _tty_get_lock( 0 );
    229         _puts("\n[GIET ERROR] in _dma_copy() : buffer unaligned\n");
    230         _tty_release_lock( 0 );
     226        _printf("\n[GIET ERROR] in _dma_copy() : buffer unaligned\n");
    231227        _exit();
    232228    }
     
    242238    if ( ko )
    243239    {
    244         _tty_get_lock( 0 );
    245         _puts("\n[GIET ERROR] in _dma_copy() : source buffer unmapped\n");
    246         _tty_release_lock( 0 );
     240        _printf("\n[GIET ERROR] in _dma_copy() : source buffer unmapped\n");
    247241        _exit();
    248242    }
     
    257251    if ( ko )
    258252    {
    259         _tty_get_lock( 0 );
    260         _puts("\n[GIET ERROR] in _dma_copy() : dest buffer unmapped\n");
    261         _tty_release_lock( 0 );
     253        _printf("\n[GIET ERROR] in _dma_copy() : dest buffer unmapped\n");
    262254        _exit();
    263255    }
     
    266258
    267259#if GIET_DEBUG_DMA_DRIVER
    268 _tty_get_lock( 0 );
    269 _puts("\n - src_paddr  = ");
    270 _putl( src_paddr );
    271 _puts("\n - dst_paddr  = ");
    272 _putl( dst_paddr );
    273 _puts("\n");
    274 _tty_release_lock( 0 );
     260_printf(" - src_paddr  = %llx\n"
     261        " - dst_paddr  = %llx\n",
     262        src_paddr, dst_paddr );
    275263#endif
    276264
     
    282270    if ( ko )
    283271    {
    284         _tty_get_lock( 0 );
    285         _puts("\n[GIET ERROR] in _dma_copy() : cannot start transfer\n");
    286         _tty_release_lock( 0 );
     272        _printf("\n[GIET ERROR] in _dma_copy() : cannot start transfer\n");
    287273        _exit();
    288274    }
     
    297283
    298284#if GIET_DEBUG_DMA_DRIVER
    299 _tty_get_lock( 0 );
    300 _puts("\n[DMA DEBUG] _dma_copy() : ... waiting on DMA_STATUS register ...\n");
    301 _tty_release_lock( 0 );
     285_printf("\n[DMA DEBUG] _dma_copy() : ... waiting on DMA_STATUS register ...\n");
    302286#endif
    303287
     
    307291    if( status != DMA_SUCCESS )
    308292    {
    309         _tty_get_lock( 0 );
    310         _puts("\n[GIET ERROR] in _dma_copy() : DMA_STATUS error = ");
    311         _putd( status );
    312         _puts("\n");
    313         _tty_release_lock( 0 );
     293        _printf("\n[GIET ERROR] in _dma_copy() : DMA_STATUS = %x\n", status );
    314294        _exit();
    315295    }
     
    318298
    319299#if GIET_DEBUG_DMA_DRIVER
    320 _tty_get_lock( 0 );
    321 _puts("\n[DMA DEBUG] _dma_copy() completed at cycle ");
    322 _putd( _get_proctime() );
    323 _puts("\n");
    324 _tty_release_lock( 0 );
     300_printf("\n[DMA DEBUG] _dma_copy() completed at cycle %d\n", _get_proctime() );
    325301#endif
    326302
    327303#else // NB_DMA_CHANNELS == 0
    328     _tty_get_lock( 0 );
    329     _puts("\n[GIET ERROR] in _dma_copy() : NB_DMA_CHANNELS = 0 !\n");
    330     _tty_release_lock( 0 );
     304    _printf("\n[GIET ERROR] in _dma_copy() : NB_DMA_CHANNELS = 0 !\n");
    331305    _exit();
    332306#endif
  • soft/giet_vm/giet_drivers/fbf_driver.c

    r275 r295  
    77// The fbf_driver.c and fbf_driver.h files are part ot the GIET-VM kernel.
    88// This driver supports the SoCLib vci_framebuffer component.
    9 //
    10 // It can exist only one frame buffer in the architecture.
    119//
    1210// There exist two methods to access the VciFrameBuffer device:
     
    5957                            unsigned int length)
    6058{
    61     char* fb_address = (char *)&seg_fbf_base + offset;
    62     _memcpy( fb_address, buffer, length);
     59    char* fbf_address = (char *)&seg_fbf_base + offset;
     60
     61    _memcpy( fbf_address, buffer, length);
     62
    6363    return 0;
    6464}
     
    7474                            unsigned int   length)
    7575{
    76     char* fb_address = (char *)&seg_fbf_base + offset;
    77     _memcpy( buffer, fb_address, length);
     76    char* fbf_address = (char *)&seg_fbf_base + offset;
     77
     78    _memcpy( buffer, fbf_address, length);
     79
    7880    return 0;
    7981}
     
    145147    if ( channel_id >= NB_CMA_CHANNELS )
    146148    {
    147         _tty_get_lock( 0 );
    148         _puts("\n[GIET ERROR] in _fb_cma_init() : CMA channel index too large\n");
    149         _tty_release_lock( 0 );
     149        _printf("\n[GIET ERROR] in _fb_cma_init() : CMA channel index too large\n");
    150150        return 1;
    151151    }
     
    154154    if ( sizeof(fb_cma_channel_t) != 32 )
    155155    {
    156         _tty_get_lock( 0 );
    157         _puts("\n[GIET ERROR] in _fb_cma_init() : bad fb_cma_channel size\n");
    158         _tty_release_lock( 0 );
     156        _printf("\n[GIET ERROR] in _fb_cma_init() : bad fb_cma_channel size\n");
    159157        return 1;
    160158    }
     
    163161    if ( (unsigned int)(&_fb_cma_channel[channel_id]) & 0x1F )
    164162    {
    165         _tty_get_lock( 0 );
    166         _puts("\n[GIET ERROR] in _fb_cma_init() : bad fb_cma_channel alignment\n");
    167         _tty_release_lock( 0 );
     163        _printf("\n[GIET ERROR] in _fb_cma_init() : bad fb_cma_channel alignment\n");
    168164        return 1;
    169165    }
     
    172168    if ( ((unsigned int)vbase0 & 0x3) || ((unsigned int)vbase1 & 0x3) || (length & 0x3) )
    173169    {
    174         _tty_get_lock( 0 );
    175         _puts("\n[GIET ERROR] in _fb_cma_init() : user buffer not word aligned\n");
    176         _tty_release_lock( 0 );
     170        _printf("\n[GIET ERROR] in _fb_cma_init() : user buffer not word aligned\n");
    177171        return 1;
    178172    }
     
    189183    if (ko)
    190184    {
    191         _tty_get_lock( 0 );
    192         _puts("\n[GIET ERROR] in _fb_cma_init() : frame buffer unmapped\n");
    193         _tty_release_lock( 0 );
     185        _printf("\n[GIET ERROR] in _fb_cma_init() : frame buffer unmapped\n");
    194186        return 1;
    195187    }
     
    204196    if (ko)
    205197    {
    206         _tty_get_lock( 0 );
    207         _puts("\n[GIET ERROR] in _fb_cma_init() : user buffer 0 unmapped\n");
    208         _tty_release_lock( 0 );
     198        _printf("\n[GIET ERROR] in _fb_cma_init() : user buffer 0 unmapped\n");
    209199        return 1;
    210200    }
    211201    if ((flags & PTE_U) == 0)
    212202    {
    213         _tty_get_lock( 0 );
    214         _puts("[GIET ERROR] in _fb_cma_init() : user buffer 0 not in user space\n");
    215         _tty_release_lock( 0 );
     203        _printf("[GIET ERROR] in _fb_cma_init() : user buffer 0 not in user space\n");
    216204        return 1;
    217205    }
     
    226214    if (ko)
    227215    {
    228         _tty_get_lock( 0 );
    229         _puts("\n[GIET ERROR] in _fb_cma_init() : user buffer 1 unmapped\n");
    230         _tty_release_lock( 0 );
     216        _printf("\n[GIET ERROR] in _fb_cma_init() : user buffer 1 unmapped\n");
    231217        return 1;
    232218    }
    233219    if ((flags & PTE_U) == 0)
    234220    {
    235         _tty_get_lock( 0 );
    236         _puts("[GIET ERROR] in _fb_cma_init() : user buffer 1 not in user space\n");
    237         _tty_release_lock( 0 );
     221        _printf("[GIET ERROR] in _fb_cma_init() : user buffer 1 not in user space\n");
    238222        return 1;
    239223    }
     
    251235    if (ko)
    252236    {
    253         _tty_get_lock( 0 );
    254         _puts("\n[GIET ERROR] in _fb_cma_init() : channel descriptor unmapped\n");
    255         _tty_release_lock( 0 );
     237        _printf("\n[GIET ERROR] in _fb_cma_init() : channel descriptor unmapped\n");
    256238        return 1;
    257239    }
     
    262244
    263245#if GIET_DEBUG_FBF_DRIVER
    264 _tty_get_lock( 0 );
    265 _puts("\n[CMA DEBUG] fb_cma_init()");
    266 _puts("\n - fbf       pbase = ");
    267 _putl( _fb_cma_channel[channel_id].fbf );
    268 _puts("\n - buf0      pbase = ");
    269 _putl( _fb_cma_channel[channel_id].buf0 );
    270 _puts("\n - buf1      pbase = ");
    271 _putl( _fb_cma_channel[channel_id].buf1 );
    272 _puts("\n - channel   pbase = ");
    273 _putl( _fb_cma_desc_paddr[channel_id] );
    274 _puts("\n");
    275 _tty_release_lock( 0 );
     246_printf("\n[CMA DEBUG] enters _fb_cma_init()\n"
     247        " - fbf       pbase = %l\n"
     248        " - buf0      pbase = %l\n"
     249        " - buf1      pbase = %l\n"
     250        " - channel   pbase = %l\n"
     251        _fb_cma_channel[channel_id].fbf,
     252        _fb_cma_channel[channel_id].buf0,
     253        _fb_cma_channel[channel_id].buf1,
     254        _fb_cma_desc_paddr[channel_id] );
    276255#endif
    277256
     
    283262
    284263    // CMA channel activation
    285     unsigned int* cma_vbase = (unsigned int *)&seg_cma_base;
    286     unsigned int  offset    = channel_id * CHBUF_CHANNEL_SPAN;
    287 
    288     cma_vbase[offset + CHBUF_SRC_DESC]  = (unsigned int)(desc_paddr & 0xFFFFFFFF);
    289     cma_vbase[offset + CHBUF_SRC_EXT]   = (unsigned int)(desc_paddr >> 32);
    290     cma_vbase[offset + CHBUF_SRC_NBUFS] = 2;
    291     cma_vbase[offset + CHBUF_DST_DESC]  = (unsigned int)(desc_paddr & 0xFFFFFFFF) + 16;
    292     cma_vbase[offset + CHBUF_DST_EXT]   = (unsigned int)(desc_paddr >> 32);
    293     cma_vbase[offset + CHBUF_DST_NBUFS] = 1;
    294     cma_vbase[offset + CHBUF_BUF_SIZE]  = length;
    295     cma_vbase[offset + CHBUF_PERIOD]    = 300;
    296     cma_vbase[offset + CHBUF_RUN]       = 1;
    297 
     264    _cma_set_register( channel_id, CHBUF_SRC_DESC , (unsigned int)(desc_paddr & 0xFFFFFFFF) );
     265    _cma_set_register( channel_id, CHBUF_SRC_EXT  , (unsigned int)(desc_paddr >> 32) );
     266    _cma_set_register( channel_id, CHBUF_SRC_NBUFS, 2 );
     267    _cma_set_register( channel_id, CHBUF_DST_DESC , (unsigned int)(desc_paddr & 0xFFFFFFFF) + 16 );
     268    _cma_set_register( channel_id, CHBUF_DST_EXT  , (unsigned int)(desc_paddr >> 32) );
     269    _cma_set_register( channel_id, CHBUF_DST_NBUFS, 1 );
     270    _cma_set_register( channel_id, CHBUF_BUF_SIZE , length );
     271    _cma_set_register( channel_id, CHBUF_PERIOD   , 300 );
     272    _cma_set_register( channel_id, CHBUF_RUN      , 1 );
    298273    return 0;
    299274
    300275#else
    301 
    302     _tty_get_lock( 0 );
    303     _puts("\n[GIET ERROR] in _fb_cma_init() : no CMA channel allocated\n");
    304     _tty_release_lock( 0 );
    305 
     276    _printf("\n[GIET ERROR] in _fb_cma_init() : no CMA channel allocated\n");
    306277    return 1;
    307278#endif
    308279}
     280
    309281////////////////////////////////////////////////////////////////////////////////////
    310282// _fb_cma_write()
     
    330302
    331303    volatile paddr_t buf_paddr;
    332     unsigned int     buf_length;
    333304    unsigned int     full = 1;
    334305
     
    339310
    340311#if GIET_DEBUG_FBF_DRIVER
    341 _tty_get_lock( 0 );
    342 _puts("\n[CMA DEBUG] fb_cma_write() for CMA channel ");
    343 _putd( channel_id );
    344 _puts(" / buf_id = ");
    345 _putd( buffer_id );
    346 _puts("\n");
    347 _tty_release_lock( 0 );
     312_printf("\n[CMA DEBUG] _fb_cma_write() for CMA channel %d / bufid = %d at cycle %d\n",
     313        channel_id, buffer_id, _get_proctime() );
    348314#endif
    349315
     
    357323
    358324            // INVAL L1 cache for the channel descriptor,
    359             _dcache_buf_invalidate( &_fb_cma_channel[channel_id], 32 );
     325            _dcache_buf_invalidate( (void*)&_fb_cma_channel[channel_id], 32 );
    360326        }
    361327
     
    367333        count++;
    368334        if ( count == 10 ) _exit();
    369 
    370 #if GIET_DEBUG_FBF_DRIVER
    371 _tty_get_lock( 0 );
    372 _puts(" - buffer descriptor = ");
    373 _putl( buf_paddr );
    374 _puts(" at cycle ");
    375 _putd( _get_proctime() );
    376 _puts("\n");
    377 _tty_release_lock( 0 );
    378 #endif
    379 
    380335    }
    381336
     
    408363#else
    409364
    410     _tty_get_lock( 0 );
    411     _puts("\n[GIET ERROR] in _fb_cma_channel() : no CMA channel allocated\n");
    412     _tty_release_lock( 0 );
     365    _printf("\n[GIET ERROR] in _fb_cma_channel() : no CMA channel allocated\n");
    413366    return 1;
    414367
     
    427380    unsigned int channel_id = _get_context_slot(CTX_CMA_ID);
    428381
     382#if GIET_DEBUG_FBF_DRIVER
     383_printf("\n[CMA DEBUG] _fb_cma_stop() for CMA channel %d at cycle %d\n",
     384        channel_id, _get_proctime() );
     385#endif
     386
    429387    // CMA channel desactivation
    430     unsigned int* cma_vbase = (unsigned int *)&seg_cma_base;
    431     unsigned int  offset     = channel_id * CHBUF_CHANNEL_SPAN;
    432     cma_vbase[offset + CHBUF_RUN] = 0;
     388    _cma_set_register( channel_id, CHBUF_RUN, 0 );
     389
    433390    return 0;
    434391
    435392#else
    436393
    437     _tty_get_lock( 0 );
    438     _puts("\n[GIET ERROR] in _fb_cma_stop() : no CMA channel allocated\n");
    439     _tty_release_lock( 0 );
     394    _printf("\n[GIET ERROR] in _fb_cma_stop() : no CMA channel allocated\n");
    440395    return 1;
    441396
  • soft/giet_vm/giet_drivers/hba_driver.c

    r289 r295  
    22// File     : hba_driver.c
    33// Date     : 23/11/2013
    4 // Author   : alain greiner and zhang
     4// Author   : alain greiner
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
     
    99// block oriented, external storage contrÃŽler, respecting the AHCI standard.
    1010//
    11 // It can exist only one ahci-device controler in the architecture.
     11// The seg_ioc_base (standard HBA virtual base address) and seg_ioc_base_bis
     12// (backup HBA virtual base address) must be defined in giet_vsegs.ld file.
     13//////////////////////////////////////////////////////////////////////////////////
     14// Implementation notes:
    1215//
    13 // The _ioc_read() and _ioc_write() functions use the _ioc_access() function,
    14 // that is always blocking, but can be called in 4 modes:
     16// 1. In order to share code, the two _hba_read() and _hba_write() functions
     17//    call the same _hba_set_cmd() function.
    1518//
    16 // - In BOOT_PA mode, the _ioc_access() function use the buffer virtual address
    17 //   as a physical address (as the page tables are not build) and use a polling
    18 //   policy on the IOC_STATUS register to detect transfer completion, as
    19 //   hardware interrupts are not activated. This mode is used by the
    20 //   boot code to load the map.bin file into memory.
    21 //
    22 // - In BOOT_VA mode, the _ioc_access() function makes a V2P translation to
    23 //   compute the buffer physical address, and use a polling policy on IOC_STATUS
    24 //   register to detect transfer completion. This mode is used by the boot code
    25 //   to load the various .elf files into memory.
    26 //
    27 // - In KERNEL mode, the _ioc_access() function makes a V2P translation to
    28 //   compute the buffer physical address, and use a descheduling strategy:
    29 //   The ISR executed when transfer completes should restart the calling task.
    30 //   There is no checking of user access right to the memory buffer.
    31 //   This mode must be used to access IOC, for an "open" system call.
    32 //
    33 // - In USER mode, the _ioc_access() function makes a V2P translation to
    34 //   compute the buffer physical address, and use a descheduling strategy:
    35 //   The ISR executed when transfer completes should restart the calling task,
    36 //   The user access right to the memory buffer must be checked.
    37 //   This mode must be used to access IOC, for a "read/write" system call.
    38 //
    39 // As the IOC component can be used by several programs running in parallel,
    40 // the _ioc_lock variable guaranties exclusive access to the device.  The
    41 // _ioc_read() and _ioc_write() functions use atomic LL/SC to get the lock.
    42 //
    43 // The IOMMU can be activated or not:
    44 //
    45 // 1) When the IOMMU is used, a fixed size 2Mbytes vseg is allocated to
    46 // the IOC peripheral, in the I/O virtual space, and the user buffer is
    47 // dynamically remapped in the IOMMU page table. The corresponding entry
    48 // in the IOMMU PT1 is defined by the kernel _ioc_iommu_ix1 variable.
    49 // The number of pages to be unmapped is stored in the _ioc_npages variable.
    50 // The number of PT2 entries is dynamically computed and stored in the
    51 // kernel _ioc_iommu_npages variable. It cannot be larger than 512.
    52 // The user buffer is unmapped by the _ioc_completed() function when
    53 // the transfer is completed.
    54 //
    55 // 2/ If the IOMMU is not used, we check that  the user buffer is mapped to a
    56 // contiguous physical buffer (this is generally true because the user space
    57 // page tables are statically constructed to use contiguous physical memory).
    58 //
    59 // Finally, the memory buffer must fulfill the following conditions:
    60 // - The buffer must be word aligned,
    61 // - The buffer must be mapped in user space for an user access,
    62 // - The buffer must be writable in case of (to_mem) access,
    63 // - The total number of physical pages occupied by the user buffer cannot
    64 //   be larger than 512 pages if the IOMMU is activated,
    65 // - All physical pages occupied by the user buffer must be contiguous
    66 //   if the IOMMU is not activated.
    67 // An error code is returned if these conditions are not verified.
    68 ///////////////////////////////////////////////////////////////////////////////////
    69 // The seg_ioc_base virtual base addresses must be defined in giet_vsegs.ld file.
     19// 2. All accesses to HBA registers are done by the two
     20//    _hba_set_register() and _hba_get_register() low-level functions,
     21//    that are handling virtual / physical extended addressing.
    7022///////////////////////////////////////////////////////////////////////////////////
    7123
     
    8032#include <vmem.h>
    8133
    82 #if !defined( NB_HBA_CHANNELS )
    83 # error: You must define NB_HBA_CHANNELS in the hard_config.h file
    84 #endif
    85 
    86 #if ( NB_HBA_CHANNELS > 8 )
    87 # error: NB_HBA_CHANNELS cannot be larger than 8
    88 #endif
    89 
    90 #if !defined( USE_IOB )
    91 # error: You must define USE_IOB in the hard_config.h file
    92 #endif
    93 
    94 #if !defined(GIET_USE_IOMMU)
    95 # error: You must define GIET_USE_IOMMU in the giet_config.h file
     34#if !defined( NB_IOC_CHANNELS )
     35# error: You must define NB_IOC_CHANNELS in the hard_config.h file
     36#endif
     37
     38#if ( NB_IOC_CHANNELS > 8 )
     39# error: NB_IOC_CHANNELS cannot be larger than 8
    9640#endif
    9741
     
    10347
    10448// command list array (one per channel)
    105 hba_cmd_list_t   hba_cmd_list[NB_HBA_CHANNELS] __attribute__((aligned(0x1000)));   
     49hba_cmd_list_t   hba_cmd_list[NB_IOC_CHANNELS] __attribute__((aligned(0x1000)));   
    10650
    10751// command tables array (32 command tables per channel)
    108 hba_cmd_table_t  hba_cmd_table[NB_HBA_CHANNELS][32] __attribute__((aligned(0x1000)));
     52hba_cmd_table_t  hba_cmd_table[NB_IOC_CHANNELS][32] __attribute__((aligned(0x1000)));
    10953
    11054// command list physical addresses array (one per channel)
    111 paddr_t          hba_cmd_list_paddr[NB_HBA_CHANNELS];
     55paddr_t          hba_cmd_list_paddr[NB_IOC_CHANNELS];
    11256
    11357// command tables physical addresses array (32 command tables per channel)
    114 paddr_t          hba_cmd_table_paddr[NB_HBA_CHANNELS][32];
     58paddr_t          hba_cmd_table_paddr[NB_IOC_CHANNELS][32];
    11559
    11660// command list pointer array (one per channel)
    117 unsigned int     hba_cmd_slot[NB_HBA_CHANNELS];
    118 
    119 //////////////////////////////////////////////////////////////////
    120 // This function returns the status of a given channel.
    121 // return 0 if success, >0 if error
    122 //////////////////////////////////////////////////////////////////
    123 unsigned int _hba_get_status( unsigned int   channel,
    124                               unsigned int*  status )
    125 {
    126     volatile unsigned int* hba_address;
    127     hba_address = (unsigned int*)(&seg_ioc_base) + (HBA_SPAN*channel);
    128 
    129     if( channel >= NB_HBA_CHANNELS )
    130     {
    131         _tty_get_lock( 0 );
    132         _puts("\n[GIET ERROR] in _hba_get_status() : illegal channel\n");
    133         _tty_release_lock( 0 );
    134         return 1;
    135     }
    136     else
    137     {
    138         *status = hba_address[HBA_PXIS];
    139         return 0;
    140     }
    141 }
    142 //////////////////////////////////////////////////////////////////
    143 // This function reset the status resgister for a given channel.
    144 // return 0 if success, >0 if error
    145 //////////////////////////////////////////////////////////////////
    146 unsigned int _hba_reset_status( unsigned int channel )
    147 {
    148     volatile unsigned int* hba_address;
    149     hba_address = (unsigned int*)(&seg_ioc_base) + (HBA_SPAN*channel);
    150 
    151     if( channel >= NB_HBA_CHANNELS )
    152     {   
    153         _tty_get_lock( 0 );
    154         _puts("\n[GIET ERROR] in _hba_reset_status() : illegal channel\n");
    155         _tty_release_lock( 0 );
    156         return 1;
    157     }
    158     else
    159     {
    160         hba_address[HBA_PXIS] = 0;
    161         return 0;
    162     }
    163 }
     61unsigned int     hba_cmd_slot[NB_IOC_CHANNELS];
     62
     63//////////////////////////////////////////////////////////////////////////////
     64// This low level function returns the value of register (channel / index)
     65//////////////////////////////////////////////////////////////////////////////
     66unsigned int _hba_get_register( unsigned int channel,
     67                                unsigned int index )
     68{
     69    unsigned int* vaddr = (unsigned int*)&seg_ioc_base + channel*HBA_SPAN + index;
     70    return _io_extended_read( vaddr );
     71}
     72
     73//////////////////////////////////////////////////////////////////////////////
     74// This low level function set a new value in register (channel / index) 
     75//////////////////////////////////////////////////////////////////////////////
     76void _hba_set_register( unsigned int channel,
     77                        unsigned int index,
     78                        unsigned int value )
     79{
     80    unsigned int* vaddr = (unsigned int*)&seg_ioc_base + channel*HBA_SPAN + index;
     81    _io_extended_write( vaddr, value );
     82}
     83
     84
    16485///////////////////////////////////////////////////////////////////////////////
    16586// This function register a command in both the command list
     
    17192// return 0 if success, > 0 if error
    17293///////////////////////////////////////////////////////////////////////////////
    173 unsigned int _hba_cmd_set( unsigned int  is_read,     // to memory
     94unsigned int _hba_cmd_set( unsigned int  channel,     // channel index
     95                           unsigned int  is_read,     // to memory
    17496                           unsigned int  lba,         // logic block address
    175                            unsigned int  buf_vaddr,   // buffer virtual address
     97                           paddr_t       buffer,      // buffer physical address
    17698                           unsigned int  count )      // number of blocks
    17799{
    178     volatile unsigned int *hba_address;
    179 
    180100    unsigned int       block_size;     // defined by the block device (bytes)
    181     unsigned int       channel_id;     // channel index
    182101    unsigned int       pxci;           // command list status
    183102    unsigned int       cmd_id;         // command index in command list
    184     unsigned int       buf_id;         // for physical buffers covering user buffer
    185     unsigned int       user_pt_vbase;  // user page table virtual base address
    186     unsigned int       vpn;            // for all pages covering the userbuffer
    187     unsigned int       vpn_min;        // first virtual page index for user buffer
    188     unsigned int       vpn_max;        // last  virtual page index for user buffer
    189     unsigned int       offset;         // unaligned bytes in page frame: buf_vaddr & 0xFFF
    190     unsigned int       offset_last;    // unaligned bytes in last frame
     103
    191104    hba_cmd_desc_t*    cmd_desc;       // command descriptor pointer   
    192105    hba_cmd_table_t*   cmd_table;      // command table pointer
     
    195108
    196109    // check buffer alignment
    197     if( buf_vaddr & (block_size-1) )
    198     {
    199         _tty_get_lock( 0 );
    200         _puts("\n[GIET ERROR] in _hba_set_cmd() : user buffer not block aligned\n");
    201         _tty_release_lock( 0 );
     110    if( buffer & (block_size-1) )
     111    {
     112        _printf("\n[GIET ERROR] in _hba_set_cmd() : user buffer not block aligned\n");
    202113        return 1;
    203114    }
    204115
    205     // get channel index
    206     channel_id = _get_context_slot(CTX_HBA_ID);
    207     if ( channel_id == 0xFFFFFFFF )
    208     {
    209         _tty_get_lock( 0 );
    210         _puts("\n[GIET ERROR] in _hba_set_cmd() : no HBA channel allocated\n");
    211         _tty_release_lock( 0 );
     116    // get command list status from PXCI register
     117    pxci = _hba_get_register( channel, HBA_PXCI );
     118
     119    // get command index and return error if command list full
     120    cmd_id = hba_cmd_slot[channel];
     121    if( pxci & (1<<cmd_id ) )
     122    {
     123        _printf("\n[GIET ERROR] in _hba_set_cmd() : command list full for channel %d\n",
     124                channel );
    212125        return 1;
    213126    }
    214127
    215     // get hba device address
    216     hba_address = (unsigned int*)(&seg_ioc_base) + (HBA_SPAN * channel_id);
    217 
    218     // get command list status
    219     pxci = hba_address[HBA_PXCI];
    220 
    221     // get command index and return error if command list full
    222     cmd_id = hba_cmd_slot[channel_id];
    223     if( pxci & (1<<cmd_id ) )
    224     {
    225         _tty_get_lock( 0 );
    226         _puts("\n[GIET ERROR] in _hba_set_cmd() : command list full in channel \n");
    227         _putd( channel_id );
    228         _puts("\n");
    229         _tty_release_lock( 0 );
    230         return 1;
    231     }
    232 
    233128    // compute pointers on command descriptor and command table   
    234     cmd_desc  = (hba_cmd_desc_t*)(&(hba_cmd_list[channel_id].desc[cmd_id]));
    235     cmd_table = (hba_cmd_table_t*)(&(hba_cmd_table[channel_id][cmd_id]));
     129    cmd_desc  = (hba_cmd_desc_t*)(&(hba_cmd_list[channel].desc[cmd_id]));
     130    cmd_table = (hba_cmd_table_t*)(&(hba_cmd_table[channel][cmd_id]));
     131
     132    // set  buffer descriptor in command table
     133    cmd_table->entry[0].dba  = (unsigned int)(buffer);
     134    cmd_table->entry[0].dbau = (unsigned int)(buffer >> 32);
     135    cmd_table->entry[0].dbc  = count * block_size;
     136
     137    // initialize command table header
     138    cmd_table->header.lba0 = (char)lba;
     139    cmd_table->header.lba1 = (char)(lba>>8);
     140    cmd_table->header.lba2 = (char)(lba>>16);
     141    cmd_table->header.lba3 = (char)(lba>>24);
     142    cmd_table->header.lba4 = 0;
     143    cmd_table->header.lba5 = 0;
     144
     145    // initialise command descriptor
     146    cmd_desc->prdtl[0] = 1;
     147    cmd_desc->prdtl[1] = 0;
     148    cmd_desc->ctba     = (unsigned int)(hba_cmd_table_paddr[channel][cmd_id]);
     149    cmd_desc->ctbau    = (unsigned int)(hba_cmd_table_paddr[channel][cmd_id]>>32);
     150    if( is_read ) cmd_desc->flag[0] = 0x00;
     151    else          cmd_desc->flag[0] = 0x40;     
     152   
     153    // update PXCI register
     154    _hba_set_register( channel, HBA_PXCI, (1<<cmd_id) );
     155
     156    // update command pointer
     157    hba_cmd_slot[channel] = (cmd_id + 1)%32;
     158
     159    return  0;
     160}
     161
     162/* This can be used for a future use with buffer in virtual space
    236163
    237164    // get user space page table virtual address
     
    262189        if ( ko )
    263190        {
    264             _tty_get_lock( 0 );
    265             _puts("[GIET ERROR] in _hba_set_cmd() : user buffer unmapped\n");
    266             _tty_release_lock( 0 );
     191            _printf("[GIET ERROR] in _hba_set_cmd() : user buffer unmapped\n");
    267192            return 1;
    268193        }
    269194        if ((flags & PTE_U) == 0)
    270195        {
    271             _tty_get_lock( 0 );
    272             _puts("[GIET ERROR] in _hba_set_cmd() : user buffer not in user space\n");
    273             _tty_release_lock( 0 );
     196            _printf("[GIET ERROR] in _hba_set_cmd() : user buffer not in user space\n");
    274197            return 1;
    275198        }
    276199        if (((flags & PTE_W) == 0 ) && (is_read == 0) )
    277200        {
    278             _tty_get_lock( 0 );
    279             _puts("[GIET ERROR] in _hba_set_cmd() : user buffer not writable\n");
    280             _tty_release_lock( 0 );
     201            _printf("[GIET ERROR] in _hba_set_cmd() : user buffer not writable\n");
    281202            return 1;
    282203        }
     
    285206        if( buf_id > 245 )
    286207        {
    287             _tty_get_lock( 0 );
    288             _puts("[GIET ERROR] in _hba_set_cmd() : max number of buffers is 248\n");
    289             _tty_release_lock( 0 );
     208            _printf("[GIET ERROR] in _hba_set_cmd() : max number of buffers is 248\n");
    290209            return 1;
    291210        }
     
    301220
    302221#if GIET_DEBUG_HBA_DRIVER
    303 _puts("\n- buf_index = ");
     222_printf("\n- buf_index = ");
    304223_putd( buf_id );
    305 _puts(" / paddr = ");
     224_printf(" / paddr = ");
    306225_putl( paddr );
    307 _puts(" / count = ");
     226_printf(" / count = ");
    308227_putd( count );
    309 _puts("\n");
     228_printf("\n");
    310229#endif
    311230            buf_id++;
     
    320239
    321240#if GIET_DEBUG_HBA_DRIVER
    322 _puts("\n- buf_index = ");
     241_printf("\n- buf_index = ");
    323242_putd( buf_id );
    324 _puts(" / paddr = ");
     243_printf(" / paddr = ");
    325244_putl( paddr );
    326 _puts(" / count = ");
     245_printf(" / count = ");
    327246_putd( count );
    328 _puts("\n");
     247_printf("\n");
    329248#endif
    330249            buf_id++;
     
    340259
    341260#if GIET_DEBUG_HBA_DRIVER
    342 _puts("\n- buf_index = ");
     261_printf("\n- buf_index = ");
    343262_putd( buf_id );
    344 _puts(" / paddr = ");
     263_printf(" / paddr = ");
    345264_putl( paddr );
    346 _puts(" / count = ");
     265_printf(" / count = ");
    347266_putd( count );
    348 _puts("\n");
     267_printf("\n");
    349268#endif
    350269            buf_id++;
     
    357276
    358277#if GIET_DEBUG_HBA_DRIVER
    359 _puts("\n- buf_index = ");
     278_printf("\n- buf_index = ");
    360279_putd( buf_id );
    361 _puts(" / paddr = ");
     280_printf(" / paddr = ");
    362281_putl( paddr );
    363 _puts(" / count = ");
     282_printf(" / count = ");
    364283_putd( count );
    365 _puts("\n");
     284_printf("\n");
    366285#endif
    367286            buf_id++;
     
    376295
    377296#if GIET_DEBUG_HBA_DRIVER
    378 _puts("\n- buf_index = ");
     297_printf("\n- buf_index = ");
    379298_putd( buf_id );
    380 _puts(" / paddr = ");
     299_printf(" / paddr = ");
    381300_putl( paddr );
    382 _puts(" / count = ");
     301_printf(" / count = ");
    383302_putd( count );
    384 _puts("\n");
     303_printf("\n");
    385304#endif
    386305            buf_id++;
    387306        }
    388307    }
    389 
    390     // initialize command table header
    391     cmd_table->header.lba0 = (char)lba;
    392     cmd_table->header.lba1 = (char)(lba>>8);
    393     cmd_table->header.lba2 = (char)(lba>>16);
    394     cmd_table->header.lba3 = (char)(lba>>24);
    395 
    396     // initialise command descriptor
    397     cmd_desc->prdtl[0] = (unsigned char)(buf_id);
    398     cmd_desc->prdtl[1] = (unsigned char)(buf_id>>8);
    399     cmd_desc->ctba     = (unsigned int)(hba_cmd_table_paddr[channel_id][cmd_id]);
    400     cmd_desc->ctbau    = (unsigned int)(hba_cmd_table_paddr[channel_id][cmd_id]>>32);
    401     if( is_read ) cmd_desc->flag[0] = 0x00;
    402     else          cmd_desc->flag[0] = 0x40;     
    403    
    404     // update PXCI register
    405     hba_address[HBA_PXCI] = (1<<cmd_id);
    406 
    407     // update command pointer
    408     hba_cmd_slot[channel_id] = (cmd_id + 1)%32;
    409 
    410     return  0;
    411 }
     308*/
     309
     310
    412311///////////////////////////////////////////////////////////////////
    413312// Register a write command in Command List and Command Table
    414 // for a single buffer.
     313// for a single physical buffer.
    415314// Returns 0 if success, > 0 if error.
    416315///////////////////////////////////////////////////////////////////
    417 unsigned int _hba_write( unsigned int  mode,
     316unsigned int _hba_write( unsigned int  channel,
     317                         unsigned int  mode,
    418318                         unsigned int  lba,
    419                          void*         buffer,
     319                         paddr_t       buffer,
    420320                         unsigned int  count )
    421321{
    422     return _hba_cmd_set( 0, lba, (unsigned int)buffer, count );
     322    return _hba_cmd_set( channel,
     323                         0,         // write
     324                         lba,
     325                         buffer,
     326                         count );
    423327}
    424328
    425329///////////////////////////////////////////////////////////////////
    426330// Register a read command in Command List and Command Table
    427 // for a single buffer.
     331// for a single physical buffer.
    428332// Returns 0 if success, > 0 if error.
    429333///////////////////////////////////////////////////////////////////
    430 unsigned int _hba_read( unsigned int  mode,
     334unsigned int _hba_read( unsigned int  channel,
     335                        unsigned int  mode,
    431336                        unsigned int  lba,
    432                         void*         buffer,
     337                        paddr_t       buffer,
    433338                        unsigned int  count )
    434339{
    435     return _hba_cmd_set( 1, lba, (unsigned int)buffer, count );
    436 }
     340    return _hba_cmd_set( channel,
     341                         1,          // read
     342                         lba,
     343                         buffer,
     344                         count );
     345}
     346
    437347//////////////////////////////////////////////////////////////////
    438348// This function initializes for a given channel
     
    453363    unsigned int pt = _get_context_slot(CTX_PTAB_ID);
    454364
    455     // HBA registers
    456     unsigned int*  hba_address;
    457     hba_address = (unsigned int*)&seg_ioc_base + HBA_SPAN * channel;
    458 
    459     hba_address[HBA_PXCLB]  = (unsigned int)(&hba_cmd_list[channel]);
    460     hba_address[HBA_PXCLBU] = 0;
    461     hba_address[HBA_PXIE]   = 0x40000001;
    462     hba_address[HBA_PXIS]   = 0;
    463     hba_address[HBA_PXCI]   = 0;
    464     hba_address[HBA_PXCMD]  = 1;
     365    // HBA registers TODO: ne faut_il pas un V2P pour PXCLB/PXCLBU ? (AG)
     366    _hba_set_register( channel, HBA_PXCLB , (unsigned int)&hba_cmd_list[channel] );
     367    _hba_set_register( channel, HBA_PXCLBU, 0 );
     368    _hba_set_register( channel, HBA_PXIE  , 0x40000001 );
     369    _hba_set_register( channel, HBA_PXIS  , 0 );
     370    _hba_set_register( channel, HBA_PXCI  , 0 );
     371    _hba_set_register( channel, HBA_PXCMD , 1 );
    465372
    466373    // command list pointer       
     
    475382    if ( fail )
    476383    {
    477         _tty_get_lock( 0 );
    478         _puts("[GIET ERROR] in _hba_init() : command list unmapped\n");
    479         _tty_release_lock( 0 );
     384        _printf("[GIET ERROR] in _hba_init() : command list unmapped\n");
    480385        return 1;
    481386    }
     
    492397        if ( fail )
    493398        {
    494             _tty_get_lock( 0 );
    495             _puts("[GIET ERROR] in _hba_init() : command table unmapped\n");
    496             _tty_release_lock( 0 );
     399            _printf("[GIET ERROR] in _hba_init() : command table unmapped\n");
    497400            return 1;
    498401        }
     
    513416}
    514417
     418/////////////////////////////////////////////////////////////////////////////////////
     419// This function returns the content of the HBA_PXIS register for a given channel,
     420// and reset this register to acknoledge IRQ.
     421// return 0 if success, > 0 if error
     422/////////////////////////////////////////////////////////////////////////////////////
     423unsigned int _hba_get_status( unsigned int channel )
     424{
     425
     426    if( channel >= NB_IOC_CHANNELS )
     427    {
     428        _printf("\n[GIET ERROR] in _hba_get_status() : illegal channel\n");
     429        _exit();
     430    }
     431
     432    // get HBA_PXIS value
     433    unsigned int status = _hba_get_register( channel, HBA_PXIS );
     434
     435    // reset HBA_PXIS
     436    _hba_set_register( channel, HBA_PXIS, 0 );
     437
     438    return status;
     439}
    515440
    516441// Local Variables:
  • soft/giet_vm/giet_drivers/hba_driver.h

    r289 r295  
    5959} hba_cmd_entry_t;
    6060
    61 typedef struct hba_cmd_table_s  // size = 256 bytes
     61typedef struct hba_cmd_table_s  // size = 4096 bytes
    6262{
    6363
     
    9797///////////////////////////////////////////////////////////////////////////////////
    9898
    99 unsigned int _hba_write( unsigned int mode,
    100                          unsigned int lba,       // logic bloc address on device
    101                          void*        buffer,    // memory buffer base address
    102                          unsigned int count );   // number of blocs
     99extern unsigned int _hba_init ( unsigned int channel );
    103100
    104 unsigned int _hba_read ( unsigned int mode,
    105                          unsigned int lba,       // logic bloc address on device
    106                          void*        buffer,    // memory buffer base address
    107                          unsigned int count );   // number of blocks
     101extern unsigned int _hba_write( unsigned int channel,     // channel index
     102                                unsigned int mode,        // BOOT / KERNEL / USER
     103                                unsigned int lba,         // logic bloc address on device
     104                                unsigned long long paddr, // memory buffer base address
     105                                unsigned int count );     // number of blocs
    108106
    109 unsigned int _hba_init ( unsigned int channel );
     107extern unsigned int _hba_read ( unsigned int channel,     // channel index
     108                                unsigned int mode,        // BOOT / KERNEL / USER
     109                                unsigned int lba,         // logic bloc address on device
     110                                unsigned long long paddr, // memory buffer base address
     111                                unsigned int count );     // number of blocks
    110112
    111 unsigned int _hba_get_status( unsigned int   channel,
    112                               unsigned int*  status );
     113extern unsigned int _hba_get_status( unsigned int   channel );
    113114
    114 unsigned int _hba_reset_status( unsigned int channel );
    115 
    116 unsigned int _hba_get_block_size ();
     115extern unsigned int _hba_get_block_size ();
    117116
    118117
  • soft/giet_vm/giet_drivers/icu_driver.c

    r263 r295  
    7070
    7171#if USE_XICU
    72     _puts("[GIET ERROR] _icu_set_mask() should not be used if USE_XICU is set\n");
     72    _printf("[GIET ERROR] _icu_set_mask() should not be used if USE_XICU is set\n");
    7373    return 1;
    7474#else
     
    9898
    9999#if USE_XICU
    100     _puts("[GIET ERROR] _icu_get_index() should not be used if USE_XICU is set\n");
     100    _printf("[GIET ERROR] _icu_set_mask() should not be used if USE_XICU is set\n");
    101101    return 1;
    102102#else
  • soft/giet_vm/giet_drivers/ioc_driver.c

    r289 r295  
    77///////////////////////////////////////////////////////////////////////////////////
    88// The ioc_driver.c and ioc_driver.h files are part ot the GIET-VM kernel.
    9 // This driver supports the SocLib vci_block_device component, that is
    10 // a single channel, block oriented, external storage contrÃŽler.
    11 //
    12 // It can exist only one block-device controler in the architecture.
    13 //
    14 // The _ioc_read() and _ioc_write() functions use the _ioc_access() function,
    15 // that is always blocking. The _ioc_access function will call the read or
    16 // write function in the driver of the choosen IOC peripheral, which can be for
    17 // now: BDV, HBA and SPI. This function can be called in 4 modes:
    18 //
    19 // - In BOOT_PA mode, the _ioc_access() function use the buffer virtual address
    20 //   as a physical address (as the page tables are not build). This mode is
    21 //   used by the boot code to load the map.bin file into memory.
    22 //
    23 // - In BOOT_VA mode, the _ioc_access() function makes a V2P translation to
    24 //   compute the buffer physical address. This mode is used by the boot code to
    25 //   load the various .elf files into memory.
    26 //
    27 // - In KERNEL mode, the _ioc_access() function makes a V2P translation to
    28 //   compute the buffer physical address. There is no checking of user access
    29 //   right to the memory buffer.  This mode must be used to access IOC, for an
    30 //   "open" system call.
    31 //
    32 // - In USER mode, the _ioc_access() function makes a V2P translation to
    33 //   compute the buffer physical address. The user access right to the memory
    34 //   buffer must be checked.  This mode must be used to access IOC, for a
    35 //   "read/write" system call.
     9//
     10// This abstact driver define a generic API, supporting various physical
     11// block device controlers, including:
     12// - vci_block_device : single channel)                    => bdv_driver
     13// - vci_ahci         : multi channels                     => hba_driver
     14// - sd_card          : single channel                     => sdc_driver
     15// - ramdisk (single channel meory mapped virtual disk)    => rdk_driver
     16//
     17// It can exist only one block-device type in the architecture, that must be
     18// defined by one of the following configuration variables in hard_config.h file:
     19// USE_IOC_BDV, USE_IOC_SDC, USE_IOC_HBA, USE_IOC_RDK.
     20//
     21// Any physical driver xxx must provide the following API:
     22// - _xxx_init()
     23// - _xxx_read()
     24// - _xxx_write()
     25// - _xxx_get_status()
     26// - _xxx_get_block_size()
     27// The "channel" parameter is no transmited to single channel devices.
     28//
     29// The _ioc_read() and _ioc_write() functions are always blocking for
     30// the calling user program.
     31//
     32// These functions compute the physical address of the memory buffer before
     33// calling the proper physical device. They can be called in 3 modes:
     34//
     35// - In BOOT mode, these functions use the buffer virtual address
     36//   as a physical address if the MMU is not activated.
     37//   They make a V2P translation if the MMU is activated.
     38//   This mode is used to load the map.bin file (before memory activation),
     39//   or to load the various .elf files (after MMU activation).
     40//
     41// - In KERNEL mode, these functions make a V2P translation to
     42//   compute the buffer physical address.
     43//   There is no checking of user access right to the memory buffer. 
     44//   This mode must be used for an "open" system call.
     45//
     46// - In USER mode, these functions make a V2P translation to
     47//   compute the buffer physical address.
     48//   The user access right to the memory buffer are checked. 
     49//   This mode must be used for a "read" or "write" system call.
    3650//
    3751// The IOMMU can be activated or not:
     
    6074//   if the IOMMU is not activated.
    6175// An error code is returned if these conditions are not verified.
     76//
     77// The "seg_ioc_base" virtual base address of the segment containing the
     78// memory-mapped registers of the device must be defined in the giet_vsegs.ld file.
     79// If the RAMDISK is used, an extra memory segment with virtual base address
     80// "seg_ramdisk_base" must be defined in the giet_vsegs.ld file.
    6281///////////////////////////////////////////////////////////////////////////////////
    63 // The seg_ioc_base virtual base addresses must be defined in giet_vsegs.ld file.
     82// Implementation note:
     83// In order to share the code, the two _ioc_read() and _ioc_write() functions
     84// call the same _ioc_access() function.
    6485///////////////////////////////////////////////////////////////////////////////////
    6586
    6687#include <giet_config.h>
    6788#include <ioc_driver.h>
     89#include <bdv_driver.h>
     90#include <hba_driver.h>
     91#include <sdc_driver.h>
     92#include <rdk_driver.h>
    6893#include <utils.h>
    6994#include <tty_driver.h>
     
    81106#endif
    82107
    83 #if (USE_BDV + USE_SPI + USE_HBA) != 1
    84 # error: You must use only one IOC controller (BDV or SPI or HBA)
    85 #endif
    86 
    87 #if USE_BDV
     108#if (USE_IOC_BDV + USE_IOC_SPI + USE_IOC_HBA + USE_IOC_RDK) != 1
     109# error: You must use only one IOC controller type (BDV or SPI or HBA or RDK)
     110#endif
     111
     112#if USE_IOC_BDV
    88113# include <bdv_driver.h>
    89114#endif
    90115
    91 #if USE_SPI
     116#if USE_IOC_SPI
    92117# include <sdc_driver.h>
    93118#endif
    94119
    95 #if USE_HBA
     120#if USE_IOC_HBA
    96121# include <hba_driver.h>
    97122#endif
    98123
     124#if USE_IOC_RDK
     125# include <rdk_driver.h>
     126#endif
     127
     128///////////////////////////////////////////////////////////////////////////////
     129// IOC global variables
     130///////////////////////////////////////////////////////////////////////////////
    99131
    100132#define in_unckdata __attribute__((section (".unckdata")))
    101133
    102 ///////////////////// IOC global variables
    103 
    104 in_unckdata unsigned int _ioc_lock = 0;
    105 in_unckdata unsigned int _ioc_status = 0;
    106 in_unckdata volatile unsigned int _ioc_gtid;
    107134in_unckdata volatile unsigned int _ioc_iommu_ix1 = 0;
    108135in_unckdata volatile unsigned int _ioc_iommu_npages;
    109136
    110137///////////////////////////////////////////////////////////////////////////////
    111 //      _ioc_access()
    112138// This function transfer data between a memory buffer and the block device.
    113139// The buffer lentgth is (count*block_size) bytes.
    114140// Arguments are:
    115141// - to_mem     : from external storage to memory when non 0.
    116 // - kernel     : kernel buffer with identity mapping when non 0.
     142// - mode       : BOOT_PA / BOOT_VA / KERNEL / USER
    117143// - lba        : first block index on the external storage.
    118144// - buf_vaddr  : virtual base address of the memory buffer.
     
    121147///////////////////////////////////////////////////////////////////////////////
    122148static unsigned int _ioc_access( unsigned int to_mem,
     149                                 unsigned int channel,
    123150                                 unsigned int mode,
    124151                                 unsigned int lba,
     
    128155
    129156#if GIET_DEBUG_IOC_DRIVER
    130 _tty_get_lock( 0 );
    131 _puts("\n[IOC DEBUG] Enter _ioc_access() at cycle ");
    132 _putd( _get_proctime() );
    133 _puts(" for processor ");
    134 _putd( _get_procid() );
    135 _puts("\n - mode    = ");
    136 _putd( mode );
    137 _puts("\n - vaddr   = ");
    138 _putx( buf_vaddr );
    139 _puts("\n - sectors = ");
    140 _putd( count );
    141 _puts("\n - lba     = ");
    142 _putx( lba );
    143 _puts("\n");
    144 _tty_release_lock( 0 );
     157unsigned int procid  = _get_procid();
     158unsigned int cid     = procid / NB_PROCS_MAX;
     159unsigned int lpid    = procid % NB_PROCS_MAX;
     160unsigned int x       = cid >> Y_WIDTH;
     161unsigned int y       = cid & ((1<<Y_WIDTH) - 1);
     162
     163_printf("\n[IOC DEBUG] Processor[%d,%d,%d] enters _ioc_access() at cycle %d\n"
     164        " - channel  = %d\n"
     165        " - mode     = %d\n"
     166        " - vaddr    = %d\n"
     167        " - sectors  = %d\n"
     168        " - lba      = %d\n",
     169        x, y, lpid, _get_proctime(), channel, mode, buf_vaddr, count, lba );
    145170#endif
    146171
     
    160185    if ((unsigned int) buf_vaddr & 0x3)
    161186    {
    162         _tty_get_lock( 0 );
    163         _puts("\n[GIET ERROR] in _ioc_access() : buffer not word aligned\n");
    164         _tty_release_lock( 0 );
    165         return 1;
     187        _printf("\n[GIET ERROR] in _ioc_access() : buffer not word aligned\n");
     188        _exit();
     189    }
     190
     191    // check channel
     192    if ( (USE_IOC_HBA == 0) && (channel > 0) )
     193    {
     194        _printf("\n[GIET ERROR] in _ioc_access() : channel must be 0 when HBA not used\n");
     195        _exit();
    166196    }
    167197
    168198    unsigned int length = count << 9;  // count * 512 bytes
    169199
    170     // computing target buffer physical address
    171     if ( mode == IOC_BOOT_PA_MODE )                // identity mapping
     200    // computing memory buffer physical address
     201    if ( (mode == IOC_BOOT_MODE) && ((_get_mmu_mode() & 0x4) == 0) ) // identity mapping
    172202    {
    173203        buf_paddr = (paddr_t)buf_vaddr;
    174204    }
    175     else                                           // V2P translation
     205    else                                                    // V2P translation required
    176206    {
    177207        // get page table virtual address
    178208        pt_vbase = _get_context_slot(CTX_PTAB_ID);
    179         vpn_min = buf_vaddr >> 12;
    180         vpn_max = (buf_vaddr + length - 1) >> 12;
     209        vpn_min  = buf_vaddr >> 12;
     210        vpn_max  = (buf_vaddr + length - 1) >> 12;
    181211
    182212        // loop on all virtual pages covering the user buffer
    183         for (vpn = vpn_min, ix2 = 0 ;
    184              vpn <= vpn_max ;
    185              vpn++, ix2++ )
     213        for (vpn = vpn_min, ix2 = 0 ; vpn <= vpn_max ; vpn++, ix2++ )
    186214        {
    187215            // get ppn and flags for each vpn
     
    193221            if ( ko )
    194222            {
    195                 _tty_get_lock( 0 );
    196                 _puts("\n[GIET ERROR] in _ioc_access() : buffer unmapped\n");
    197                 _tty_release_lock( 0 );
     223                _printf("\n[GIET ERROR] in _ioc_access() : buffer unmapped\n");
    198224                return 1;
    199225            }
     
    201227            if ( (mode == IOC_USER_MODE) && ((flags & PTE_U) == 0) )
    202228            {
    203                 _tty_get_lock( 0 );
    204                 _puts("\n[GIET ERROR] in _ioc_access() : buffer not user accessible\n");
    205                 _tty_release_lock( 0 );
     229                _printf("\n[GIET ERROR] in _ioc_access() : buffer not user accessible\n");
    206230                return 1;
    207231            }
     
    209233            if ( ((flags & PTE_W) == 0 ) && to_mem )
    210234            {
    211                 _tty_get_lock( 0 );
    212                 _puts("\n[GIET ERROR] in _ioc_access() : buffer not writable\n");
    213                 _tty_release_lock( 0 );
     235                _printf("\n[GIET ERROR] in _ioc_access() : buffer not writable\n");
    214236                return 1;
    215237            }
     
    223245            if (ix2 > 511) // check buffer length < 2 Mbytes
    224246            {
    225                 _tty_get_lock( 0 );
    226                 _puts("\n[GIET ERROR] in _ioc_access() : user buffer > 2 Mbytes\n");
    227                 _tty_release_lock( 0 );
     247                _printf("\n[GIET ERROR] in _ioc_access() : user buffer > 2 Mbytes\n");
    228248                return 1;
    229249            }
     
    242262            if ((ppn - ppn_first) != ix2)
    243263            {
    244                 _tty_get_lock( 0 );
    245                 _puts("[GIET ERROR] in _ioc_access() : split physical buffer\n");
    246                 _tty_release_lock( 0 );
     264                _printf("[GIET ERROR] in _ioc_access() : split physical buffer\n");
    247265                return 1;
    248266            }
     
    272290    else         // memory read : update data caches
    273291    {
    274         // L1 cache : nothing to do if L1 write-through
     292        // L1 cache : nothing to do for L1 write-through
    275293
    276294        // L2 cache (only if IOB used)
     
    280298    if ( GIET_USE_IOMMU ) buf_paddr = (paddr_t) buf_xaddr;
    281299
    282 #if   USE_BDV
    283     if (to_mem) error = _bdv_read (mode, lba, buf_paddr, count);
    284     else        error = _bdv_write(mode, lba, buf_paddr, count);
    285 #elif USE_SPI
    286     if (to_mem) error = _sdc_read (mode, lba, buf_paddr, count);
    287     else        error = _sdc_write(mode, lba, buf_paddr, count);
    288 #elif USE_HBA
    289     if (to_mem) error = _hba_read (mode, lba, buf_paddr, count);
    290     else        error = _hba_write(mode, lba, buf_paddr, count);
     300    ///////////////////////////////////////////
     301    // select the proper physical device
     302    ///////////////////////////////////////////
     303
     304#if       ( USE_IOC_BDV )
     305
     306#if GIET_DEBUG_IOC_DRIVER
     307_printf("\n[IOC DEBUG] Calling BDV driver\n");
     308#endif
     309        if (to_mem) error = _bdv_read ( mode, lba, buf_paddr, count);
     310        else        error = _bdv_write( mode, lba, buf_paddr, count);
     311
     312#elif ( USE_IOC_SPI )
     313
     314#if GIET_DEBUG_IOC_DRIVER
     315_printf("\n[IOC DEBUG] Calling SPI driver\n");
     316#endif
     317        if (to_mem) error = _sdc_read (mode, lba, buf_paddr, count);
     318        else        error = _sdc_write(mode, lba, buf_paddr, count);
     319
     320#elif ( USE_IOC_HBA )
     321
     322#if GIET_DEBUG_IOC_DRIVER
     323_printf("\n[IOC DEBUG] Calling HBA driver\n");
     324#endif
     325        if (to_mem) error = _hba_read (channel, mode, lba, buf_paddr, count);
     326        else        error = _hba_write(channel, mode, lba, buf_paddr, count);
     327
     328#elif ( USE_IOC_RDK )
     329
     330#if GIET_DEBUG_IOC_DRIVER
     331_printf("\n[IOC DEBUG] Calling RDK driver\n");
     332#endif
     333        if (to_mem) error = _rdk_read (lba, buf_vaddr, count);
     334        else        error = _rdk_write(lba, buf_vaddr, count);
     335
    291336#endif
    292337
     
    295340
    296341///////////////////////////////////////////////////////////////////////////////
    297 //       _ioc_init()
    298342// This function cheks block size, and activates the IOC interrupts.
    299343// Return 0 for success.
     
    301345unsigned int _ioc_init( unsigned int channel )
    302346{
    303 #if   USE_BDV
    304     return _bdv_init( channel );
    305 #elif USE_SPI
    306     return _sdc_init( channel );
    307 #elif USE_HBA
     347
     348#if   ( USE_IOC_BDV )
     349
     350    return _bdv_init();
     351
     352#elif ( USE_IOC_SPI )
     353
     354    return _sdc_init();
     355   
     356#elif ( USE_IOC_HBA )
     357
    308358    return _hba_init( channel );
    309 #endif
     359   
     360#elif ( USE_IOC_RDK )
     361
     362    return _rdk_init();
     363   
     364#endif
     365   
    310366}
    311367
    312368///////////////////////////////////////////////////////////////////////////////
    313 //     _ioc_read()
    314369// Transfer data from the block device to a memory buffer.
    315 // - mode     : BOOT / KERNEL / USER
     370// - mode     : BOOT_PA / BOOT_VA / KERNEL / USER
    316371// - lba      : first block index on the block device
    317372// - buffer   : base address of the memory buffer (must be word aligned)
     
    319374// Returns 0 if success, > 0 if error.
    320375///////////////////////////////////////////////////////////////////////////////
    321 unsigned int _ioc_read( unsigned int mode, 
     376unsigned int _ioc_read( unsigned int channel,
     377                        unsigned int mode, 
    322378                        unsigned int lba,
    323379                        void*        buffer,
     
    325381{
    326382    return _ioc_access( 1,        // read access
     383                        channel,
    327384                        mode, 
    328385                        lba,
     
    332389
    333390///////////////////////////////////////////////////////////////////////////////
    334 //     _ioc_write()
    335391// Transfer data from a memory buffer to the block device.
    336 // - mode     : BOOT / KERNEL / USER
     392// - mode     : BOOT_PA / BOOT_VA / KERNEL / USER
    337393// - lba      : first block index on the block device
    338394// - buffer   : base address of the memory buffer (must be word aligned)
     
    340396// Returns 0 if success, > 0 if error.
    341397///////////////////////////////////////////////////////////////////////////////
    342 unsigned int _ioc_write( unsigned int mode, 
     398unsigned int _ioc_write( unsigned int channel,
     399                         unsigned int mode, 
    343400                         unsigned int lba,
    344401                         const void*  buffer,
     
    346403{
    347404    return _ioc_access( 0,        // write access
     405                        channel,
    348406                        mode, 
    349407                        lba,
     
    353411
    354412///////////////////////////////////////////////////////////////////////////////
    355 //     _ioc_get_status()
    356413// This function returns in the status variable, the transfert status, and
    357414// acknowledge the IRQ if the IOC controler is not busy.
    358415// Returns 0 if success, > 0 if error
    359416///////////////////////////////////////////////////////////////////////////////
    360 unsigned int _ioc_get_status( unsigned int  channel,
    361                               unsigned int* status )
    362 {
    363 #if   USE_BDV
    364     return _bdv_get_status(channel, status);
    365 #elif USE_SPI
    366     return _sdc_get_status(channel, status);
    367 #elif USE_HBA
    368     return _hba_get_status(channel, status);
    369 #endif
     417unsigned int _ioc_get_status( unsigned int  channel )
     418{
     419
     420#if   ( USE_IOC_BDV )
     421
     422    return _bdv_get_status( );
     423
     424#elif ( USE_IOC_SPI )
     425
     426    return _sdc_get_status( );
     427
     428#elif ( USE_IOC_HBA )
     429
     430    return _hba_get_status( channel );
     431
     432#elif ( USE_IOC_RDK )
     433
     434    _printf("[GIET ERROR] _ioc_get_status() should not be called");
     435    _printf(" when RAMDISK  is used...\n");
     436    _exit();
     437
     438    return 0;
     439
     440#endif
     441
    370442}
    371443
    372444///////////////////////////////////////////////////////////////////////////////
    373 //     _ioc_get_block_size()
    374445// This function returns the block_size with which the IOC has been configured.
    375446///////////////////////////////////////////////////////////////////////////////
    376447unsigned int _ioc_get_block_size()
    377448{
    378 #if   USE_BDV
     449
     450#if   ( USE_IOC_BDV )
     451
    379452    return _bdv_get_block_size();
    380 #elif USE_SPI
     453   
     454#elif ( USE_IOC_SPI )
     455
    381456    return _sdc_get_block_size();
    382 #elif USE_HBA
     457   
     458#elif ( USE_IOC_HBA )
     459
    383460    return _hba_get_block_size();
    384 #endif
     461   
     462#elif ( USE_IOC_RDK )
     463
     464    return 512;
     465
     466#endif
     467
    385468}
    386469
  • soft/giet_vm/giet_drivers/ioc_driver.h

    r289 r295  
    1313///////////////////////////////////////////////////////////////////////////////////
    1414
    15 enum IOC_registers
    16 {
    17     BLOCK_DEVICE_BUFFER,
    18     BLOCK_DEVICE_LBA,
    19     BLOCK_DEVICE_COUNT,
    20     BLOCK_DEVICE_OP,
    21     BLOCK_DEVICE_STATUS,
    22     BLOCK_DEVICE_IRQ_ENABLE,
    23     BLOCK_DEVICE_SIZE,
    24     BLOCK_DEVICE_BLOCK_SIZE,
    25     BLOCK_DEVICE_BUFFER_EXT,
    26 };
    27 enum IOC_operations
    28 {
    29     BLOCK_DEVICE_NOOP,
    30     BLOCK_DEVICE_READ,
    31     BLOCK_DEVICE_WRITE,
    32 };
    33 enum IOC_status
    34 {
    35     BLOCK_DEVICE_IDLE,
    36     BLOCK_DEVICE_BUSY,
    37     BLOCK_DEVICE_READ_SUCCESS,
    38     BLOCK_DEVICE_WRITE_SUCCESS,
    39     BLOCK_DEVICE_READ_ERROR,
    40     BLOCK_DEVICE_WRITE_ERROR,
    41     BLOCK_DEVICE_ERROR,
    42 };
    4315enum IOC_driver_modes
    4416{
    45     IOC_BOOT_PA_MODE,  // No V2P translation / Polling IOC_STATUS / no access checking
    46     IOC_BOOT_VA_MODE,  // V2P translation    / Polling IOC_STATUS / no access checking
    47     IOC_KERNEL_MODE,   // V2P translation    / Descheduling + IRQ / no access checking
    48     IOC_USER_MODE,     // V2P translation    / Descheduling + IRQ / access checking
     17    IOC_BOOT_MODE   = 0,     //  Polling IOC_STATUS / no access right checking
     18    IOC_KERNEL_MODE = 1,     //  Descheduling + IRQ / no access right checking
     19    IOC_USER_MODE   = 2,     //  Descheduling + IRQ / access right checking
    4920};
    5021
    5122///////////////////////////////////////////////////////////////////////////////////
    52 // IOC access functions and variables (vci_block_device)
     23// IOC global variables (generic disk controller)
    5324///////////////////////////////////////////////////////////////////////////////////
    5425
    55 extern unsigned int _ioc_lock;
    56 extern unsigned int _ioc_status;
    57 extern volatile unsigned int _ioc_gtid;
    5826extern volatile unsigned int _ioc_iommu_ix1;
    5927extern volatile unsigned int _ioc_iommu_npages;
    6028
     29///////////////////////////////////////////////////////////////////////////////////
     30// IOC access functions  (generic disk controller)
     31///////////////////////////////////////////////////////////////////////////////////
     32
    6133extern unsigned int _ioc_init( unsigned int channel );
    6234
    63 extern unsigned int _ioc_write( unsigned int mode,
     35extern unsigned int _ioc_write( unsigned int channel,
     36                                unsigned int mode,
    6437                                unsigned int lba,
    6538                                const void*  buffer,
    6639                                unsigned int count );
    6740
    68 extern unsigned int _ioc_read(  unsigned int mode,
     41extern unsigned int _ioc_read(  unsigned int channel,
     42                                unsigned int mode,
    6943                                unsigned int lba,
    7044                                void*        buffer,
    7145                                unsigned int count );
    7246
    73 extern unsigned int _ioc_get_status( unsigned int  channel,
    74                                      unsigned int* status );
     47extern unsigned int _ioc_get_status( unsigned int channel );
    7548
    7649extern unsigned int _ioc_get_block_size();
  • soft/giet_vm/giet_drivers/mmc_driver.c

    r263 r295  
    5757    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
    5858    {
    59         _puts("\n[GIET ERROR] in _memc_inval() : illegal cluster index[");
    60         _putd( x );
    61         _puts(",");
    62         _putd( y );
    63         _puts("]\n");
    64         _puts("   - paddr      = ");
    65         _putl( buf_paddr );
    66         _puts("\n   - cluster_xy = ");
    67         _putx( cluster_xy );
    68         _puts("\n");
     59        _printf("\n[GIET ERROR] in _memc_inval() : illegal cluster_xy for paddr %l\n",
     60                 buf_paddr );
    6961        _exit();
    7062    }
     
    10294    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
    10395    {
    104         _puts("\n[GIET ERROR] in _memc_sync() : illegal cluster index[");
    105         _putd( x );
    106         _puts(",");
    107         _putd( y );
    108         _puts("]\n");
    109         _puts("   - paddr      = ");
    110         _putl( buf_paddr );
    111         _puts("\n   - cluster_xy = ");
    112         _putx( cluster_xy );
    113         _puts("\n");
     96        _printf( "\n[GIET ERROR] in _memc_sync() : illegal cluster_xy for paddr %l\n",
     97                 buf_paddr );
    11498        _exit();
    11599    }
  • soft/giet_vm/giet_drivers/mwr_driver.c

    r263 r295  
    5656                           paddr_t                channel_pbase )
    5757{
    58     _puts(" [GIET_ERROR] _mwr_hw_init() function not supported yet\n");
     58    _printf(" [GIET_ERROR] _mwr_hw_init() function not supported yet\n");
    5959    _exit();
    6060
  • soft/giet_vm/giet_drivers/nic_driver.c

    r258 r295  
    5656#define in_unckdata __attribute__((section (".unckdata")))
    5757
     58///////////////////////////////////////////////////////////////////////////////
     59// This low_level function returns the value contained in register (index).
     60///////////////////////////////////////////////////////////////////////////////
     61unsigned int _nic_get_register( unsigned int channel,
     62                                unsigned int index )
     63{
     64    unsigned int* vaddr = (unsigned int*)&seg_nic_base +
     65                           NIC_CHANNEL_SPAN*channel + index;
     66    return _io_extended_read( vaddr );
     67}
     68
     69///////////////////////////////////////////////////////////////////////////////
     70// This low-level function set a new value in register (index).
     71///////////////////////////////////////////////////////////////////////////////
     72void _nic_set_register( unsigned int channel,
     73                        unsigned int index,
     74                        unsigned int value )
     75{
     76    unsigned int* vaddr = (unsigned int*)&seg_nic_base +
     77                           NIC_CHANNEL_SPAN*channel + index;
     78    _io_extended_write( vaddr, value );
     79}
     80
    5881//////////////////////////////////////////////////////////////////////////////////
    59 // _nic_sync_write()
    6082// Transfer data from an memory buffer to the NIC device using a memcpy.
    6183// - buffer : base address of the memory buffer.
     
    6587                              unsigned int   length )
    6688{
    67     _puts("[GIET ERROR] _nic_sync_write function not implemented\n");
     89    _printf("[GIET ERROR] _nic_sync_write function not implemented\n");
    6890    _exit();
    6991
     
    7395}
    7496//////////////////////////////////////////////////////////////////////////////////
    75 // _nic_sync_read()
    7697// Transfer data from the NIC device to a memory buffer using a memcpy.
    7798// - buffer : base address of the memory buffer.
     
    81102                             unsigned int   length )
    82103{
    83     _puts("[GIET ERROR] _nic_sync_read function not implemented\n");
     104    _printf("[GIET ERROR] _nic_sync_read function not implemented\n");
    84105    _exit();
    85106
     
    89110}
    90111//////////////////////////////////////////////////////////////////////////////////
    91 // _nic_cma_start()
    92112// Returns 0 if success, > 0 if error.
    93113//////////////////////////////////////////////////////////////////////////////////
    94114unsigned int _nic_cma_start( )
    95115{
    96     _puts("[GIET ERROR] _nic_cma_start function not implemented\n");
     116    _printf("[GIET ERROR] _nic_cma_start() not implemented\n");
    97117    _exit();
    98118
     
    101121}
    102122//////////////////////////////////////////////////////////////////////////////////
    103 // _nic_cma_stop()
    104123// Returns 0 if success, > 0 if error.
    105124//////////////////////////////////////////////////////////////////////////////////
    106125unsigned int _nic_cma_stop()
    107126{
    108     _puts("[GIET ERROR] _nic_cma_stop function not implemented\n");
     127    _printf("[GIET ERROR] _nic_cma_stop() not implemented\n");
    109128    _exit();
    110129
     
    113132}
    114133
     134//////////////////////////////////////////////////////////////////////////////////
     135// This ISR handles IRQx from a NIC RX channeL
     136//////////////////////////////////////////////////////////////////////////////////
     137void _nic_rx_isr( unsigned int irq_type,
     138                  unsigned int irq_id,
     139                  unsigned int channel )
     140{
     141    _printf("[GIET ERROR] _nic_rx_isr() not implemented\n");
     142    _exit();
     143}
     144
     145//////////////////////////////////////////////////////////////////////////////////
     146// This ISR handles IRQx from a NIC RX channeL
     147//////////////////////////////////////////////////////////////////////////////////
     148void _nic_tx_isr( unsigned int irq_type,
     149                  unsigned int irq_id,
     150                  unsigned int channel )
     151{
     152    _printf("[GIET ERROR] _nic_tx_isr() not implemented\n");
     153    _exit();
     154}
    115155
    116156// Local Variables:
  • soft/giet_vm/giet_drivers/nic_driver.h

    r258 r295  
    88#ifndef _GIET_NIC_DRIVERS_H_
    99#define _GIET_NIC_DRIVERS_H_
     10
     11///////////////////////////////////////////////////////////////////////////////////
     12// NIC Registers  (vci_multi_nic)
     13///////////////////////////////////////////////////////////////////////////////////
     14
     15enum SoclibMultiNicHyperviseurRegisters {
     16    NIC_G_VIS                        = 0,   // bitfield : bit N = 0 -> channel N disabled
     17    NIC_G_ON                         = 1,   // boolean : NIC component activated
     18    NIC_G_NB_CHAN                    = 2,   // Number of channels present in this NIC (read only)
     19    NIC_G_BC_ENABLE                  = 3,   // boolean : Enable Broadcast if non zero
     20    NIC_G_TDM_ENABLE                 = 4,   // boolean : TDM Scheduler if non zero
     21    NIC_G_TDM_PERIOD                 = 5,   // TDM time slot value
     22    NIC_G_BYPASS_ENABLE              = 6,   // boolean : Enable bypass for TX packets
     23    // alignment
     24    NIC_G_MAC_4                      = 8,   // channel mac address 32 LSB bits array[8]
     25    NIC_G_MAC_2                      = 16,  // channel mac address 16 MSB bits array[8]
     26    // alignment
     27    NIC_G_NPKT_RX_G2S_RECEIVED       = 32,  // number of packets received on GMII RX port
     28    NIC_G_NPKT_RX_G2S_DISCARDED      = 33,  // number of RX packets discarded by RX_G2S FSM
     29
     30    NIC_G_NPKT_RX_DES_SUCCESS        = 34,  // number of RX packets transmited by RX_DES FSM
     31    NIC_G_NPKT_RX_DES_TOO_SMALL      = 35,  // number of discarded too small RX packets (<60B)
     32    NIC_G_NPKT_RX_DES_TOO_BIG        = 36,  // number of discarded too big RX packets (>1514B)
     33    NIC_G_NPKT_RX_DES_MFIFO_FULL     = 37,  // number of discarded RX packets because fifo full
     34    NIC_G_NPKT_RX_DES_CRC_FAIL       = 38,  // number of discarded RX packets because CRC32 failure
     35
     36    NIC_G_NPKT_RX_DISPATCH_RECEIVED  = 39,  // number of packets received by RX_DISPATCH FSM
     37    NIC_G_NPKT_RX_DISPATCH_BROADCAST = 40,  // number of broadcast RX packets received
     38    NIC_G_NPKT_RX_DISPATCH_DST_FAIL  = 41,  // number of discarded RX packets for DST MAC not found
     39    NIC_G_NPKT_RX_DISPATCH_CH_FULL   = 42,  // number of discarded RX packets for channel full
     40
     41    NIC_G_NPKT_TX_DISPATCH_RECEIVED  = 43,  // number of packets received by TX_DISPATCH FSM
     42    NIC_G_NPKT_TX_DISPATCH_TOO_SMALL = 44,  // number of discarded too small TX packets (<60B)
     43    NIC_G_NPKT_TX_DISPATCH_TOO_BIG   = 45,  // number of discarded too big TX packets (>1514B)
     44    NIC_G_NPKT_TX_DISPATCH_SRC_FAIL  = 46,  // number of discarded TX packets for SRC MAC failed
     45    NIC_G_NPKT_TX_DISPATCH_BROADCAST = 47,  // number of broadcast TX packets received
     46    NIC_G_NPKT_TX_DISPATCH_BYPASS    = 48,  // number of bypassed TX->RX packets
     47    NIC_G_NPKT_TX_DISPATCH_TRANSMIT  = 49,  // number of transmit TX packets
     48
     49    NIC_CHANNEL_SPAN                 = 0x2000,
     50};
     51
     52/////////////////////////////////////////////////////////////////////
     53// A container descriptor has the following form:
     54// LOW WORD : Container LSB base address     
     55// HIGH WORD: Container status (leftmost bit), '1' means full
     56//            Base address MSB extension, if needed (right aligned)
     57//////////////////////////////////////////////////////////////////////
     58enum SoclibMultiNicChannelRegisters
     59{
     60    NIC_RX_DESC_LO_0          = 0,   // RX_0 descriptor low word         (Read/Write)
     61    NIC_RX_DESC_HI_0          = 1,   // RX_0 descriptor high word        (Read/Write)
     62    NIC_RX_DESC_LO_1          = 2,   // RX_1 descriptor low word         (Read/Write)
     63    NIC_RX_DESC_HI_1          = 3,   // RX_1 descriptor high word        (Read/Write)
     64    NIC_TX_DESC_LO_0          = 4,   // TX_0 descriptor low word         (Read/Write)
     65    NIC_TX_DESC_HI_0          = 5,   // TX_0 descriptor high word        (Read/Write)
     66    NIC_TX_DESC_LO_1          = 6,   // TX_1 descriptor low word         (Read/Write)
     67    NIC_TX_DESC_HI_1          = 7,   // TX_1 descriptor high word        (Read/Write)
     68    NIC_MAC_4                 = 8,   // channel mac address 32 LSB bits  (Read Only)
     69    NIC_MAC_2                 = 9,   // channel mac address 16 LSB bits  (Read Only)
     70    NIC_RX_RUN                = 10,  // RX packets can be received       (write_only)
     71    NIC_TX_RUN                = 11,  // TX packets can be transmitted    (write_only)
     72};
    1073
    1174///////////////////////////////////////////////////////////////////////////////////
     
    2386extern unsigned int _nic_cma_stop();
    2487
     88extern void _nic_rx_isr( unsigned int irq_type,
     89                         unsigned int irq_id,
     90                         unsigned int channel );
     91
     92extern void _nic_tx_isr( unsigned int irq_type,
     93                         unsigned int irq_id,
     94                         unsigned int channel );
     95
    2596///////////////////////////////////////////////////////////////////////////////////
    2697
  • soft/giet_vm/giet_drivers/sdc_driver.c

    r289 r295  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
     7
    78#include <sdc_driver.h>
     9#include <tty_driver.h>
    810#include <utils.h>
    911
     
    179181        if ( sdcard_rsp != 0x01 )
    180182        {
    181 
    182                 _puts("card CMD0 failed ");
     183                _printf("[SDC ERROR] card CMD0 failed\n");
    183184                return sdcard_rsp;
    184185        }
     
    196197        if (!SDCARD_CHECK_R1_VALID(sdcard_rsp))
    197198    {
    198                 _puts("card CMD8 failed ");
     199                _printf("[SDC ERROR] card CMD8 failed\n");
    199200                return sdcard_rsp;
    200201        }
     
    206207                ersp = (ersp << 8) | _sdc_receive_char();
    207208                ersp = (ersp << 8) | _sdc_receive_char();
    208                 if ((ersp & 0xffff) != 0x0101) {
     209                if ((ersp & 0xffff) != 0x0101)
     210        {
    209211                        // voltage mismatch
    210                         _puts("card CMD8 mismatch: ");
    211                         _putx(ersp);
     212                        _printf("[SDC ERROR] card CMD8 mismatch : ersp = %x\n");
    212213                        return sdcard_rsp;
    213214                }
    214                 _puts("v2 or later ");
     215                _printf("[SDC WARNING] v2 or later ");
    215216                sdcard.sdhc = 1;
    216217        }
     
    218219    {
    219220                // other error
    220                 _puts("card CMD8 error ");
     221                _printf("[SDC ERROR] card CMD8 error\n");
    221222                return sdcard_rsp;
    222223        }
     
    249250        if (sdcard_rsp)
    250251    {
    251                 _puts("SD ACMD41 failed ");
     252                _printf("[SDC ERROR] ACMD41 failed\n");
    252253                return sdcard_rsp;
    253254        }
     
    263264                if (sdcard_rsp)
    264265        {
    265                         _puts("SD CMD58 failed ");
     266                        _printf("[SDC ERROR] CMD58 failed\n");
    266267                        return sdcard_rsp;
    267268                }
     
    272273                if (ersp & 0x40000000)
    273274        {
    274                         _puts("SDHC ");
    275                 } else
     275                        _printf(" SDHC ");
     276                }
     277        else
    276278        {
    277279                        sdcard.sdhc = 0;
     
    279281                _sdc_disable();
    280282        }
    281         _puts("card detected ");
     283        _printf("card detected\n");
    282284        return 0;
    283285}
     
    334336// Returns 0 if success, other value if failure
    335337///////////////////////////////////////////////////////////////////////////////
    336 unsigned int _sdc_init( unsigned int channel )
     338unsigned int _sdc_init()
    337339{
    338340    spi = (struct spi_dev*) &seg_ioc_base;
     
    355357    while(1)
    356358    {
    357         _puts("Trying to initialize SD card... ");
    358 
    359         sdcard_rsp = _sdc_open( channel );
     359        _printf("[SDC WARNING] Trying to initialize SD card...\n");
     360
     361        sdcard_rsp = _sdc_open( 0 );  // only channel 0
    360362        if (sdcard_rsp == 0)
    361363        {
    362             _puts("OK\n");
     364            _printf("OK\n");
    363365            break;
    364366        }
    365367
    366         _puts("KO\n");
     368        _printf("KO\n");
    367369
    368370        for (i = 0; i < 1000; i++);
     
    370372        if (++iter >= SDCARD_RESET_ITER_MAX)
    371373        {
    372             _puts("\nERROR: During SD card reset to IDLE state\n"
    373                  "/ card response = ");
    374             _putx(sdcard_rsp);
    375             _puts("\n");
     374            _printf("\n[SDC ERROR] During SD card reset to IDLE state "
     375                    "/ card response = %x\n", sdcard_rsp );
    376376            _exit();
    377377        }
     
    382382    if (sdcard_rsp)
    383383    {
    384         _puts("ERROR: During SD card blocklen initialization\n");
     384        _printf("[SDC ERROR] During SD card blocklen initialization\n");
    385385        _exit();
    386386    }
     
    396396    );
    397397
    398     _puts("Finish block device initialization\n\r");
     398    _printf("[SDC WARNING] Finish SD card initialization\n\r");
    399399
    400400    return 0;
     
    478478
    479479///////////////////////////////////////////////////////////////////////////////
    480 //     _sdc_get_status()
    481480// Transfer data from memory buffer to SD card device.
    482481// - channel: channel index
     
    484483// Returns 0 if success, > 0 if error.
    485484///////////////////////////////////////////////////////////////////////////////
    486 unsigned int _sdc_get_status( unsigned int channel ,
    487                               unsigned int* status )
    488 {
    489     *status = BLOCK_DEVICE_IDLE;
    490 
    491     return 0;
    492 }
    493 
    494 ///////////////////////////////////////////////////////////////////////////////
    495 //     _sdc_get_block_size()
     485unsigned int _sdc_get_status()
     486{
     487    _printf("[SDC ERROR] function _sdc_get_status() should not be called\n");
     488    _exit();
     489
     490    return 0;  // to avoid a warning
     491}
     492
     493///////////////////////////////////////////////////////////////////////////////
    496494// Returns the block size in bytes of the SD card
    497495///////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/giet_drivers/sdc_driver.h

    r289 r295  
    3636};
    3737
    38 unsigned int _sdc_init( unsigned int channel );
    39 
     38unsigned int _sdc_init();
    4039
    4140unsigned int _sdc_read( unsigned int mode,
     
    5049                         unsigned int count);
    5150
     51unsigned int _sdc_get_status();
     52
    5253unsigned int _sdc_get_block_size();
    53 
    54 unsigned int _sdc_get_status( unsigned int channel ,
    55                               unsigned int* status );
    5654
    5755
  • soft/giet_vm/giet_drivers/tim_driver.c

    r263 r295  
    1818// The global index is cluster_xy * (NB_PROCS_MAX + NB_TIM_CHANNELS) + local_id
    1919//
    20 // The NB_PROCS_MAX and NB_TIM_CHANNELS values must be defined in the
    21 // hard_config.h file.
    22 //
    23 // The register offsets must be defined in the hwr_mapping.h file.
     20// The NB_PROCS_MAX and NB_TIM_CHANNELS values must be defined in hard_config.h file.
    2421/////////////////////////////////////////////////////////////////////////////////////
    2522// The virtual base address of the segment associated to a channel is:
     
    3330#include <giet_config.h>
    3431#include <tim_driver.h>
     32#include <xcu_driver.h>
     33#include <tty_driver.h>
    3534#include <utils.h>
    3635
     
    6867
    6968#if (NB_TIM_CHANNELS > 0)
    70 in_unckdata volatile unsigned char _user_timer_event[X_SIZE*Y_SIZE*NB_TIM_CHANNELS]
    71                             = { [0 ... ((X_SIZE*Y_SIZE*NB_TIM_CHANNELS) - 1)] = 0 };
     69in_unckdata volatile unsigned char _user_timer_event[(1<<X_WIDTH)*(1<<Y_WIDTH)*NB_TIM_CHANNELS]
     70                        = { [0 ... (((1<<X_WIDTH)*(1<<Y_WIDTH)*NB_TIM_CHANNELS) - 1)] = 0 };
    7271#endif
    7372
    7473////////////////////////////////////////////////////////////////////////////////////
    75 //     _timer_start()
    7674// This function activates a timer in the vci_timer component
    7775// by writing in the proper register the period value.
    7876// It can be used by both the kernel to initialise a "system" timer,
    7977// or by a task (through a system call) to configure an "user" timer.
    80 // Returns 0 if success, > 0 if error.
    81 //////////////////////////////////////////////////////////////////////////////
    82 unsigned int _timer_start( unsigned int cluster_xy,
    83                            unsigned int local_id,
    84                            unsigned int period)
    85 {
    86     // parameters checking
    87     unsigned int x = cluster_xy >> Y_WIDTH;
    88     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    89     if (x >= X_SIZE)                  return 1;
    90     if (y >= Y_SIZE)                  return 1;
    91     if (local_id >= NB_TIM_CHANNELS)  return 1;
     78///////////////////////////////////////////////////////////////////////////////////
     79void _timer_start( unsigned int cluster_xy,
     80                   unsigned int local_id,
     81                   unsigned int period)
     82{
     83#if NB_TIM_CHANNELS
     84
     85    // parameters checking
     86    unsigned int x = cluster_xy >> Y_WIDTH;
     87    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     88    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) )
     89    {
     90        _printf("[GIET ERROR] in _timer_start()\n");
     91        _exit();
     92    }
    9293
    9394    unsigned int* timer_address = (unsigned int *) ((unsigned int)&seg_tim_base +
     
    9697    timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period;
    9798    timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0x3;
    98     return 0;
    99 }
    100 
    101 //////////////////////////////////////////////////////////////////////////////
    102 //     _timer_stop()
     99
     100#else
     101    _printf("[GIET ERROR] _timer_start() should not be called when NB_TIM_CHANNELS is 0\n");
     102    _exit();
     103#endif
     104}
     105
     106//////////////////////////////////////////////////////////////////////////////
    103107// This function desactivates a timer in the vci_timer component
    104108// by writing in the proper register.
    105109// Returns 0 if success, > 0 if error.
    106110//////////////////////////////////////////////////////////////////////////////
    107 unsigned int _timer_stop( unsigned int cluster_xy,
    108                           unsigned int local_id)
    109 {
    110     // parameters checking
    111     unsigned int x = cluster_xy >> Y_WIDTH;
    112     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    113     if (x >= X_SIZE)                  return 1;
    114     if (y >= Y_SIZE)                  return 1;
    115     if (local_id >= NB_TIM_CHANNELS)  return 1;
     111void _timer_stop( unsigned int cluster_xy,
     112                  unsigned int local_id)
     113{
     114#if NB_TIM_CHANNELS
     115
     116    // parameters checking
     117    unsigned int x = cluster_xy >> Y_WIDTH;
     118    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     119    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) )
     120    {
     121        _printf("[GIET ERROR] in _timer_stop()\n");
     122        _exit();
     123    }
    116124
    117125    unsigned int* timer_address = (unsigned int *) ((unsigned int)&seg_tim_base +
     
    119127
    120128    timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0;
    121     return 0;
    122 }
    123 
    124 //////////////////////////////////////////////////////////////////////////////
    125 //     _timer_reset_irq()
     129
     130#else
     131    _printf("[GIET ERROR] _timer_stop() should not be called when NB_TIM_CHANNELS is 0\n");
     132    _exit();
     133#endif
     134}
     135
     136//////////////////////////////////////////////////////////////////////////////
    126137// This function acknowlegge a timer interrupt in the vci_timer 
    127138// component by writing in the proper register.
     
    130141// Returns 0 if success, > 0 if error.
    131142//////////////////////////////////////////////////////////////////////////////
    132 unsigned int _timer_reset_irq( unsigned int cluster_xy,
    133                                unsigned int local_id )
    134 {
    135     // parameters checking
    136     unsigned int x = cluster_xy >> Y_WIDTH;
    137     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    138     if (x >= X_SIZE)                  return 1;
    139     if (y >= Y_SIZE)                  return 1;
    140     if (local_id >= NB_TIM_CHANNELS)  return 1;
     143void _timer_reset_irq( unsigned int cluster_xy,
     144                       unsigned int local_id )
     145{
     146#if NB_TIM_CHANNELS
     147
     148    // parameters checking
     149    unsigned int x = cluster_xy >> Y_WIDTH;
     150    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     151    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) )
     152    {
     153        _printf("[GIET ERROR] in _timer_reset_irq()\n");
     154        _exit();
     155    }
    141156
    142157    unsigned int * timer_address = (unsigned int *) ((unsigned int)&seg_tim_base +
     
    144159
    145160    timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0;
    146     return 0;
     161
     162#else
     163    _printf("[GIET ERROR] _timer_reset_irq() should not be called when NB_TIM_CHANNELS is 0\n");
     164    _exit();
     165#endif
    147166}
    148167
    149168/////////////////////////////////////////////////////////////////////////////
    150 //     _timer_reset_cpt()
    151169// This function resets the timer counter. To do so, we re-write the period
    152170// in the proper register, what causes the count to restart.
     
    156174// This function is called during a context switch (user or preemptive)
    157175//////////////////////////////////////////////////////////////////////i//////
    158 unsigned int _timer_reset_cpt( unsigned int cluster_xy,
    159                                unsigned int local_id)
    160 {
    161     // parameters checking
    162     unsigned int x = cluster_xy >> Y_WIDTH;
    163     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    164     if (x >= X_SIZE)                  return 1;
    165     if (y >= Y_SIZE)                  return 1;
    166     if (local_id >= NB_TIM_CHANNELS)  return 1;
     176void _timer_reset_cpt( unsigned int cluster_xy,
     177                       unsigned int local_id)
     178{
     179#if NB_TIM_CHANNELS
     180
     181    // parameters checking
     182    unsigned int x = cluster_xy >> Y_WIDTH;
     183    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     184    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) )
     185    {
     186        _printf("[GIET ERROR in _timer_reset_cpt()\n");
     187        _exit();
     188    }
    167189
    168190    // We suppose that the TIMER_MODE register value is 0x3
     
    172194    unsigned int period = timer_address[local_id * TIMER_SPAN + TIMER_PERIOD];
    173195    timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period;
    174     return 0;
    175 }
     196
     197#else
     198    _printf("[GIET ERROR] _timer_reset_cpt should not be called when NB_TIM_CHANNELS is 0\n");
     199    _exit();
     200#endif
     201}
     202
     203///////////////////////////////////////////////////////////////////////////////////
     204// This ISR handles the IRQs generated by the "user" timers that are
     205// replicated in all clusters.
     206// The IRQs generated by the "system" timers should be handled by _isr_switch().
     207// It can be a HWI or a PTI.
     208// The channel argument is the user timer local index.
     209//     timer_global_id = cluster_id*(NB_TIM_CHANNELS) + channel
     210// The ISR acknowledges the IRQ and registers the event in the proper entry
     211// of the _user_timer_event[] array, and a log message is displayed on TTY0.
     212///////////////////////////////////////////////////////////////////////////////////
     213void _timer_isr( unsigned int irq_type,   // HWI / PTI
     214                 unsigned int irq_id,     // index returned by XCU
     215                 unsigned int channel )   // user timer index
     216{
     217#if NB_TIM_CHANNELS
     218
     219    unsigned int cluster_xy = _get_procid() / NB_PROCS_MAX;
     220
     221    // acknowledge IRQ depending on type
     222    if   ( irq_type == IRQ_TYPE_HWI )  _timer_reset_irq( cluster_xy, channel );
     223    else                               _xcu_timer_reset_irq( cluster_xy, irq_id );
     224
     225    // register the event
     226    _user_timer_event[cluster_xy * NB_TIM_CHANNELS + channel] = 1;
     227
     228    // display a message on TTY 0
     229    _printf("\n[GIET WARNING] User Timer IRQ at cycle %d / cluster = %x / channel = %d\n",
     230            _get_proctime(), cluster_xy, channel );
     231
     232#else
     233    _printf("[GIET ERROR] _timer_isr() should not be called when NB_TIM_CHANNELS == 0\n");
     234    _exit();
     235#endif
     236}
     237
    176238
    177239
  • soft/giet_vm/giet_drivers/tim_driver.h

    r263 r295  
    66///////////////////////////////////////////////////////////////////////////////////
    77
    8 #ifndef _GIET_TIM_DRIVERS_H_
    9 #define _GIET_TIM_DRIVERS_H_
     8#ifndef _GIET_TIM_DRIVER_H_
     9#define _GIET_TIM_DRIVER_H_
    1010
    1111///////////////////////////////////////////////////////////////////////////////////
     
    2727///////////////////////////////////////////////////////////////////////////////////
    2828
    29 extern volatile unsigned char _timer_event[];
     29extern void _timer_start( unsigned int cluster_xy,
     30                          unsigned int local_id,
     31                          unsigned int period );
    3032
    31 extern unsigned int _timer_start( unsigned int cluster_xy,
    32                                   unsigned int local_id,
    33                                   unsigned int period );
     33extern void _timer_stop( unsigned int cluster_xy,
     34                         unsigned int local_id );
    3435
    35 extern unsigned int _timer_stop( unsigned int cluster_xy,
    36                                  unsigned int local_id );
     36extern void _timer_reset_irq( unsigned int cluster_xy,
     37                              unsigned int local_id );
    3738
    38 extern unsigned int _timer_reset_irq( unsigned int cluster_xy,
    39                                       unsigned int local_id );
     39extern void _timer_reset_cpt( unsigned int cluster_xy,
     40                              unsigned int local_id);
    4041
    41 extern unsigned int _timer_reset_cpt( unsigned int cluster_xy,
    42                                       unsigned int local_id);
     42extern void _timer_isr( unsigned int irq_type,
     43                        unsigned int irq_id,
     44                        unsigned int channel );
    4345
    4446///////////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/giet_drivers/tty_driver.c

    r258 r295  
    88// This driver supports the SocLib vci_multi_tty component.
    99//
    10 // It can exist only one multi_tty controler in the architecture.
    11 //
    1210// The total number of TTY terminals must be defined by the configuration
    1311// parameter NB_TTY_CHANNELS in the hard_config.h file.
    14 //
    15 // The register offsets must be defined in the hwr_mapping.h file.
    1612//
    1713// The "system" terminal is TTY[0].
     
    1915// as defined in the mapping_info data structure. The corresponding tty_id must
    2016// be stored in the context of the task by the boot code.
    21 ///////////////////////////////////////////////////////////////////////////////////
    22 // The virtual base address of the segment associated to a channel is:
    2317//
    24 //                  seg_tty_base  + TTY_SPAN * channel_id
    25 //
    26 // The seg_tty_base virtual base addresses must be defined in giet_vsegs.ld file.
     18// The seg_tty_base must be defined in giet_vsegs.ld file.
     19///////////////////////////////////////////////////////////////////////////////////
     20// Implementation note:
     21//
     22// All physical accesses to device registers are done by the two
     23// _tty_get_register(), _tty_set_register() low-level functions,
     24// that are handling virtual / physical addressing.
    2725///////////////////////////////////////////////////////////////////////////////////
    2826
    2927#include <giet_config.h>
    3028#include <tty_driver.h>
     29#include <xcu_driver.h>
    3130#include <ctx_handler.h>
    3231#include <utils.h>
     
    4241#define in_unckdata __attribute__((section (".unckdata")))
    4342
    44 /////////////////   TTY global variables
    45 in_unckdata volatile unsigned char _tty_get_buf[NB_TTY_CHANNELS];
    46 in_unckdata volatile unsigned char _tty_get_full[NB_TTY_CHANNELS]
     43//////////////////////////////////////////////////////////////////////////////
     44//   TTY global variables
     45//////////////////////////////////////////////////////////////////////////////
     46
     47in_unckdata volatile unsigned int _tty_rx_buf[NB_TTY_CHANNELS];
     48in_unckdata volatile unsigned int _tty_rx_full[NB_TTY_CHANNELS]
    4749                                     = { [0 ... NB_TTY_CHANNELS - 1] = 0 };
     50
     51//////////////////////////////////////////////////////////////////////////////
     52// This low level function returns the value of register (channel / index)
     53//////////////////////////////////////////////////////////////////////////////
     54unsigned int _tty_get_register( unsigned int channel,
     55                                unsigned int index )
     56{
     57    unsigned int* vaddr = (unsigned int*)&seg_tty_base + channel*TTY_SPAN + index;
     58    return _io_extended_read( vaddr );
     59}
     60
     61//////////////////////////////////////////////////////////////////////////////
     62// This low level function set a new value in register (channel / index) 
     63//////////////////////////////////////////////////////////////////////////////
     64void _tty_set_register( unsigned int channel,
     65                        unsigned int index,
     66                        unsigned int value )
     67{
     68    unsigned int* vaddr = (unsigned int*)&seg_tty_base + channel*TTY_SPAN + index;
     69    _io_extended_write( vaddr, value );
     70}
    4871
    4972/////////////////////////////////////////////////////////////////////////////////
    5073// This non-blocking function writes a character string from a fixed-length
    51 // buffer to the TTY_WRITE register of a TTY terminal identified by the
    52 // channel argument. If the channel argument is 0xFFFFFFFF, the channel
    53 // index is obtained from the current taxk context.
    54 // It doesn't use any interrupt.
     74// buffer to a TTY terminal identified by the channel argument.
     75// This function is intended to be used to handle a system call, and should
     76// not be used by the kernel for log messages on TTY 0.
     77// protecting exclusive access to the selected terminal.
     78// If channel argument is 0xFFFFFFFF, the TTY index is found in the task context.
    5579// This is a non blocking call: it tests the TTY_STATUS register, and stops
    5680// the transfer as soon as the TTY_STATUS[WRITE] bit is set.
     
    6286                         unsigned int channel)   // channel index
    6387{
    64     unsigned int nwritten;
    65     unsigned int tty_id;
    66     unsigned int* tty_address = (unsigned int *) &seg_tty_base;
    67 
    68     // compute tty channel
    69     if( channel == 0xFFFFFFFF )
    70     {
    71         tty_id = _get_context_slot(CTX_TTY_ID);
    72     }
    73     else
    74     {
    75         tty_id = (unsigned int)channel;
    76     }
     88    unsigned int  nwritten;
     89
     90    // compute and check tty channel
     91    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
     92    if( channel >= NB_TTY_CHANNELS ) return -1;
    7793
    7894    // write string to TTY channel
     
    8096    {
    8197        // check tty's status
    82         if ((tty_address[tty_id * TTY_SPAN + TTY_STATUS] & 0x2) == 0x2) break;
    83         _tty_write_data( tty_id, buffer[nwritten] );
    84     }
     98        if ( _tty_get_register( channel, TTY_STATUS ) & 0x2 )  break;
     99
     100        // write one byte
     101        _tty_set_register( channel, TTY_WRITE, (unsigned int)buffer[nwritten] );
     102    }
     103   
    85104    return nwritten;
    86105}
     
    92111// It uses the TTY_GET_IRQ[tty_id] interrupt and the buffer must have been
    93112// filled by the TTY_ISR.
    94 // It test the _tty_get_full[tty_id] register, read the _tty_get_buf[tty_id]
     113// It test the _tty_rx_full[tty_id] variable, read the _tty_rx_buf[tty_id]
    95114// buffer, writes this character to the target buffer, and resets the
    96 // _tty_get_full[tty_id] register.
     115// _tty_rx_full[tty_id] register.
    97116// The length argument is not used.
    98117//////////////////////////////////////////////////////////////////////////////
     
    103122                        unsigned int channel)   // channel index
    104123{
    105    
    106     unsigned int tty_id;
    107 
    108     // compute tty channel
    109     if( channel == 0xFFFFFFFF )
    110     {
    111         tty_id = _get_context_slot(CTX_TTY_ID);
    112     }
    113     else
    114     {
    115         tty_id = (unsigned int)channel;
    116     }
     124    // compute and check tty channel
     125    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
     126    if( channel >= NB_TTY_CHANNELS ) return -1;
    117127
    118128    // read one character from TTY channel
    119     if (_tty_get_full[tty_id] == 0)
     129    if (_tty_rx_full[channel] == 0)
    120130    {
    121131        return 0;
     
    123133    else
    124134    {
    125         *buffer = _tty_get_buf[tty_id];
    126         _tty_get_full[tty_id] = 0;
     135        *buffer = _tty_rx_buf[channel];
     136        _tty_rx_full[channel] = 0;
    127137        return 1;
    128138    }
    129139}
    130 //////////////////////////////////////////////////////////////////////////////
    131 
    132 //////////////////////////////////////////////////////////////////////////////
    133 // This function try to take the hardwired lock protecting exclusive access
    134 // to TTY terminal identified by the channel argument.
     140
     141//////////////////////////////////////////////////////////////////////////////
     142// This function try to take the hardwired lock protecting
     143// exclusive access to TTY terminal identified by the "channel" argument.
     144// It enters a critical section before taking the lock, and save the SR value
     145// at address defined by the "save_sr_ptr" argument.
    135146// It returns only when the lock has been successfully taken.
    136147//////////////////////////////////////////////////////////////////////////////
    137 void _tty_get_lock( unsigned int channel )
    138 {
    139     unsigned int* tty_address = (unsigned int *) &seg_tty_base;
    140 
    141     if( channel >= NB_TTY_CHANNELS )
    142     {
    143         _puts("[GIET ERROR] in _tty_get_lock() : illegal TTY index\n");
    144         _exit();       
    145     }
    146 
    147     while ( tty_address[channel * TTY_SPAN + TTY_CONFIG] );
    148 }
    149 
    150 //////////////////////////////////////////////////////////////////////////////
    151 // This function releases the hardwired lock protecting exclusive access
    152 // to TTY terminal identified by the channel argument.
    153 //////////////////////////////////////////////////////////////////////////////
    154 void _tty_release_lock( unsigned int channel )
    155 {
    156     unsigned int* tty_address = (unsigned int *) &seg_tty_base;
    157 
    158     if( channel >= NB_TTY_CHANNELS )
    159     {
    160         _puts("[GIET ERROR] in _tty_release_lock() : illegal TTY index\n");
    161         _exit();       
    162     }
    163 
    164     tty_address[channel * TTY_SPAN + TTY_CONFIG] = 0;
    165 }
    166 
    167 //////////////////////////////////////////////////////////////////////////////
    168 // This function returns the content of the TTY_READ register in the
    169 // TTY terminal identified by the channel argument.
    170 //////////////////////////////////////////////////////////////////////////////
    171 unsigned int _tty_read_data( unsigned int channel )
    172 {
    173     unsigned int* tty_address = (unsigned int *) &seg_tty_base;
    174 
    175     if( channel >= NB_TTY_CHANNELS )
    176     {
    177         _puts("[GIET ERROR] in _tty_read_data() : illegal TTY index\n");
    178         _exit();       
    179     }
    180 
    181     return tty_address[channel * TTY_SPAN + TTY_READ];
    182 }
    183 
    184 //////////////////////////////////////////////////////////////////////////////
    185 // This function returns the content of the TTY_STATUS register in the
    186 // TTY terminal identified by the channel argument.
    187 //////////////////////////////////////////////////////////////////////////////
    188 unsigned int _tty_get_status( unsigned int channel )
    189 {
    190     unsigned int* tty_address = (unsigned int *) &seg_tty_base;
    191 
    192     if( channel >= NB_TTY_CHANNELS )
    193     {
    194         _puts("[GIET ERROR] in _tty_get_status() : illegal TTY index\n");
    195         _exit();       
    196     }
    197 
    198     return tty_address[channel * TTY_SPAN + TTY_STATUS];
    199 }
    200 
    201 //////////////////////////////////////////////////////////////////////////////
    202 // This function writes one character in the TTY_WRITE register in the
    203 // TTY terminal identified by the channel argument.
    204 //////////////////////////////////////////////////////////////////////////////
    205 void _tty_write_data( unsigned int channel,
    206                       char         byte )
    207 {
    208     unsigned int* tty_address = (unsigned int *) &seg_tty_base;
    209 
    210     if( channel >= NB_TTY_CHANNELS )
    211     {
    212         _puts("[GIET ERROR] in _tty_write_data() : illegal TTY index\n");
    213         _exit();       
    214     }
    215 
    216     tty_address[channel * TTY_SPAN + TTY_WRITE] = (unsigned int) byte;
    217 }
    218 
     148void _tty_get_lock( unsigned int   channel,
     149                    unsigned int * save_sr_ptr )
     150{
     151    if( channel >= NB_TTY_CHANNELS ) _exit();
     152    _it_disable( save_sr_ptr );
     153    while ( _tty_get_register( channel, TTY_CONFIG ) ); // busy waiting
     154}
     155
     156//////////////////////////////////////////////////////////////////////////////
     157// This function releases the hardwired lock protecting
     158// exclusive access to TTY terminal identified by the channel argument.
     159// It exit the critical section after lock release, and restore SR value
     160// from address defined by the "save_sr_ptr" argument.
     161//////////////////////////////////////////////////////////////////////////////
     162void _tty_release_lock( unsigned int   channel,
     163                        unsigned int * save_sr_ptr )
     164{
     165    if( channel >= NB_TTY_CHANNELS ) _exit();
     166
     167    _tty_set_register( channel, TTY_CONFIG, 0 );
     168    _it_restore( save_sr_ptr );
     169}
     170
     171///////////////////////////////////////////////////////////////////////////////////
     172// This ISR handles the IRQ signaling that the RX buffer is full.
     173// IT can be an HWI or an SWI.
     174// There is one single multi_tty component controling all channels.
     175// There is one communication buffer _tty_rx_buf[i] and one synchronisation
     176// variable _tty_rx_full[i] per channel.
     177// A character is lost if the buffer is full when the ISR is executed.
     178///////////////////////////////////////////////////////////////////////////////////
     179void _tty_rx_isr( unsigned int irq_type,   // HWI / WTI
     180                  unsigned int irq_id,     // index returned by XCU
     181                  unsigned int channel )   // TTY channel
     182{
     183    unsigned int cluster_xy = _get_procid() / NB_PROCS_MAX;
     184
     185    if ( irq_type == IRQ_TYPE_WTI )   // reset SWI in XCU if required
     186    {
     187        unsigned int value;
     188        _xcu_get_wti_value( cluster_xy, irq_id, &value );
     189    }
     190     
     191    // get character and reset TTY IRQ
     192    _tty_rx_buf[channel] = _tty_get_register( channel, TTY_READ );
     193
     194#if GIET_DEBUG_IRQS  // we don't take the TTY lock to avoid deadlock
     195unsigned int x              = cluster_xy >> Y_WIDTH;
     196unsigned int y              = cluster_xy & ((1<<Y_WIDTH)-1);
     197unsigned int lpid           = _get_procid() % NB_PROCS_MAX;
     198_puts("\n[IRQS DEBUG] Processor[");
     199_putd(x );
     200_puts(",");
     201_putd(y );
     202_puts(",");
     203_putd(lpid );
     204_puts("] enters _tty_rx_isr() at cycle ");
     205_putd(_get_proctime() );
     206_puts("\n  read byte = ");
     207_putx(_tty_rx_buf[channel] );
     208_puts("\n");
     209#endif
     210
     211    // signals character available
     212    _tty_rx_full[channel] = 1;
     213}
     214
     215///////////////////////////////////////////////////////////////////////////////////
     216// This ISR handles the IRQ signaling that the TX buffer is empty.
     217// IT can be an HWI or an SWI.
     218// There is one single multi_tty component controling all channels.
     219// There is one communication buffer _tty_rx_buf[i] and one synchronisation
     220// variable _tty_rx_full[i] per channel.
     221// A character is lost if the buffer is full when the ISR is executed.
     222///////////////////////////////////////////////////////////////////////////////////
     223void _tty_tx_isr( unsigned int irq_type,   // HWI / WTI
     224                  unsigned int irq_id,     // index returned by XCU
     225                  unsigned int channel )   // TTY channel
     226{
     227    _puts("\n[GIET ERROR] the _tty_tx_isr() is not implemented\n");
     228    _exit();
     229}
    219230
    220231// Local Variables:
  • soft/giet_vm/giet_drivers/tty_driver.h

    r258 r295  
    2424
    2525///////////////////////////////////////////////////////////////////////////////////
    26 // TTY access functions and variables
     26// TTY variables
    2727///////////////////////////////////////////////////////////////////////////////////
    2828
     
    3131extern volatile unsigned char _tty_get_full[];
    3232
    33 /////// rather high level access functions ///////////////////////////////////////
     33//////////////////////////////////////////////////////////////////////////////////
     34// TTY access functions
     35//////////////////////////////////////////////////////////////////////////////////
    3436
    3537extern unsigned int _tty_write( const char*  buffer,
    36                                 unsigned int length,     // number of characters
    37                                 unsigned int channel );  // channel index
     38                                unsigned int length,     
     39                                unsigned int channel ); 
    3840
    3941extern unsigned int _tty_read(  char*        buffer,
    40                                 unsigned int length,     // unused
    41                                 unsigned int channel );  // channel index
     42                                unsigned int length, 
     43                                unsigned int channel );
    4244
    43 /////// very low level access functions //////////////////////////////////////////
     45extern void _tty_get_lock( unsigned int  channel,
     46                           unsigned int* save_sr_ptr );
    4447
    45 extern void _tty_write_data( unsigned int channel, char byte );
     48extern void _tty_release_lock( unsigned int  channel,
     49                               unsigned int* save_sr_ptr );
    4650
    47 extern unsigned int _tty_read_data( unsigned int channel );
     51extern void _tty_rx_isr( unsigned int irq_type,
     52                         unsigned int irq_id,
     53                         unsigned int channel );
    4854
    49 extern unsigned int _tty_get_status( unsigned int channel );
    50 
    51 extern void _tty_get_lock( unsigned int channel );
    52 
    53 extern void _tty_release_lock( unsigned int channel );
     55extern void _tty_tx_isr( unsigned int irq_type,
     56                         unsigned int irq_id,
     57                         unsigned int channel );
    5458
    5559///////////////////////////////////////////////////////////////////////////////////
     60// low-level access functions
     61///////////////////////////////////////////////////////////////////////////////////
    5662
     63extern unsigned int _tty_get_register( unsigned int channel,
     64                                       unsigned int index );
     65
     66extern void _tty_set_register( unsigned int channel,
     67                               unsigned int index,
     68                               unsigned int value );
    5769
    5870#endif
  • soft/giet_vm/giet_drivers/xcu_driver.c

    r281 r295  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The xcu_driver.c and xcu_driver.h files are part ot the GIET-VM nano-kernel.
    8 // This driver supports the SoCLib vci_xicu, that is a vectorised interrupt
    9 // controler supporting IPI (Inter Processor Interrupts) and integrated timers.
    10 //
    11 // It can exist several interrupt controller unit in the architecture
    12 // (one per cluster), and each one can contain several channels.
    13 // The number of XICU channels is equal to NB_PROCS_MAX, because there is
    14 // one private XICU channel per processor in a cluster.
    15 ////////////////////////////////////////////////////////////////////////////////
    16 // The virtual base address of the segment associated to the component is:
    17 //
    18 //      seg_xcu_base + cluster_xy * vseg_cluster_increment
    19 //
    20 // The seg_xcu_base and vseg_cluster_increment values must be defined
    21 // in giet_vsegs.ld file.
    22 ////////////////////////////////////////////////////////////////////////////////
    237
    248#include <giet_config.h>
     
    5236#endif
    5337
    54 ////////////////////////////////////////////////////////////////////////////////
    55 //     _xcu_set_mask()
    56 // This function set the mask register for the XICU channel identified by the
    57 // cluster index and the processor index multiplied by the number of IRQ per
    58 // processor.
     38
     39////////////////////////////////////////////////////////////////////////////////
     40// This function set the mask register for the IRQ type defined by "irq_type",
     41// and for the channel identified by the "cluster_xy" and "channel" arguments.
    5942// All '1' bits are set / all '0' bits are not modified.
    60 // Returns 0 if success, > 0 if error.
    61 ////////////////////////////////////////////////////////////////////////////////
    62 unsigned int _xcu_set_mask( unsigned int cluster_xy,
    63                             unsigned int irq_index,
    64                             unsigned int value,
    65                             unsigned int irq_type )
    66 {
    67     // parameters checking
    68     unsigned int x = cluster_xy >> Y_WIDTH;
    69     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    70     if (x >= X_SIZE)                                     return 1;
    71     if (y >= Y_SIZE)                                     return 1;
    72     if (irq_index >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) return 1;
    73 
    74 #if USE_XICU
     43////////////////////////////////////////////////////////////////////////////////
     44void _xcu_set_mask( unsigned int cluster_xy,
     45                    unsigned int channel, 
     46                    unsigned int value,
     47                    unsigned int irq_type )
     48{
     49#if USE_XICU
     50    // parameters checking
     51    unsigned int x = cluster_xy >> Y_WIDTH;
     52    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     53    if (x >= X_SIZE)                                   _exit();
     54    if (y >= Y_SIZE)                                   _exit();
     55    if (channel >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) _exit();
     56
    7557    volatile unsigned int* xcu_address =
    7658        (unsigned int *) ((unsigned int)&seg_xcu_base +
     
    7961    unsigned int func;
    8062    if      (irq_type == IRQ_TYPE_PTI) func = XICU_MSK_PTI_ENABLE;
    81     else if (irq_type == IRQ_TYPE_SWI) func = XICU_MSK_WTI_ENABLE;
    82     else                               func = XICU_MSK_HWI_ENABLE;
    83     xcu_address[XICU_REG(func,irq_index)] = value;
    84     return 0;
    85 #else
    86     _tty_get_lock( 0 );
    87     _puts("[GIET ERROR] _xcu_set_mask should not be used if USE_XICU is not set\n");
    88     _tty_release_lock( 0 );
    89     return 1;
    90 #endif
    91 }
    92 
    93 ////////////////////////////////////////////////////////////////////////////////
    94 //     _xcu_get_index()
    95 // This function returns the index of the highest priority (smaller index)
    96 // - active HWI (Hardware Interrupt), or
    97 // - active PTI (Timer Interrupt), or
    98 // - active SWI (Software Interrupt).
    99 // The ICU channel is identified by the cluster index and the processor index
    100 // multiplied by the number of IRQ per processor.
    101 // Returns 0 if success, > 0 if error.
    102 ////////////////////////////////////////////////////////////////////////////////
    103 unsigned int _xcu_get_index( unsigned int cluster_xy,
    104                              unsigned int irq_index,
    105                              unsigned int * buffer)
    106 {
    107     // parameters checking
    108     unsigned int x = cluster_xy >> Y_WIDTH;
    109     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    110     if (x >= X_SIZE)                                     return 1;
    111     if (y >= Y_SIZE)                                     return 1;
    112     if (irq_index >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) return 1;
    113 
    114 #if USE_XICU
    115     volatile unsigned int* xcu_address =
    116         (unsigned int *) ((unsigned int)&seg_xcu_base +
    117         (cluster_xy * (unsigned int)&vseg_cluster_increment));
    118 
    119     unsigned int prio = xcu_address[XICU_REG(XICU_PRIO,irq_index)];
     63    else if (irq_type == IRQ_TYPE_WTI) func = XICU_MSK_WTI_ENABLE;
     64    else if (irq_type == IRQ_TYPE_HWI) func = XICU_MSK_HWI_ENABLE;
     65    else
     66    {
     67        _printf("[GIET ERROR] _xcu_set_mask() receives illegal IRQ type\n");
     68        _exit();
     69    }
     70
     71    xcu_address[XICU_REG(func,channel)] = value;
     72
     73#else
     74    _printf("[GIET ERROR] _xcu_set_mask() should not be used if USE_XICU not set\n");
     75    _exit();
     76#endif
     77}
     78
     79////////////////////////////////////////////////////////////////////////////////
     80// This function returns the index and the type of the highest priority
     81// - active PTI (Timer Interrupt), then
     82// - active HWI (Hardware Interrupt), then
     83// - active WTI (Software Interrupt)
     84// As the hardware can define more than one IRQ per processor, but the GIET
     85// use only one, channel = lpid * IRQ_PER_PROCESSOR.
     86////////////////////////////////////////////////////////////////////////////////
     87void _xcu_get_index( unsigned int cluster_xy,
     88                     unsigned int channel,   
     89                     unsigned int * index,
     90                     unsigned int * irq_type )
     91{
     92#if USE_XICU
     93    // parameters checking
     94    unsigned int x = cluster_xy >> Y_WIDTH;
     95    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     96    if (x >= X_SIZE)                                   _exit();
     97    if (y >= Y_SIZE)                                   _exit();
     98    if (channel >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) _exit();
     99
     100    volatile unsigned int* xcu_address =
     101        (unsigned int *) ((unsigned int)&seg_xcu_base +
     102        (cluster_xy * (unsigned int)&vseg_cluster_increment));
     103
     104    unsigned int prio = xcu_address[XICU_REG(XICU_PRIO,channel)];
    120105    unsigned int pti_ok = (prio & 0x00000001);
    121106    unsigned int hwi_ok = (prio & 0x00000002);
    122     unsigned int swi_ok = (prio & 0x00000004);
     107    unsigned int wti_ok = (prio & 0x00000004);
    123108    unsigned int pti_id = (prio & 0x00001F00) >> 8;
    124109    unsigned int hwi_id = (prio & 0x001F0000) >> 16;
    125     unsigned int swi_id = (prio & 0x1F000000) >> 24;
    126     if      (pti_ok)  *buffer = pti_id;
    127     else if (hwi_ok)  *buffer = hwi_id;
    128     else if (swi_ok)  *buffer = swi_id;
    129     else              *buffer = 32;
    130     return 0;
    131 #else
    132     _tty_get_lock( 0 );
    133     _puts("[GIET ERROR] _xcu_get_index should not be used if USE_XICU is not set\n");
    134     _tty_release_lock( 0 );
    135     return 1;
    136 #endif
    137 }
    138 
    139 ////////////////////////////////////////////////////////////////////////////////
    140 //     _xcu_send_ipi()
    141 // This function can be used only in an architecture using  XICU components.
    142 // It writes the "wdata" value in the mailbox defined by the cluster index
    143 // and the processor index.
    144 // Giet-VM supports at most NB_PROCS_MAX mailboxes:
    145 // (0 <= wti_index <= NB_PROCS_MAX-1)
    146 // Returns 0 if success, > 0 if error.
    147 ////////////////////////////////////////////////////////////////////////////////
    148 unsigned int _xcu_send_ipi( unsigned int cluster_xy,
    149                             unsigned int wti_index,
    150                             unsigned int wdata )
     110    unsigned int wti_id = (prio & 0x1F000000) >> 24;
     111    if      (pti_ok)
     112    {
     113        *index    = pti_id;
     114        *irq_type = IRQ_TYPE_PTI;
     115    }
     116    else if (hwi_ok)
     117    {
     118        *index    = hwi_id;
     119        *irq_type = IRQ_TYPE_HWI;
     120    }
     121    else if (wti_ok)
     122    {
     123        *index    = wti_id;
     124        *irq_type = IRQ_TYPE_WTI;
     125    }
     126    else
     127    {
     128        *index = 32;
     129    }
     130 
     131#else
     132    _printf("[GIET ERROR] _xcu_get_index should not be used if USE_XICU is not set\n");
     133    _exit();
     134#endif
     135}
     136
     137////////////////////////////////////////////////////////////////////////////////
     138// This function writes the "wdata" value in the mailbox defined
     139// by the "cluster_xy" and "wti_index" arguments.
     140////////////////////////////////////////////////////////////////////////////////
     141void _xcu_send_wti( unsigned int cluster_xy,
     142                    unsigned int wti_index,
     143                    unsigned int wdata )
    151144{
    152     // parameters checking
    153     unsigned int x = cluster_xy >> Y_WIDTH;
    154     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    155     if (x >= X_SIZE)               return 1;
    156     if (y >= Y_SIZE)               return 1;
    157     if (wti_index >= NB_PROCS_MAX) return 1;
    158 
    159 #if USE_XICU
     145#if USE_XICU
     146    // parameters checking
     147    unsigned int x = cluster_xy >> Y_WIDTH;
     148    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     149    if (x >= X_SIZE)               _exit();
     150    if (y >= Y_SIZE)               _exit();
     151    if (wti_index >= 32)           _exit();
     152
    160153    volatile unsigned int* xcu_address =
    161154        (unsigned int *) ((unsigned int)&seg_xcu_base +
     
    163156
    164157    xcu_address[XICU_REG(XICU_WTI_REG,wti_index)] = wdata;
    165     return 0;
    166 #else
    167     _tty_get_lock( 0 );
    168     _puts("[GIET ERROR] _xcu_send_ipi should not be used if USE_XICU is not set\n");
    169     _tty_release_lock( 0 );
    170     return 1;
     158
     159#else
     160    _printf("[GIET ERROR] _xcu_send_ipi should not be used if USE_XICU is not set\n");
     161    _exit();
    171162#endif
    172163}
    173164
    174165////////////////////////////////////////////////////////////////////////////////
    175 //    _xcu_timer_start()
     166// This function returns the value contained in a WTI mailbox defined by
     167// the cluster_xy and "wti_index" arguments. This value is written in
     168// the "value" argument, and the corresponding WTI is acknowledged.
     169// returns 0 if success, > 0 if error.
     170////////////////////////////////////////////////////////////////////////////////
     171void _xcu_get_wti_value( unsigned int   cluster_xy,
     172                         unsigned int   wti_index,
     173                         unsigned int * value )
     174{
     175#if USE_XICU
     176    // parameters checking
     177    unsigned int x = cluster_xy >> Y_WIDTH;
     178    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     179    if (x >= X_SIZE)               _exit();
     180    if (y >= Y_SIZE)               _exit();
     181    if (wti_index >= 32)           _exit();
     182 
     183    volatile unsigned int* xcu_address =
     184        (unsigned int *) ((unsigned int)&seg_xcu_base +
     185        (cluster_xy * (unsigned int)&vseg_cluster_increment));
     186
     187    *value = xcu_address[XICU_REG(XICU_WTI_REG, wti_index)];
     188
     189#else
     190    _printf("[GIET ERROR] in _xcu_get_wti_value() USE_XICU is not set\n");
     191    _exit();
     192#endif
     193}
     194
     195////////////////////////////////////////////////////////////////////////////////
     196// This function returns the address of a WTI mailbox defined by
     197// the "wti_index" argument, in the unsigned int "address" argument.
     198// It is used by the GIET to configurate the IOPIC component.
     199// There is no access to a specific XCU component in a specific cluster.
     200// returns 0 if success, > 0 if error.
     201////////////////////////////////////////////////////////////////////////////////
     202void _xcu_get_wti_address( unsigned int   wti_index,
     203                           unsigned int * address )
     204{
     205#if USE_XICU
     206    if (wti_index >= 32)           _exit();
     207 
     208    unsigned int xcu_address = (unsigned int)&seg_xcu_base;
     209    *address = xcu_address + (XICU_REG(XICU_WTI_REG, wti_index)<<2);
     210
     211#else
     212    _printf("[GIET ERROR] in _xcu_get_wti_address() USE_XICU is not set\n");
     213    _exit();
     214#endif
     215}
     216
     217////////////////////////////////////////////////////////////////////////////////
    176218// This function activates a timer contained in XICU by writing in the
    177219// proper register the period value.
    178 // Returns 0 if success, > 0 if error.
    179 ////////////////////////////////////////////////////////////////////////////////
    180 unsigned int _xcu_timer_start( unsigned int cluster_xy,
    181                                unsigned int pti_index,
    182                                unsigned int period )
    183 {
    184     // parameters checking
    185     unsigned int x = cluster_xy >> Y_WIDTH;
    186     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    187     if (x >= X_SIZE)             return 1;
    188     if (y >= Y_SIZE)             return 1;
    189 
    190 #if USE_XICU
     220////////////////////////////////////////////////////////////////////////////////
     221void _xcu_timer_start( unsigned int cluster_xy,
     222                       unsigned int pti_index,
     223                       unsigned int period )
     224{
     225#if USE_XICU
     226    // parameters checking
     227    unsigned int x = cluster_xy >> Y_WIDTH;
     228    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     229    if (x >= X_SIZE)             _exit();
     230    if (y >= Y_SIZE)             _exit();
     231
    191232    volatile unsigned int* xcu_address =
    192233        (unsigned int *) ((unsigned int)&seg_xcu_base +
     
    194235
    195236    xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = period;
    196     return 0;
    197 #else
    198     _tty_get_lock( 0 );
    199     _puts("[GIET ERROR] _xcu_timer_start should not be used if USE_XICU is not set\n");
    200     _tty_release_lock( 0 );
    201     return 1;
    202 #endif
    203 }
    204 
    205 //////////////////////////////////////////////////////////////////////////////
    206 //     _xcu_timer_stop()
     237
     238#else
     239    _printf("[GIET ERROR] in _xcu_timer_start() USE_XICU is not set\n");
     240    _exit();
     241#endif
     242}
     243
     244//////////////////////////////////////////////////////////////////////////////
    207245// This function desactivates a timer in XICU component
    208246// by writing in the proper register.
    209 // Returns 0 if success, > 0 if error.
    210 //////////////////////////////////////////////////////////////////////////////
    211 unsigned int _xcu_timer_stop( unsigned int cluster_xy,
    212                               unsigned int pti_index)
    213 {
    214     // parameters checking
    215     unsigned int x = cluster_xy >> Y_WIDTH;
    216     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    217     if (x >= X_SIZE)             return 1;
    218     if (y >= Y_SIZE)             return 1;
    219 
    220 #if USE_XICU
     247//////////////////////////////////////////////////////////////////////////////
     248void _xcu_timer_stop( unsigned int cluster_xy,
     249                      unsigned int pti_index)
     250{
     251#if USE_XICU
     252    // parameters checking
     253    unsigned int x = cluster_xy >> Y_WIDTH;
     254    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     255    if (x >= X_SIZE)             _exit();
     256    if (y >= Y_SIZE)             _exit();
     257
    221258    volatile unsigned int * xcu_address =
    222259        (unsigned int *) ((unsigned int)&seg_xcu_base +
     
    224261
    225262    xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = 0;
    226     return 0;
    227 #else
    228     _tty_get_lock( 0 );
    229     _puts("[GIET ERROR] _xcu_timer_stop should not be used if USE_XICU is not set\n");
    230     _tty_release_lock( 0 );
    231     return 1;
    232 #endif
    233 }
    234 
    235 //////////////////////////////////////////////////////////////////////////////
    236 //     _xcu_timer_reset_irq()
     263
     264#else
     265    _printf("[GIET ERROR] in _xcu_timer_stop() USE_XICU is not set\n");
     266    _exit();
     267#endif
     268}
     269
     270//////////////////////////////////////////////////////////////////////////////
    237271// This function acknowlegge a timer interrupt in XICU
    238272// component by reading in the proper register.
    239273// It can be used by both the isr_switch() for a "system" timer,
    240274// or by the _isr_timer() for an "user" timer.
    241 // Returns 0 if success, > 0 if error.
    242 //////////////////////////////////////////////////////////////////////////////
    243 unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy,
    244                                    unsigned int pti_index )
    245 {
    246     // parameters checking
    247     unsigned int x = cluster_xy >> Y_WIDTH;
    248     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    249     if (x >= X_SIZE)             return 1;
    250     if (y >= Y_SIZE)             return 1;
    251 
    252 #if USE_XICU
     275//////////////////////////////////////////////////////////////////////////////
     276void _xcu_timer_reset_irq( unsigned int cluster_xy,
     277                           unsigned int pti_index )
     278{
     279#if USE_XICU
     280    // parameters checking
     281    unsigned int x = cluster_xy >> Y_WIDTH;
     282    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     283    if (x >= X_SIZE)             _exit();
     284    if (y >= Y_SIZE)             _exit();
     285
    253286    volatile unsigned int * xcu_address =
    254287        (unsigned int *) ((unsigned int)&seg_xcu_base +
     
    256289
    257290    xcu_address[XICU_REG(XICU_PTI_ACK, pti_index)];
    258     return 0;
    259 #else
    260     _tty_get_lock( 0 );
    261     _puts("[GIET ERROR] _xcu_timer_reset_irq should not be used if USE_XICU is not set\n");
    262     _tty_release_lock( 0 );
    263     return 1;
    264 #endif
    265 }
    266 
    267 //////////////////////////////////////////////////////////////////////////////
    268 //     _xcu_timer_reset_cpt()
     291
     292#else
     293    _printf("[GIET ERROR] in _xcu_timer_reset_irq() USE_XICU is not set\n");
     294    _exit();
     295#endif
     296}
     297
     298//////////////////////////////////////////////////////////////////////////////
    269299// This function resets a timer counter. To do so, we re-write the period
    270300// in the proper register, what causes the count to restart.
    271301// The period value is read from the same (TIMER_PERIOD) register,
    272302// this is why in appearance we do nothing useful (read a value
    273 // from a register and write this value in the same register)
     303// from a register and write this value in the same register).
    274304// This function is called during a context switch (user or preemptive)
    275305/////////////////////////////////////////////////////////////////////////////
    276 unsigned int _xcu_timer_reset_cpt( unsigned int cluster_xy,
    277                                    unsigned int pti_index )
    278 {
    279     // parameters checking
    280     unsigned int x = cluster_xy >> Y_WIDTH;
    281     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    282     if (x >= X_SIZE)             return 1;
    283     if (y >= Y_SIZE)             return 1;
    284 
    285 #if USE_XICU
     306void _xcu_timer_reset_cpt( unsigned int cluster_xy,
     307                           unsigned int pti_index )
     308{
     309#if USE_XICU
     310    // parameters checking
     311    unsigned int x = cluster_xy >> Y_WIDTH;
     312    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     313    if (x >= X_SIZE)             _exit();
     314    if (y >= Y_SIZE)             _exit();
     315
    286316    volatile unsigned int * xcu_address =
    287317        (unsigned int *) ((unsigned int) &seg_xcu_base +
     
    294324    xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = 0;
    295325    xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = period;
    296     return 0;
    297 #else
    298     _tty_get_lock( 0 );
    299     _puts("[GIET ERROR] _xcu_timer_reset_irq should not be used if USE_XICU is not set\n");
    300     _tty_release_lock( 0 );
    301     return 1;
     326
     327#else
     328    _printf("[GIET ERROR] in _xcu_timer_reset_cpt() USE_XICU is not set\n");
     329    _exit();
    302330#endif
    303331}
  • soft/giet_vm/giet_drivers/xcu_driver.h

    r281 r295  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
     7// The xcu_driver.c and xcu_driver.h files are part ot the GIET-VM nano-kernel.
     8// This driver supports the SoCLib vci_xicu, that is a vectorised interrupt
     9// controler supporting IPI (Inter Processor Interrupts) and integrated timers.
     10//
     11// It can exist several interrupt controller unit in the architecture
     12// (one per cluster), and each one can contain several channels.
     13// The number of XICU channels is equal to NB_PROCS_MAX, because there is
     14// one private XICU channel per processor in a cluster.
     15////////////////////////////////////////////////////////////////////////////////
     16// The virtual base address of the segment associated to the component is:
     17//
     18//      seg_xcu_base + cluster_xy * vseg_cluster_increment
     19//
     20// The seg_xcu_base and vseg_cluster_increment values must be defined
     21// in giet_vsegs.ld file.
     22////////////////////////////////////////////////////////////////////////////////
    723
    824#ifndef _GIET_XCU_DRIVER_H_
     
    4460///////////////////////////////////////////////////////////////////////////////////
    4561
    46 extern unsigned int _xcu_get_index( unsigned int cluster_xy,
    47                                     unsigned int irq_index,
    48                                     unsigned int * buffer );
     62extern void _xcu_set_mask( unsigned int cluster_xy,
     63                           unsigned int channel, 
     64                           unsigned int mask,
     65                           unsigned int irq_type );
    4966
    50 extern unsigned int _xcu_set_mask( unsigned int cluster_xy,
    51                                    unsigned int irq_index,
    52                                    unsigned int mask,
    53                                    unsigned int is_timer );
     67extern void _xcu_get_index( unsigned int   cluster_xy,
     68                            unsigned int   channel,   
     69                            unsigned int * index,
     70                            unsigned int * irq_type );
    5471
    55 extern unsigned int _xcu_send_ipi( unsigned int cluster_xy,
    56                                    unsigned int wti_index,
    57                                    unsigned int wdata );
     72extern void _xcu_send_wti( unsigned int cluster_xy,
     73                           unsigned int wti_index,
     74                           unsigned int wdata );
    5875
    59 extern unsigned int _xcu_timer_start( unsigned int cluster_xy,
    60                                       unsigned int pti_index,
    61                                       unsigned int period );
     76extern void _xcu_get_wti_value( unsigned int   cluster_xy,
     77                                unsigned int   wti_index,
     78                                unsigned int * value );
    6279
    63 extern unsigned int _xcu_timer_stop( unsigned int cluster_xy,
    64                                      unsigned int pti_index );
     80extern void _xcu_get_wti_address( unsigned int   wti_index,
     81                                  unsigned int * address );
    6582
    66 extern unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy,
    67                                           unsigned int pti_index );
     83extern void _xcu_timer_start( unsigned int cluster_xy,
     84                              unsigned int pti_index,
     85                              unsigned int period );
    6886
    69 extern unsigned int _xcu_timer_reset_cpt( unsigned int cluster_xy,
    70                                           unsigned int pti_index );
     87extern void _xcu_timer_stop( unsigned int cluster_xy,
     88                             unsigned int pti_index );
     89
     90extern void _xcu_timer_reset_irq( unsigned int cluster_xy,
     91                                  unsigned int pti_index );
     92
     93extern void _xcu_timer_reset_cpt( unsigned int cluster_xy,
     94                                  unsigned int pti_index );
    7195
    7296///////////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/giet_fat32/fat32.c

    r291 r295  
    1717// 2. This FAT32 library uses a FAT cache whose storage capacity is one
    1818//    sector (512 bytes, or 128 cluster indexes in FAT)
    19 // 3. This FAT32 library can be used in three modes: BOOT/KERNEL/USER
    20 //    defining three different behaviours for the IOC driver.
     19// 3. This FAT32 library can be used in four modes: BOOT_PA/BOOT_VA/KERNEL/USER
     20//    defining different behaviours for the IOC driver.
    2121//////////////////////////////////////////////////////////////////////////////////
    2222
     
    4646    temp[8] = 0;
    4747
    48     _tty_get_lock( 0 );
    49     _puts("\n*********************** fat_cache_lba = ");
    50     _putx( fat.cache_lba );
    51     _puts(" **************************\n");
     48    _printf("\n*********************** fat_cache_lba = %x *****************************\n",
     49            fat.cache_lba );
    5250
    5351    for ( line=0 ; line<16 ; line++ )
    5452    {
    5553        // display address
    56         _putx( (fat.cache_lba<<9) + (line<<5) );
    57         _puts(" : ");
     54        _printf( "%x : ", (fat.cache_lba<<9) + (line<<5) );
    5855
    5956        // display data hexa
     
    6562                                 (fat.fat_cache[byte+2]<< 8) |
    6663                                 (fat.fat_cache[byte+3]);
    67             _putx( hexa );
    68             _puts(" | ");
     64            _printf("%x | ", hexa );
    6965
    7066            // prepare display ascii
     
    7672       
    7773        // display data ascii
    78         _puts( (char*)temp );
    79         _puts("\n");
    80     }
    81     _puts("***************************************************************************\n");
    82     _tty_release_lock( 0 );
     74        _printf( (char*)temp );
     75        _printf("\n");
     76    }
     77    _printf("**************************************************************************\n");
    8378} // end display_fat_cache() 
    8479#endif
     
    202197       
    203198        // access fat
    204         if( _ioc_read( mode,              // mode for IOC driver
     199        if( _ioc_read( 0,                 // channel
     200                       mode,              // mode for IOC driver
    205201                       lba,               // sector index
    206202                       fat.fat_cache,     // fat cache
    207203                       1 ) )              // one sector
    208204        {
    209             _tty_get_lock( 0 );
    210             _puts("[FAT_ERROR] in get_next cluster_id() cannot read block ");
    211             _putd( lba );
    212             _puts("\n");
    213             _tty_release_lock( 0 );
     205            _printf("[FAT_ERROR] in get_next cluster_id() "
     206                    "cannot read block %x\n", lba );
    214207            return 1;
    215208        }
     
    271264
    272265#if GIET_DEBUG_FAT
    273 _tty_get_lock( 0 );
    274 _puts("\n[FAT DEBUG] filename ");
    275 _puts( string );
    276 _tty_release_lock( 0 );
     266_printf("\n[FAT DEBUG] filename %s", string );
    277267#endif
    278268
     
    282272
    283273#if GIET_DEBUG_FAT
    284 _tty_get_lock( 0 );
    285 _puts(" converted to 8.3 SFN format : ");
    286 _puts( sfn_string );
    287 _puts("\n");
    288 _tty_release_lock( 0 );
     274_printf(" converted to 8.3 SFN format : %s\n", sfn_string );
    289275#endif
    290276
     
    298284
    299285#if GIET_DEBUG_FAT
    300 _tty_get_lock( 0 );
    301 _puts(" converted to 8.3 SFN format : ");
    302 _puts( string );
    303 _puts("\n");
    304 _tty_release_lock( 0 );
     286_printf(" converted to 8.3 SFN format : %s\n", sfn_string );
    305287#endif
    306288
     
    358340
    359341#if GIET_DEBUG_FAT
    360 _tty_get_lock( 0 );
    361 _puts(" converted to 8.3 SFN format : ");
    362 _puts( sfn_string );
    363 _puts("\n");
    364 _tty_release_lock( 0 );
     342_printf(" converted to 8.3 SFN format : %s\n", sfn_string );
    365343#endif
    366344
     
    524502    is_sfn = is_short( file_name, sfn );
    525503
    526     if ( _ioc_read( IOC_KERNEL_MODE, // mode for IOC driver
     504    if ( _ioc_read( 0,               // channel
     505                    IOC_KERNEL_MODE, // mode for IOC driver
    527506                    lba,             // sector index
    528507                    fat.fat_cache,   // buffer address
    529508                    1 ) )            // one sector
    530509    {
    531         _tty_get_lock( 0 );
    532         _puts("[FAT ERROR] in update_entry() cannot read sector ");
    533         _putd( lba );
    534         _puts("\n");
    535         _tty_release_lock( 0 );
     510        _printf("[FAT ERROR] in update_entry() cannot read sector %x\n", lba );
    536511        return 1;
    537512    }
     
    562537            else if (ord == NO_MORE_ENTRY )            // end of directory : return
    563538            {
    564                 _tty_get_lock( 0 );
    565                 _puts("[FAT ERROR] in update_entry() end of directory reaches ");
    566                 _puts("\n");
    567                 _tty_release_lock( 0 );
     539                _printf("[FAT ERROR] in update_entry() : reaches end of directory\n");
    568540                return 1;
    569541            }
     
    591563            else if (ord == NO_MORE_ENTRY )                        // end of directory : return
    592564            {
    593                 _tty_get_lock( 0 );
    594                 _puts("[FAT ERROR] in update_entry() end of directory reaches ");
    595                 _puts("\n");
    596                 _tty_release_lock( 0 );
     565                _printf("[FAT ERROR] in update_entry() reaches end of directory\n");
    597566                return 1;
    598567            }
     
    643612    }
    644613
    645     return _ioc_write( IOC_KERNEL_MODE,
    646                        lba, 
    647                        fat.fat_cache,
    648                        1     );
    649 }
    650 //////////////////////////////////////////////////////////////////////////////////
    651 // This function update FS_INFO, for new last cluster allocated and number of free
    652 // cluster.
     614    return _ioc_write( 0,                // channel
     615                       IOC_KERNEL_MODE,  // mode
     616                       lba,              // sector index
     617                       fat.fat_cache,    // source buffer
     618                       1 );              // one sector
     619}
     620//////////////////////////////////////////////////////////////////////////////////
     621// This function update FS_INFO:
     622// last cluster allocated and number of free cluster.
    653623// Return 0 in case of success, > 0 if failure.
    654624//////////////////////////////////////////////////////////////////////////////////
     
    658628
    659629#if GIET_DEBUG_FAT
    660 _tty_get_lock( 0 );
    661 _puts("\n[FAT DEBUG] Enter in update_fs_info()\n");
    662 _tty_release_lock( 0 );
     630_printf("\n[FAT DEBUG] Enter update_fs_info()\n");
    663631#endif
    664632
     
    670638    else                                   // miss cache
    671639    {
    672         if ( _ioc_read( IOC_KERNEL_MODE,   // mode for IOC driver
     640        if ( _ioc_read( 0,                 // channel
     641                        IOC_KERNEL_MODE,   // mode for IOC driver
    673642                        lba,               // sector index
    674                         fat.fat_cache,     // fat cache
     643                        fat.fat_cache,     // source buffer
    675644                        1 ) )              // one sector
    676645        {
    677             _tty_get_lock( 0 );
    678             _puts("[FAT_ERROR] in update_fat() cannot read block ");
    679             _putd( lba );
    680             _puts("\n");
    681             _tty_release_lock( 0 );
     646            _printf("[FAT_ERROR] in update_fat() cannot read block %x\n", lba );
    682647            return 1;
    683648        }
     
    686651        write_entry( FS_FREE_CLUSTER_HINT, fat.fat_cache, fat.last_cluster_allocated );
    687652    }
    688     return _ioc_write( IOC_KERNEL_MODE,       
    689                        lba,           
    690                        fat.fat_cache,           
    691                        1 );
     653    return _ioc_write( 0,                // channel
     654                       IOC_KERNEL_MODE,  // mode   
     655                       lba,              // sector index
     656                       fat.fat_cache,    // source buffer
     657                       1 );              // one sector
    692658}
    693659
     
    703669
    704670#if GIET_DEBUG_FAT
    705 _tty_get_lock( 0 );
    706 _puts("\n[FAT DEBUG] Enter in update_fat() :\n");
    707 _puts("    - Cluster to update = ");
    708 _putd( cluster );
    709 _puts("\n");
    710 _puts("    - Value to write = ");
    711 _putd( value );
    712 _puts("\n");
    713 _tty_release_lock( 0 );
     671_printf("\n[FAT DEBUG] Enter update_fat() : cluster = %x / value = %x\n",
     672        cluster, value );
    714673#endif
    715674
     
    720679    else                                   // miss cache
    721680    {
    722         if ( _ioc_read( IOC_KERNEL_MODE,   // mode for IOC driver
     681        if ( _ioc_read( 0,                 // channel
     682                        IOC_KERNEL_MODE,   // mode for IOC driver
    723683                        lba,               // sector index
    724                         fat.fat_cache,     // fat cache
     684                        fat.fat_cache,     // source buffer
    725685                        1 ) )              // one sector
    726686        {
    727             _tty_get_lock( 0 );
    728             _puts("[FAT_ERROR] in update_fat() cannot read block ");
    729             _putd( lba );
    730             _puts("\n");
    731             _tty_release_lock( 0 );
     687            _printf("[FAT_ERROR] in update_fat() cannot read block %x\n");
    732688            return 1;
    733689        }
     
    735691        write_entry( ((cluster % 128) << 2), 4, fat.fat_cache, value );
    736692    }
    737     return _ioc_write( IOC_KERNEL_MODE,       
    738                        lba,           
    739                        fat.fat_cache,           
    740                        1 );
     693    return _ioc_write( 0,                // channel
     694                       IOC_KERNEL_MODE,  // mode     
     695                       lba,              // sector indexs
     696                       fat.fat_cache,    // source buffer
     697                       1 );              // one sector
    741698}
    742699
     
    759716    if ( get_next_cluster_id( IOC_KERNEL_MODE, free_cluster ) != FREE_CLUSTER)
    760717    {
    761         _tty_get_lock( 0 );
    762         _puts("\n[FAT ERROR] in _fat_allocate() : first free_cluster isnt free\n");
    763         _tty_release_lock( 0 );
     718        _printf("\n[FAT ERROR] in _fat_allocate() : first free_cluster not free\n");
    764719        return -1;
    765720    }
     
    767722    if ( count > fat.number_free_cluster )
    768723    {
    769         _tty_get_lock( 0 );
    770         _puts("\n[FAT ERROR] in _fat_allocate() : Not enough free cluster(s) for this allocation\n");
    771         _tty_release_lock( 0 );
     724        _printf("\n[FAT ERROR] in _fat_allocate() : Not enough free cluster(s)\n");
    772725        return -1;
    773726    }
    774727
    775728#if GIET_DEBUG_FAT
    776 _tty_get_lock( 0 );
    777 _puts("\n[FAT DEBUG] Enter in _fat_allocate() :\n");
    778 _puts("    - Need to allocate ");
    779 _putd( count );
    780 _puts(" cluster(s) for file ");
    781 _putd( fd_id );
    782 _puts("\n");
    783 _tty_release_lock( 0 );
     729_printf("\n[FAT DEBUG] Enter in _fat_allocate() for file %d\n", fd_id );
    784730#endif
    785731
     
    795741
    796742#if GIET_DEBUG_FAT
    797 _tty_get_lock( 0 );
    798 _puts("\n[FAT DEBUG] Cluster to update is : ");
    799 _putd( last_cluster_file );
    800 _puts("\n");
    801 _puts("[FAT DEBUG] Free cluster is : ");
    802 _putd( free_cluster );
    803 _puts("\n");
    804 _puts("[FAT DEBUG] Number of cluster need to be allocated : ");
    805 _putd( cluster_to_allocate );
    806 _puts("\n");
    807 _tty_release_lock( 0 );
     743_printf("\n[FAT DEBUG] cluster to update = %x / free cluster = %x / clusters required = %d\n",
     744        last_cluster_file, free_cluster, cluster_to_allocate );
    808745#endif
    809746
     
    812749        if ( update_fat( last_cluster_file, free_cluster ) )
    813750        {
    814             _tty_get_lock( 0 );
    815             _puts("\n[FAT ERROR] in _fat_allocate() : update fat for file ");
    816             _putd( fd_id );
    817             _puts(" failed\n");
    818             _tty_release_lock( 0 );
     751            _printf("\n[FAT ERROR] in _fat_allocate() : update fat failed\n");
    819752            return -1;
    820753        }
     
    831764            if ( update_fat( last_cluster_file, END_OF_CHAIN_CLUSTER ) )
    832765            {
    833                 _tty_get_lock( 0 );
    834                 _puts("\n[FAT ERROR] in _fat_allocate() : update fat for file ");
    835                 _putd( fd_id );
    836                 _puts(" failed\n");
    837                 _tty_release_lock( 0 );
     766                _printf("\n[FAT ERROR] in _fat_allocate() : update fat failed\n");
    838767                return -1;
    839768            }
     
    845774        if ( get_next_cluster_id( IOC_KERNEL_MODE, free_cluster ) != FREE_CLUSTER)
    846775        {
    847             _tty_get_lock( 0 );
    848             _puts("\n[FAT ERROR] in _fat_allocate() : free_cluster isnt free\n");
    849             _tty_release_lock( 0 );
     776            _printf("\n[FAT ERROR] in _fat_allocate() : free_cluster not free\n");
    850777            return -1;
    851778        }
     
    859786    if ( update_fs_info() )
    860787    {
    861         _tty_get_lock( 0 );
    862         _puts("\n[FAT ERROR] in _fat_allocate() : update fs_info for file ");
    863         _putd( fd_id );
    864         _puts(" failed\n");
    865         _tty_release_lock( 0 );
     788        _printf("\n[FAT ERROR] in _fat_allocate() : update fs_info failed\n");
    866789        return -1;
    867790    }
     
    895818
    896819#if GIET_DEBUG_FAT
    897 _tty_get_lock( 0 );
    898 _puts("\n[FAT DEBUG] enter _scan_directory() searching dir/file : ");
    899 _puts( file_name );
    900 _puts("\n");
    901 _tty_release_lock( 0 );
     820_printf("\n[FAT DEBUG] enter _scan_directory() searching dir/file %s", filename );
    902821#endif
    903822
     
    920839    // load first cluster sector from DATA region into FAT cache
    921840    // other sectors will be loaded inside loop as required
    922     if( _ioc_read( mode,            // mode for IOC driver
     841    if( _ioc_read( 0,               // channel
     842                   mode,            // mode for IOC driver
    923843                   lba,             // sector index
    924844                   fat.fat_cache,   // buffer address
    925845                   1 ) )            // one sector
    926846    {
    927         _tty_get_lock( 0 );
    928         _puts("[FAT ERROR] in scan directory() cannot read sector ");
    929         _putd( lba );
    930         _puts("\n");
    931         _tty_release_lock( 0 );
     847        _printf("[FAT ERROR] in scan directory() cannot read sector %x\n", lba );
    932848        return -1;
    933849    }
     
    935851    fat.cache_lba = lba;
    936852
    937     #if GIET_DEBUG_FAT
    938     display_fat_cache();
    939     #endif
     853#if GIET_DEBUG_FAT
     854display_fat_cache();
     855#endif
    940856
    941857    // in this loop we scan all names in directory identified by cluster:
     
    961877                block_id = fat.sectors_per_cluster;
    962878            }
    963             if( _ioc_read( mode,            // mode for IOC driver
     879            if( _ioc_read( 0,               // channel
     880                           mode,            // mode for IOC driver
    964881                           lba,             // sector index
    965882                           fat.fat_cache,   // buffer address
    966883                           1 ) )            // one sector
    967884            {
    968                 _tty_get_lock( 0 );
    969                 _puts("[FAT ERROR] in scan directory() cannot read sector ");
    970                 _putd( lba );
    971                 _puts("\n");
    972                 _tty_release_lock( 0 );
     885                _printf("[FAT ERROR] in scan directory() cannot read sector %x\n", lba );
    973886                return -1;
    974887            }
     
    1072985            *lba_dir_entry = lba;
    1073986
    1074 #if GIET_DEBUG_FAT
    1075 _tty_get_lock( 0 );
    1076 _puts("\n[FAT DEBUG] FILE FOUND\n");
    1077 _tty_release_lock( 0 );
    1078 #endif
    1079987            return read_cluster( dir_entry );
    1080988        }
     
    10941002                       unsigned int    dir_cluster )
    10951003{
    1096     _tty_get_lock( 0 );
    1097     _puts("\n[FAT ERROR] _fat_create() not implemented\n");
    1098     _tty_release_lock( 0 );
     1004    _printf("\n[FAT ERROR] _fat_create() not implemented\n");
    10991005    return 0;
    11001006}  //end _fat_create()
     
    11151021
    11161022#if GIET_DEBUG_FAT
    1117 _tty_get_lock( 0 );
    1118 _puts("\n[FAT DEBUG] Enter _fat_init() / fat_cache_base = ");
    1119 _putx( (unsigned int)fat.fat_cache );
    1120 _puts("\n");
    1121 _tty_release_lock( 0 );
     1023unsigned int procid  = _get_procid();
     1024unsigned int cid     = procid / NB_PROCS_MAX;
     1025unsigned int lpid    = procid % NB_PROCS_MAX;
     1026unsigned int x       = cid >> Y_WIDTH;
     1027unsigned int y       = cid & ((1<<Y_WIDTH) - 1);
     1028
     1029_printf("\n[FAT DEBUG] Processor[%d,%d,%d] enters _fat_init()\n",
     1030        x, y, lpid );
    11221031#endif
    11231032
    11241033    // load Master Boot Record (sector 0) into fat cache
    1125     if ( _ioc_read( mode,             // mode for IOC driver
     1034    if ( _ioc_read( 0,                // channel
     1035                    mode,             // mode for IOC driver
    11261036                    0,                // sector index
    11271037                    fat.fat_cache,    // buffer address
    11281038                    1 ) )             // one sector
    11291039    {
    1130         _tty_get_lock( 0 );
    1131         _puts("\n[FAT ERROR] in _fat_init() cannot load Boot Sector\n");
    1132         _tty_release_lock( 0 );
     1040        _printf("\n[FAT ERROR] in _fat_init() cannot load Boot Sector\n");
    11331041        return -1;
    11341042    }
    11351043    fat.cache_lba = 0;
    11361044   
     1045#if GIET_DEBUG_FAT
     1046display_fat_cache();
     1047#endif
     1048
    11371049    // checking Boot sector integrity
    11381050    if( MBR_SIGNATURE_VALUE != read_entry( MBR_SIGNATURE_POSITION, fat.fat_cache, 1))
    11391051    {
    1140         _tty_get_lock( 0 );
    1141         _puts("\n[FAT ERROR] Boot sector not recognized or corrupt \n");
    1142         _tty_release_lock( 0 );
     1052        _printf("\n[FAT ERROR] Boot sector not recognized or corrupt \n");
    11431053        return -1; 
    11441054    }
    11451055
    11461056#if GIET_DEBUG_FAT
    1147 _tty_get_lock( 0 );
    1148 _puts("\n[FAT DEBUG] Boot Sector Loaded\n");
    1149 _tty_release_lock( 0 );
     1057_printf("\n[FAT DEBUG] Boot Sector Loaded\n");
    11501058#endif
    11511059
     
    11551063
    11561064    // load Partition Boot Record (first partition sector) into fat cache
    1157     if ( _ioc_read( mode,                // mode for IOC driver
     1065    if ( _ioc_read( 0,                   // channel
     1066                    mode,                // mode for IOC driver
    11581067                    fat.partition_lba,   // sector index
    11591068                    fat.fat_cache,       // buffer address
    11601069                    1 ) )                // one sector
    11611070    {
    1162         _tty_get_lock( 0 );
    1163         _puts("\n[FAT ERROR] in _fat_init() cannot load block ");
    1164         _putd( fat.partition_lba );
    1165         _puts("\n");
    1166         _tty_release_lock( 0 );
     1071        _printf("\n[FAT ERROR] in _fat_init() cannot load block %x\n", fat.partition_lba );
    11671072        return -1;
    11681073    }
     
    11701075
    11711076#if GIET_DEBUG_FAT
    1172 _tty_get_lock( 0 );
    1173 _puts("\n[FAT DEBUG] Partition First Sector Loaded\n");
    1174 _tty_release_lock( 0 );
     1077_printf("\n[FAT DEBUG] Partition First Sector Loaded\n");
    11751078#endif
    11761079
     
    11791082    if( read_entry( BPB_BYTSPERSEC, fat.fat_cache, 1 ) != 512 )
    11801083    {
    1181         _tty_get_lock( 0 );
    1182         _puts("\n[FAT ERROR] The sector size must be 512 bytes\n");
    1183         _tty_release_lock( 0 );
     1084        _printf("\n[FAT ERROR] The sector size must be 512 bytes\n");
    11841085        return -1; 
    11851086    }
    11861087    if( read_entry( BPB_RSVDSECCNT, fat.fat_cache, 1 ) != 32 )
    11871088    {
    1188         _tty_get_lock( 0 );
    1189         _puts("\n[FAT ERROR] The RSVD region in FAT32 must be 32 sectors\n");
    1190         _tty_release_lock( 0 );
     1089        _printf("\n[FAT ERROR] The RSVD region in FAT32 must be 32 sectors\n");
    11911090        return -1; 
    11921091    }
    11931092    if( read_entry( BPB_NUMFATS, fat.fat_cache, 1 ) != 1 )
    11941093    {
    1195         _tty_get_lock( 0 );
    1196         _puts("\n[FAT ERROR] The number of FAT copies in FAT region must be 1\n");
    1197         _tty_release_lock( 0 );
     1094        _printf("\n[FAT ERROR] The number of FAT copies in FAT region must be 1\n");
    11981095        return -1; 
    11991096    }
    12001097    if( (read_entry( BPB_FAT32_FATSZ32, fat.fat_cache, 1 ) & 0xF) != 0 )
    12011098    {
    1202         _tty_get_lock( 0 );
    1203         _puts("\n[FAT ERROR] The FAT region in FAT32 must be multiple of 32 sectors\n");
    1204         _tty_release_lock( 0 );
     1099        _printf("\n[FAT ERROR] The FAT region in FAT32 must be multiple of 32 sectors\n");
    12051100        return -1; 
    12061101    }
    1207 
    12081102    if( read_entry( BPB_FAT32_ROOTCLUS, fat.fat_cache, 1 ) != 2 )
    12091103    {
    1210         _tty_get_lock( 0 );
    1211         _puts("\n[FAT ERROR] The first cluster index must be 2\n");
    1212         _tty_release_lock( 0 );
     1104        _printf("\n[FAT ERROR] The first cluster index must be 2\n");
    12131105        return -1; 
    12141106    }
     
    12271119
    12281120#if GIET_DEBUG_FAT
    1229 _tty_get_lock( 0 );
    1230 _puts("\n[FAT DEBUG] FS_INFO Sector = ");
    1231 _putd(fat.fs_info_lba);
    1232 _puts("\n");
    1233 _tty_release_lock( 0 );
     1121_printf("\n[FAT DEBUG] FS_INFO Sector = %x\n", fat.fs_info_lba );
    12341122#endif
    12351123
    12361124    // load FS_INFO into fat cache
    1237     if ( _ioc_read( mode,               // mode for IOC driver
     1125    if ( _ioc_read( 0,                  // channel
     1126                    mode,               // mode for IOC driver
    12381127                    fat.fs_info_lba,    // sector index
    12391128                    fat.fat_cache,      // buffer address
    12401129                    1 ) )               // one sector
    12411130    {
    1242         _tty_get_lock( 0 );
    1243         _puts("\n[FAT ERROR] in _fat_init() cannot load FS_INFO Sector\n");
    1244         _tty_release_lock( 0 );
     1131        _printf("\n[FAT ERROR] in _fat_init() cannot load FS_INFO Sector\n");
    12451132        return -1;
    12461133    }
     
    12511138
    12521139#if GIET_DEBUG_FAT
    1253 _tty_get_lock( 0 );
    1254 _puts("\n[FAT DEBUG] Number of Free Clusters = ");
    1255 _putd(fat.number_free_cluster);
    1256 _puts("\n");
    1257 _puts("\n[FAT DEBUG] Last known cluster allocated = ");
    1258 _putd(fat.last_cluster_allocated);
    1259 _puts("\n");
    1260 _puts("\n[FAT DEBUG] FS_INFO Sector Loaded\n");
    1261 _tty_release_lock( 0 );
    1262 #endif
    1263 
    1264 
    1265 #if GIET_DEBUG_FAT
    1266 _tty_get_lock( 0 );
    1267 _puts("\n[FAT DEBUG] Exit _fat_init()\n");
    1268 _tty_release_lock( 0 );
     1140_printf("\n[FAT DEBUG] Processor[%d,%d,%d] exit _fat_init() / "
     1141        "free clusters = %x / last allocated cluster = %x\n",
     1142        fat.number_free_cluster, fat.last_cluster_allocated );
    12691143#endif
    12701144
     
    12751149void _fat_print()
    12761150{
    1277     _puts("\n################################ FAT32 ###############################"); 
    1278     _puts("\nFAT initialised                "); _putx( fat.initialised );
    1279     _puts("\nSector Size  (bytes)           "); _putx( fat.sector_size );
    1280     _puts("\nSectors per cluster            "); _putx( fat.sectors_per_cluster );
    1281     _puts("\nPartition size (sectors)       "); _putx( fat.partition_sectors );
    1282     _puts("\nPartition first lba            "); _putx( fat.partition_lba );
    1283     _puts("\nData region first lba          "); _putx( fat.data_lba );
    1284     _puts("\nNumber of sectors for one FAT  "); _putx( fat.fat_sectors );
    1285     _puts("\n######################################################################\n");
     1151    _printf("\n########################## FAT32 ###########################"); 
     1152    _printf("\nFAT initialised                %d", fat.initialised );
     1153    _printf("\nSector Size  (bytes)           %x", fat.sector_size );
     1154    _printf("\nSectors per cluster            %x", fat.sectors_per_cluster );
     1155    _printf("\nPartition size (sectors)       %x", fat.partition_sectors );
     1156    _printf("\nPartition first lba            %x", fat.partition_lba );
     1157    _printf("\nData region first lba          %x", fat.data_lba );
     1158    _printf("\nNumber of sectors for one FAT  %x", fat.fat_sectors );
     1159    _printf("\n############################################################\n");
    12861160}
    12871161
     
    12941168// a new file is created and introduced in the directory.
    12951169// Finally, it sets a new open file in the file descriptors array.
     1170// The same file can be open several times by differents taks.
    12961171///////////////////////////////////////////////////////////////////////////////
    12971172// Returns file descriptor index if success, returns -1 if error.
     
    13111186   
    13121187#if GIET_DEBUG_FAT
    1313 _tty_get_lock( 0 );
    1314 _puts("\n[FAT DEBUG] enter _fat_open() for file ");
    1315 _puts( pathname );
    1316 _puts("\n");
    1317 _tty_release_lock( 0 );
    1318 #endif
    1319 
    1320     // check FAT initialised
     1188unsigned int procid  = _get_procid();
     1189unsigned int cid     = procid / NB_PROCS_MAX;
     1190unsigned int lpid    = procid % NB_PROCS_MAX;
     1191unsigned int x       = cid >> Y_WIDTH;
     1192unsigned int y       = cid & ((1<<Y_WIDTH) - 1);
     1193
     1194_printf("\n[FAT DEBUG] Processor[%d,%d,%d] enters _fat_open() for file %s\n",
     1195        x, y, lpid, pathname );
     1196#endif
     1197
     1198    // checking arguments
     1199    if ( creat )
     1200    {
     1201        _printf("[FAT ERROR] in _fat_open() : create not supported yet\n");
     1202        return -1;
     1203    }
     1204
     1205    // takes the FAT lock for exclusive access
     1206    _get_lock( &fat.lock );
     1207
     1208#if GIET_DEBUG_FAT
     1209_printf("\n[FAT DEBUG] Processor[%d,%d,%d] takes the FAT lock\n",
     1210        x, y, lpid );
     1211#endif
     1212
     1213    // FAT initialisation if required
    13211214    if( fat.initialised != FAT_INITIALISED )
    13221215    {
    13231216        if ( _fat_init( mode ) )
    13241217        {
    1325             _puts("[FAT ERROR] Cannot initialize FAT descriptor from Boot Sector\n");
    1326             _exit();
    1327         }
    1328 
    1329 #if GIET_DEBUG_FAT
    1330 _tty_get_lock( 0 );
    1331 _puts("\n[FAT DEBUG] FAT initialisation completed at cycle ");
    1332 _putd(_get_proctime());
    1333 _puts("\n");
     1218            _printf("[FAT ERROR] in _fat_open() : Cannot initialize FAT descriptor\n");
     1219
     1220            // release FAT lock
     1221            _release_lock( &fat.lock );
     1222
     1223            return -1;
     1224        }
     1225
     1226#if GIET_DEBUG_FAT
     1227_printf("\n[FAT DEBUG] Processor[%d,%d,%d] initialises FAT descriptor\n",
     1228        x, y, lpid );
    13341229_fat_print();
    1335 _tty_release_lock( 0 );
    1336 #endif
     1230#endif
     1231
    13371232    }
    13381233 
     
    13501245
    13511246#if GIET_DEBUG_FAT
    1352 _tty_get_lock( 0 );
    1353 _puts("\n[FAT DEBUG] _fat_open : search dir/file : ");
    1354 _puts( name );
    1355 _puts("\n");
    1356 _tty_release_lock( 0 );
     1247_printf("\n[FAT DEBUG] Processor[%d,%d,%d] search dir/file : %s\n",
     1248        x, y, lpid, name );
    13571249#endif
    13581250
     
    13731265        else if ( cluster == END_OF_CHAIN_CLUSTER )
    13741266        {
    1375             _tty_get_lock( 0 );
    1376             _puts("\n[FAT ERROR] in _fat_open() for file ");
    1377             _puts( pathname );
    1378             _puts(" : cannot found name ");
    1379             _puts( name );
    1380             _puts("\n");
    1381             _tty_release_lock( 0 );
     1267            _printf("\n[FAT ERROR] in _fat_open() cannot found %s\n", name );
     1268
     1269            // release FAT lock
     1270            _release_lock( &fat.lock );
     1271
    13821272            return -1;
    13831273        }
    13841274    }
    1385 
    1386 #if GIET_DEBUG_FAT
    1387 _tty_get_lock( 0 );
    1388 _puts("\n[FAT DEBUG] File ");
    1389 _puts( pathname );
    1390 _puts(" found\n");
    1391 _tty_release_lock( 0 );
    1392 #endif
    13931275
    13941276    // check the next value for cluster index found
     
    14141296
    14151297#if GIET_DEBUG_FAT
    1416 _tty_get_lock( 0 );
    1417 _puts("\n[FAT DEBUG] file  ");
    1418 _puts( pathname );
    1419 _puts(" open with fd_id = ");
    1420 _putd( fd_id );
    1421 _puts("\n");
    1422 _tty_release_lock( 0 );
    1423 #endif
     1298_printf("\n[FAT DEBUG] Processor[%d,%d,%d] open file %s with fd = %d\n",
     1299        x, y, lpid, pathname, fd_id );
     1300#endif
     1301
     1302            // release FAT lock
     1303            _release_lock( &fat.lock );
    14241304
    14251305            return fd_id;
     
    14271307        else
    14281308        {
    1429             _tty_get_lock( 0 );
    1430             _puts("\n[FAT ERROR] in _fat_open() for file ");
    1431             _puts( pathname );
    1432             _puts(" : file descriptor array full\n ");
    1433             _tty_release_lock( 0 );
     1309            _printf("\n[FAT ERROR] in _fat_open() for file %s : fd array full\n",
     1310                    pathname );
     1311
     1312            // release FAT lock
     1313            _release_lock( &fat.lock );
     1314
    14341315            return -1;
    14351316        }
     
    14371318    else
    14381319    {
    1439         _tty_get_lock( 0 );
    1440         _puts("\n[FAT ERROR] in _fat_open() for file ");
    1441         _puts( pathname );
    1442         _puts(" : file found, but bad cluster\n");
    1443         _tty_release_lock( 0 );
     1320        _printf("\n[FAT ERROR] in _fat_open() for file %s : bad cluster\n",
     1321                pathname );
     1322
     1323        // release FAT lock
     1324        _release_lock( &fat.lock );
     1325
    14441326        return -1;
    14451327    }
     
    14611343
    14621344#if GIET_DEBUG_FAT
    1463 _tty_get_lock( 0 );
    1464 _puts("\n[FAT DEBUG] Enter _fat_read() for file ");
    1465 _puts( fat.fd[fd_id].name );
    1466 _puts("\n - buffer base     = ");
    1467 _putx( (unsigned int)buffer );
    1468 _puts("\n - skipped sectors = ");
    1469 _putd( offset );
    1470 _puts("\n - read sectors    = ");
    1471 _putd( count );
    1472 _tty_release_lock( 0 );
     1345unsigned int procid  = _get_procid();
     1346unsigned int cid     = procid / NB_PROCS_MAX;
     1347unsigned int lpid    = procid % NB_PROCS_MAX;
     1348unsigned int x       = cid >> Y_WIDTH;
     1349unsigned int y       = cid & ((1<<Y_WIDTH) - 1);
     1350
     1351_printf("\n[FAT DEBUG] Processor[%d,%d,%d] enters _fat_read() for file %s\n",
     1352        " - buffer vbase    = %x\n"
     1353        " - skipped sectors = %x\n"
     1354        " - read sectors    = %x\n",
     1355        x, y, lpid, fat.fd[fd_id].name, (unsigned int)buffer, offset, count );
    14731356#endif
    14741357
     
    14901373    if ( fd_id >= GIET_OPEN_FILES_MAX )
    14911374    {
    1492         _tty_get_lock( 0 );
    1493         _puts("\n[FAT ERROR] in _fat_read() : illegal file descriptor index\n");
    1494         _tty_release_lock( 0 );
     1375        _printf("\n[FAT ERROR] in _fat_read() : illegal file descriptor index\n");
    14951376        return -1;
    14961377    }
    14971378    if ( fat.fd[fd_id].used != 1 )
    14981379    {
    1499         _tty_get_lock( 0 );
    1500         _puts("\n[FAT ERROR] in _fat_read() : file not open\n");
    1501         _tty_release_lock( 0 );
     1380        _printf("\n[FAT ERROR] in _fat_read() : file not open\n");
    15021381        return -1;
    15031382    }
    15041383    if ( ((unsigned int)buffer & 0x1FF) != 0 )
    15051384    {
    1506         _tty_get_lock( 0 );
    1507         _puts("\n[FAT ERROR] in _fat_read() : memory buffer not sector aligned\n");
    1508         _tty_release_lock( 0 );
     1385        _printf("\n[FAT ERROR] in _fat_read() : memory buffer not sector aligned\n");
    15091386        return -1;
    15101387    }
    15111388    if ( offset >= file_sectors )
    15121389    {
    1513         _tty_get_lock( 0 );
    1514         _puts("\n[FAT ERROR] offset larger than number of sectors in file\n");
    1515         _puts(" - offset       = ");
    1516         _putd( offset );
    1517         _puts(" - file_sectors = ");
    1518         _putd( file_sectors );
    1519         _tty_release_lock( 0 );
     1390        _printf("\n[FAT ERROR] offset larger than number of sectors\n");
    15201391        return -1;
    15211392    }
     
    15331404
    15341405#if GIET_DEBUG_FAT
    1535 _tty_get_lock( 0 );
    1536 _puts("\n - first cluster   = ");
    1537 _putd( cluster );   
    1538 _puts("\n - skiped clusters = ");
    1539 _putd( clusters_to_skip );   
    1540 _puts("\n");
    1541 _tty_release_lock( 0 );
     1406_printf(" - first cluster   = %x\n"
     1407        " - skiped clusters = %x\n",
     1408        cluster, clusters_to_skip );   
    15421409#endif
    15431410
     
    15681435
    15691436#if GIET_DEBUG_FAT
    1570 _tty_get_lock( 0 );
    1571 _puts("\n[FAT DEBUG] _fat_read() IOC request : buf = ");
    1572 _putx( (unsigned int)dst );
    1573 _puts(" / lba = ");
    1574 _putd( lba );
    1575 _puts(" / sectors = ");
    1576 _putd( iter_sectors );
    1577 _puts("\n"); 
    1578 _tty_release_lock( 0 );
    1579 #endif
    1580 
    1581         if( _ioc_read( mode,              // mode for IOC driver
     1437_printf("\n[FAT DEBUG] Processor[%d,%d,%d] makes an IOC read :"
     1438        " buf = %x / lba = %x / sectors = %d\n",
     1439        x, y, lpid, (unsigned int)dst, lba, iter_sectors );
     1440#endif
     1441
     1442        if( _ioc_read( 0,                 // channel
     1443                       mode,              // mode for IOC driver
    15821444                       lba,               // first sector index
    15831445                       dst,               // buffer address
    15841446                       iter_sectors ) )   // number of sectors
    15851447        {
    1586             _tty_get_lock( 0 );
    1587             _puts("\n[FAT ERROR] in _fat_read() cannot load block ");
    1588             _putd( lba );
    1589             _puts("\n");
    1590             _tty_release_lock( 0 );
     1448            _printf("\n[FAT ERROR] in _fat_read() cannot load block %x\n", lba );
    15911449            return -1;
    15921450        }
     
    16531511
    16541512#if GIET_DEBUG_FAT
    1655 _tty_get_lock( 0 );
    1656 _puts("\n[FAT DEBUG] Enter _fat_write() for file ");
    1657 _puts( fat.fd[fd_id].name );
    1658 _puts("\n - buffer base     = ");
    1659 _putx( (unsigned int)buffer );
    1660 _puts("\n - skipped sectors = ");
    1661 _putd( offset );
    1662 _puts("\n - write sectors    = ");
    1663 _putd( count );
    1664 _puts("\n - file size (sectors)  = ");
    1665 _putd( file_sectors );
    1666 _puts("\n - need allocate = ");
    1667  allocate ? _puts( "True" ) : _puts( "False");
    1668 _tty_release_lock( 0 );
     1513unsigned int procid  = _get_procid();
     1514unsigned int cid     = procid / NB_PROCS_MAX;
     1515unsigned int lpid    = procid % NB_PROCS_MAX;
     1516unsigned int x       = cid >> Y_WIDTH;
     1517unsigned int y       = cid & ((1<<Y_WIDTH) - 1);
     1518
     1519_printf("\n[FAT DEBUG] Processor[%d,%d,%d] enters _fat_write() for file %s\n",
     1520        " - buffer vbase    = %x\n"
     1521        " - skipped sectors = %x\n"
     1522        " - write sectors   = %x\n"
     1523        " - file sectors    = %x\n"
     1524        " - need allocate   = %d\n",
     1525        x, y, lpid, fat.fd[fd_id].name, (unsigned int)buffer,
     1526        offset, count, file_sectors, allocate );
    16691527#endif
    16701528
     
    16721530    if ( fd_id >= GIET_OPEN_FILES_MAX )
    16731531    {
    1674         _tty_get_lock( 0 );
    1675         _puts("\n[FAT ERROR] in _fat_write() : illegal file descriptor index\n");
    1676         _tty_release_lock( 0 );
     1532        _printf("\n[FAT ERROR] in _fat_write() : illegal file descriptor index\n");
    16771533        return -1;
    16781534    }
    16791535    if ( fat.fd[fd_id].used != 1 )
    16801536    {
    1681         _tty_get_lock( 0 );
    1682         _puts("\n[FAT ERROR] in _fat_write() : file not open\n");
    1683         _tty_release_lock( 0 );
     1537        _printf("\n[FAT ERROR] in _fat_write() : file not open\n");
    16841538        return -1;
    16851539    }
    16861540    if ( ((unsigned int)buffer & 0x1FF) != 0 )
    16871541    {
    1688         _tty_get_lock( 0 );
    1689         _puts("\n[FAT ERROR] in _fat_write() : memory buffer not sector aligned\n");
    1690         _tty_release_lock( 0 );
     1542        _printf("\n[FAT ERROR] in _fat_write() : memory buffer not sector aligned\n");
    16911543        return -1;
    16921544    }
     
    16961548        if ( _fat_allocate( fd_id, (required_cluster - current_cluster) ) < 0 )
    16971549        {
    1698             _tty_get_lock( 0 );
    1699             _puts("\n[FAT ERROR] in _fat_write() : fat_allocate for file ");
    1700             _putd( fd_id );
    1701             _puts(" failed\n");
    1702             _tty_release_lock( 0 );
     1550            _printf("\n[FAT ERROR] in _fat_write() : fat_allocate failed\n");
    17031551            return -1;
    17041552        }
     
    17131561
    17141562#if GIET_DEBUG_FAT
    1715 _tty_get_lock( 0 );
    1716 _puts("\n - first cluster   = ");
    1717 _putd( cluster );   
    1718 _puts("\n - skiped clusters = ");
    1719 _putd( clusters_to_skip );   
    1720 _puts("\n");
    1721 _tty_release_lock( 0 );
     1563_printf(" - first cluster   = %x\n"
     1564        " - skiped clusters = %x\n",
     1565        cluster, clusters_to_skip );   
    17221566#endif
    17231567
     
    17481592
    17491593#if GIET_DEBUG_FAT
    1750 _tty_get_lock( 0 );
    1751 _puts("\n[FAT DEBUG] _fat_write() IOC request : buf = ");
    1752 _putx( (unsigned int)src );
    1753 _puts(" / lba = ");
    1754 _putd( lba );
    1755 _puts(" / sectors = ");
    1756 _putd( iter_sectors );
    1757 _puts("\n"); 
    1758 _tty_release_lock( 0 );
    1759 #endif
    1760 
    1761         if( _ioc_write( mode,              // mode for IOC driver
     1594_printf("\n[FAT DEBUG] Processor[%d,%d,%d] makes an IOC write : "
     1595        "buf = %x / lba = %x / sectors = %x\n",
     1596        x, y, lpid, (unsigned int)src, lba, iter_sectors );
     1597#endif
     1598
     1599        if( _ioc_write( 0,                 // channel
     1600                        mode,              // mode for IOC driver
    17621601                        lba,               // first sector index
    1763                         src,               // buffer address
     1602                        src,               // source buffer address
    17641603                        iter_sectors ) )   // number of sectors
    17651604        {
    1766             _tty_get_lock( 0 );
    1767             _puts("\n[FAT ERROR] in _fat_write() cannot write block ");
    1768             _putd( lba );
    1769             _puts("\n");
    1770             _tty_release_lock( 0 );
     1605            _printf("\n[FAT ERROR] in _fat_write() cannot write block %x\n", lba );
    17711606            return -1;
    17721607        }
     
    17921627    if ( update_entry(fd_id, DIR_FILE_SIZE, fat.fd[fd_id].file_size) )
    17931628    {
    1794             _tty_get_lock( 0 );
    1795             _puts("\n[FAT ERROR] in _fat_write() update entry for file ");
    1796             _putd( fd_id );
    1797             _puts(" failed\n");
    1798             _tty_release_lock( 0 );
     1629            _printf("\n[FAT ERROR] in _fat_write() update entry failed\n");
    17991630            return -1;
    18001631    }
     
    18261657    else
    18271658    {
    1828         _tty_get_lock( 0 );
    1829         _puts("\n[FAT ERROR] in _fat_fstat() : illegal file descriptor index\n");
    1830         _tty_release_lock( 0 );
     1659        _printf("\n[FAT ERROR] in _fat_fstat() : illegal file descriptor index\n");
    18311660        return -1;
    18321661    }
     
    18471676    else
    18481677    {
    1849         _tty_get_lock( 0 );
    1850         _puts("\n[FAT ERROR] in _fat_close() : illegal file descriptor index\n");
    1851         _tty_release_lock( 0 );
     1678        _printf("\n[FAT ERROR] in _fat_close() : illegal file descriptor index\n");
    18521679        return -1;
    18531680    }
     
    18631690                    unsigned int flags )     // unused: TODO
    18641691{
    1865     return _fat_open( IOC_KERNEL_MODE,       // we KERNEL_MODE, because
     1692    return _fat_open( IOC_KERNEL_MODE,       // we use KERNEL_MODE, because
    18661693                      pathname,              // we need to write into FAT cache
    1867                       0 );       
     1694                      0 );                   // no creation if not found
    18681695}
    18691696
     
    19091736                     unsigned int whence )
    19101737{
    1911     _tty_get_lock( 0 );
    1912     _puts("[GIET ERROR] _fat_user_lseek function not implemented\n");
    1913     _tty_release_lock( 0 );
     1738    _printf("[GIET ERROR] _fat_user_lseek() not implemented\n");
    19141739    _exit();
    19151740    return 0;
  • soft/giet_vm/giet_fat32/fat32.h

    r291 r295  
    143143    unsigned int    cluster_size;            // sector_size * sector_per_cluster (bytes)
    144144    unsigned int    fat_sectors;             // number of sectors occupied by one FAT copy
    145     unsigned int    partition_sectors;       // total number of sectors (RESVD + FAT + DATA)
     145    unsigned int    partition_sectors;       // total number of sectors (RESVD+FAT+DATA)
    146146    unsigned int    partition_lba;           // lba of first partiton sector
    147147    unsigned int    data_lba;                // lba of first data sector 
     
    150150    unsigned int    number_free_cluster;     // number of free clusters
    151151    unsigned int    fs_info_lba;             // lba of fs_info
     152    unsigned int    lock;                    // lock protecting exclusive access
    152153} fat32_fs_t;
    153154/***************************************************************************************/
  • soft/giet_vm/giet_libs/barrier.c

    r258 r295  
    1515
    1616///////////////////////////////////////////////////////////////////////////////////
    17 //     barrier_init()
    18 // This function makes a cooperative initialisation of the barrier:
    19 // several tasks try to initialize the barrier, but the initialisation
    20 // is done by only one task, using LL/SC instructions.
     17// This function initializes the barrier: this should be done by a single task.
    2118///////////////////////////////////////////////////////////////////////////////////
    22 void barrier_init( giet_barrier_t * barrier, unsigned int value) {
    23     unsigned int * pinit  = (unsigned int *) &barrier->init;
    24     unsigned int * pcount = (unsigned int *) &barrier->count;
    25 
    26     // parallel initialisation using atomic instructions LL/SC
    27     // inputs : pinit, pcount, value
    28     // no output
    29     asm volatile ("_barrier_init_test:                  \n"
    30             "ll   $2,     0(%0)                   \n" /* read initial value */
    31             "bnez $2,     _barrier_init_done      \n"
    32             "move $3,     %2                      \n"
    33             "sc   $3,     0(%0)                   \n" /* write initial value */
    34             "beqz $3,     _barrier_init_test      \n"
    35             "move $3,     %2                      \n"
    36             "sw   $3,     0(%1)                   \n" /* write count */
    37             "_barrier_init_done:                  \n"
    38             :
    39             : "r"(pinit), "r"(pcount), "r"(value)
    40             : "$2", "$3");
     19void barrier_init( giet_barrier_t* barrier,
     20                   unsigned int    value )
     21{
     22    barrier->init  = value;
     23    barrier->count = value;
    4124}
    4225
    4326
    4427///////////////////////////////////////////////////////////////////////////////////
    45 //    barrier_wait()
    4628// This blocking function uses LL/SC to decrement the barrier's counter.
    4729// Then, it uses a busy_waiting mechanism if it is not the last.
    48 // (because the GIET does not support dynamic task scheduling/descheduling)
    4930///////////////////////////////////////////////////////////////////////////////////
    50 void barrier_wait(giet_barrier_t * barrier) {
     31void barrier_wait( giet_barrier_t* barrier )
     32{
    5133    unsigned int * pcount  = (unsigned int *) &barrier->count;
    5234    unsigned int maxcount = barrier->init;
     
    5638    // - input : pointer on the barrier counter
    5739    // - output : counter value
    58     asm volatile ("_barrier_decrement:          \n"
     40    asm volatile ("_barrier_decrement:    \n"
    5941            "ll   %0, 0(%1)               \n"
    6042            "addi $3, %0,     -1          \n"
     
    6850    // waking up all other waiting tasks
    6951
    70     if (count == 1) {
     52    if (count == 1)
     53    {
    7154        // last task
    7255        *pcount = maxcount;
  • soft/giet_vm/giet_libs/barrier.h

    r258 r295  
    1313///////////////////////////////////////////////////////////////////////////////////
    1414
    15 typedef struct giet_barrier_s {
     15typedef struct giet_barrier_s
     16{
    1617    char name[32];      // barrier name
    1718    unsigned int init;  // total number of participants
     
    2324//////////////////////////////////////////////////////////////////////////////
    2425
    25 void barrier_init(giet_barrier_t * barrier, unsigned int value);
    26 void barrier_wait(giet_barrier_t * barrier);
     26void barrier_init( giet_barrier_t* barrier,
     27                   unsigned int    value );  // number of tasks 
     28
     29void barrier_wait( giet_barrier_t* barrier );
    2730
    2831#endif
  • soft/giet_vm/giet_libs/malloc.h

    r258 r295  
    88#ifndef _MALLOC_H_
    99#define _MALLOC_H_
     10
    1011//#define DEBUG_MALLOC 1
    1112
  • soft/giet_vm/giet_libs/stdio.c

    r289 r295  
    1919
    2020////////////////////////////////////////////////////////////////////////////////////
    21 // giet_procid()
    22 ////////////////////////////////////////////////////////////////////////////////////
    23 // This function returns the processor identifier.
    24 ////////////////////////////////////////////////////////////////////////////////////
    25 int giet_procid()
    26 {
    27     return sys_call( SYSCALL_PROCID,
    28                      0, 0, 0, 0 );
    29 }
    30 ////////////////////////////////////////////////////////////////////////////////////
    31 // giet_proctime()
    32 ////////////////////////////////////////////////////////////////////////////////////
    33 // This function returns the local processor time (clock cycles since boot)
    34 ////////////////////////////////////////////////////////////////////////////////////
    35 int giet_proctime()
    36 {
    37     return sys_call( SYSCALL_PROCTIME,
    38                      0, 0, 0, 0 );
    39 }
    40 
    41 
    42 ////////////////////////////////////////////////////////////////////////////////////
    4321/////////////////////  TTY device related system calls /////////////////////////////
    4422////////////////////////////////////////////////////////////////////////////////////
    4523
    46 ////////////////////////////////////////////////////////////////////////////////////
    47 // giet_tty_putc()
    48 ////////////////////////////////////////////////////////////////////////////////////
    49 // This function displays a single ascii character on a terminal.
    50 // The terminal index must be defined in the task context in the boot phase.
    51 // It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer.
    52 // - Returns 1 if the character has been written, 0 otherwise.
    53 ////////////////////////////////////////////////////////////////////////////////////
    54 int giet_tty_putc(char byte)
    55 {
    56     return sys_call(SYSCALL_TTY_WRITE,
    57                     (unsigned int)(&byte),
    58                     1,
    59                     0xFFFFFFFF, 
    60                     0);
    61 }
    62 ////////////////////////////////////////////////////////////////////////////////////
    63 // giet_tty_puts()
    64 ////////////////////////////////////////////////////////////////////////////////////
    65 // This function displays a string on a terminal.
    66 // The terminal index must be defined in the task context in the boot phase.
    67 // The string must be terminated by a NUL character.
    68 // It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer.
    69 // - Returns the number of written characters.
    70 ////////////////////////////////////////////////////////////////////////////////////
    71 int giet_tty_puts(char * buf)
    72 {
    73     unsigned int length = 0;
    74     while (buf[length] != 0) { length++; }
    75     return sys_call(SYSCALL_TTY_WRITE,
    76                    (unsigned int)buf,
    77                    length,
    78                    0xFFFFFFFF,
    79                    0);
    80 }
    81 ////////////////////////////////////////////////////////////////////////////////////
    82 // giet_tty_putw()
    83 ////////////////////////////////////////////////////////////////////////////////////
    84 // This function displays the value of a 32-bit word with decimal characters.
    85 // The terminal index must be defined in the task context in the boot phase.
    86 // It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer.
    87 // Returns the number of written characters (should be equal to ten).
    88 ////////////////////////////////////////////////////////////////////////////////////
    89 int giet_tty_putw(unsigned int val)
    90 {
    91     char buf[10];
    92     unsigned int i;
    93     for (i = 0; i < 10; i++)
    94     {
    95         buf[9 - i] = (val % 10) + 0x30;
    96         val = val / 10;
    97     }
    98     return sys_call(SYSCALL_TTY_WRITE,
    99                    (unsigned int)buf,
    100                    10,
    101                    0xFFFFFFFF,
    102                    0);
    103 }
    104 ////////////////////////////////////////////////////////////////////////////////////
    105 // giet_tty_getc()
    106 ////////////////////////////////////////////////////////////////////////////////////
    107 // This blocking function fetches a single ascii character from a terminal.
    108 // The terminal index must be defined in the task context in the boot phase.
    109 // It uses the IRQ_GET interrupt, and the associated kernel buffer.
    110 // - Returns 0 when completed.
    111 ////////////////////////////////////////////////////////////////////////////////////
    112 int giet_tty_getc(char * byte)
    113 {
    114     unsigned int ret = 0;
    115     while (ret == 0)
     24////////////////////////////////////////
     25void giet_tty_printf( char* format, ...)
     26{
     27    va_list args;
     28    va_start( args, format );
     29
     30    int          ret;     // return value from the syscalls
     31    unsigned int channel = 0xFFFFFFFF;
     32
     33printf_text:
     34
     35    while (*format)
     36    {
     37        unsigned int i;
     38        for (i = 0 ; format[i] && (format[i] != '%') ; i++);
     39        if (i)
     40        {
     41            ret = sys_call(SYSCALL_TTY_WRITE,
     42                           (unsigned int)format,
     43                           i,
     44                           channel,
     45                           0);
     46
     47            if (ret != i) goto return_error;
     48
     49            format += i;
     50        }
     51        if (*format == '%')
     52        {
     53            format++;
     54            goto printf_arguments;
     55        }
     56    }
     57
     58    va_end( args );
     59    return;
     60
     61printf_arguments:
     62
     63    {
     64        char buf[20];
     65        char * pbuf;
     66        unsigned int len = 0;
     67        static const char HexaTab[] = "0123456789ABCDEF";
     68        unsigned int i;
     69
     70        switch (*format++)
     71        {
     72            case ('c'):             /* char conversion */
     73            {
     74                int val = va_arg( args, int );
     75                len = 1;
     76                buf[0] = val;
     77                pbuf = &buf[0];
     78                break;
     79            }
     80            case ('d'):             /* 32 bits decimal signed integer */
     81            {
     82                int val = va_arg( args, int );
     83                if (val < 0)
     84                {
     85                    val = -val;
     86                    ret = sys_call(SYSCALL_TTY_WRITE,
     87                                   (unsigned int)"-",
     88                                   1,
     89                                   channel,
     90                                   0);
     91                    if (ret != 1) goto return_error;
     92                }
     93                for(i = 0; i < 10; i++)
     94                {
     95                    buf[9 - i] = HexaTab[val % 10];
     96                    if (!(val /= 10)) break;
     97                }
     98                len =  i + 1;
     99                pbuf = &buf[9 - i];
     100                break;
     101            }
     102            case ('u'):             /* 32 bits decimal unsigned integer */
     103            {
     104                unsigned int val = va_arg( args, unsigned int );
     105                for(i = 0; i < 10; i++)
     106                {
     107                    buf[9 - i] = HexaTab[val % 10];
     108                    if (!(val /= 10)) break;
     109                }
     110                len =  i + 1;
     111                pbuf = &buf[9 - i];
     112                break;
     113            }
     114            case ('x'):             /* 32 bits hexadecimal integer */
     115            {
     116                unsigned int val = va_arg( args, unsigned int );
     117                ret = sys_call(SYSCALL_TTY_WRITE,
     118                               (unsigned int)"0x",
     119                               2,
     120                               channel,
     121                               0);
     122                if (ret != 2) goto return_error;       
     123                for(i = 0; i < 8; i++)
     124                {
     125                    buf[7 - i] = HexaTab[val % 16];
     126                    if (!(val /= 16))  break;
     127                }
     128                len =  i + 1;
     129                pbuf = &buf[7 - i];
     130                break;
     131            }
     132            case ('l'):            /* 64 bits hexadecimal unsigned */
     133            {
     134                unsigned long long val = va_arg( args, unsigned long long );
     135                ret = sys_call(SYSCALL_TTY_WRITE,
     136                               (unsigned int)"0x",
     137                               2,
     138                               channel,
     139                               0);
     140                if (ret != 2) goto return_error;
     141                for(i = 0; i < 16; i++)
     142                {
     143                    buf[15 - i] = HexaTab[val % 16];
     144                    if (!(val /= 16))  break;
     145                }
     146                len =  i + 1;
     147                pbuf = &buf[15 - i];
     148                break;
     149            }
     150            case ('s'):             /* string */
     151            {
     152                char* str = va_arg( args, char* );
     153                while (str[len])
     154                {
     155                    len++;
     156                }
     157                pbuf = str;
     158                break;
     159            }
     160            default:
     161                goto return_error;
     162        }
     163
     164        ret = sys_call(SYSCALL_TTY_WRITE,
     165                       (unsigned int)pbuf,
     166                       len,
     167                       channel,
     168                       0);
     169        if (ret != len)  goto return_error;
     170       
     171        goto printf_text;
     172    }
     173
     174return_error:
     175
     176    va_end( args );
     177    giet_exit("error in giet_tty_printf()");
     178} // end giet_tty_printf()
     179
     180////////////////////////////////////////
     181void giet_shr_printf( char* format, ...)
     182{
     183    va_list args;
     184    va_start( args, format );
     185
     186    int          ret;     // return value from the syscalls
     187    unsigned int channel = 0;
     188    unsigned int sr_save;
     189
     190    sys_call( SYSCALL_TTY_GET_LOCK,
     191              channel,
     192              (unsigned int)&sr_save,
     193              0, 0 );
     194
     195printf_text:
     196
     197    while (*format)
     198    {
     199        unsigned int i;
     200        for (i = 0 ; format[i] && (format[i] != '%') ; i++);
     201        if (i)
     202        {
     203            ret = sys_call(SYSCALL_TTY_WRITE,
     204                           (unsigned int)format,
     205                           i,
     206                           channel,
     207                           0);
     208
     209            if (ret != i) goto return_error;
     210
     211            format += i;
     212        }
     213        if (*format == '%')
     214        {
     215            format++;
     216            goto printf_arguments;
     217        }
     218    }
     219
     220    sys_call( SYSCALL_TTY_RELEASE_LOCK,
     221              channel,
     222              (unsigned int)&sr_save,
     223              0, 0 );
     224 
     225    va_end( args );
     226    return;
     227
     228printf_arguments:
     229
     230    {
     231        char buf[20];
     232        char * pbuf;
     233        unsigned int len = 0;
     234        static const char HexaTab[] = "0123456789ABCDEF";
     235        unsigned int i;
     236
     237        switch (*format++)
     238        {
     239            case ('c'):             /* char conversion */
     240            {
     241                int val = va_arg( args, int );
     242                len = 1;
     243                buf[0] = val;
     244                pbuf = &buf[0];
     245                break;
     246            }
     247            case ('d'):             /* 32 bits decimal signed integer */
     248            {
     249                int val = va_arg( args, int );
     250                if (val < 0)
     251                {
     252                    val = -val;
     253                    ret = sys_call(SYSCALL_TTY_WRITE,
     254                                   (unsigned int)"-",
     255                                   1,
     256                                   channel,
     257                                   0);
     258                    if (ret != 1) goto return_error;
     259                }
     260                for(i = 0; i < 10; i++)
     261                {
     262                    buf[9 - i] = HexaTab[val % 10];
     263                    if (!(val /= 10)) break;
     264                }
     265                len =  i + 1;
     266                pbuf = &buf[9 - i];
     267                break;
     268            }
     269            case ('u'):             /* 32 bits decimal unsigned integer */
     270            {
     271                unsigned int val = va_arg( args, unsigned int );
     272                for(i = 0; i < 10; i++)
     273                {
     274                    buf[9 - i] = HexaTab[val % 10];
     275                    if (!(val /= 10)) break;
     276                }
     277                len =  i + 1;
     278                pbuf = &buf[9 - i];
     279                break;
     280            }
     281            case ('x'):             /* 32 bits hexadecimal integer */
     282            {
     283                unsigned int val = va_arg( args, unsigned int );
     284                ret = sys_call(SYSCALL_TTY_WRITE,
     285                               (unsigned int)"0x",
     286                               2,
     287                               channel,
     288                               0);
     289                if (ret != 2) goto return_error;       
     290                for(i = 0; i < 8; i++)
     291                {
     292                    buf[7 - i] = HexaTab[val % 16];
     293                    if (!(val /= 16))  break;
     294                }
     295                len =  i + 1;
     296                pbuf = &buf[7 - i];
     297                break;
     298            }
     299            case ('l'):            /* 64 bits hexadecimal unsigned */
     300            {
     301                unsigned long long val = va_arg( args, unsigned long long );
     302                ret = sys_call(SYSCALL_TTY_WRITE,
     303                               (unsigned int)"0x",
     304                               2,
     305                               channel,
     306                               0);
     307                if (ret != 2) goto return_error;
     308                for(i = 0; i < 16; i++)
     309                {
     310                    buf[15 - i] = HexaTab[val % 16];
     311                    if (!(val /= 16))  break;
     312                }
     313                len =  i + 1;
     314                pbuf = &buf[15 - i];
     315                break;
     316            }
     317            case ('s'):             /* string */
     318            {
     319                char* str = va_arg( args, char* );
     320                while (str[len])
     321                {
     322                    len++;
     323                }
     324                pbuf = str;
     325                break;
     326            }
     327            default:
     328                goto return_error;
     329        }
     330
     331        ret = sys_call(SYSCALL_TTY_WRITE,
     332                       (unsigned int)pbuf,
     333                       len,
     334                       channel,
     335                       0);
     336        if (ret != len)  goto return_error;
     337       
     338        goto printf_text;
     339    }
     340
     341return_error:
     342
     343    sys_call( SYSCALL_TTY_RELEASE_LOCK,
     344              channel,
     345              (unsigned int)&sr_save,
     346              0, 0 );
     347
     348    va_end( args );
     349    giet_exit("error in giet_shr_printf()");
     350}  // end giet_shr_printf()
     351
     352
     353/////////////////////////////////
     354void giet_tty_getc( char * byte )
     355{
     356    int ret;
     357
     358    do
    116359    {
    117360        ret = sys_call(SYSCALL_TTY_READ,
     
    120363                      0xFFFFFFFF,          // channel index from task context
    121364                      0);
    122     }
    123     return 0;
    124 }
    125 ////////////////////////////////////////////////////////////////////////////////////
    126 // giet_tty_gets()
    127 ////////////////////////////////////////////////////////////////////////////////////
    128 // This blocking function fetches a string from a terminal to a fixed length buffer.
    129 // The terminal index must be defined in the task context in the boot phase.
    130 // It uses the TTY_GET_IRQ interrupt, anf the associated kernel buffer.
    131 // - Returns 0 when completed.
    132 // - Up to (bufsize - 1) characters (including the non printable characters)
    133 //   will be copied into buffer, and the string is always completed by a NUL
    134 //   character.
    135 // - The <LF> character is interpreted, and the function close the string with a
    136 //   NUL character if <LF> is read.
    137 // - The <DEL> character is interpreted, and the corresponding character(s) are
    138 //   removed from the target buffer.
    139 ////////////////////////////////////////////////////////////////////////////////////
    140 int giet_tty_gets( char*        buf,
    141                    unsigned int bufsize)
    142 {
    143     unsigned int ret;
     365        if ( ret < 0 ) giet_exit("error in giet_tty_getc()");
     366    }
     367    while (ret != 1);
     368}
     369
     370/////////////////////////////////////
     371void giet_tty_gets( char*        buf,
     372                    unsigned int bufsize )
     373{
     374    int           ret;
    144375    unsigned char byte;
    145     unsigned int index = 0;
    146 
     376    unsigned int  index = 0;
     377 
    147378    while (index < (bufsize - 1))
    148379    {
     
    154385                           0xFFFFFFFF,
    155386                           0);
     387            if ( ret < 0 ) giet_exit("error in giet_tty_gets()");
    156388        }
    157389        while (ret != 1);
     
    172404    }
    173405    buf[index] = 0;
    174     return 0;
    175 }
    176 ////////////////////////////////////////////////////////////////////////////////////
    177 // giet_tty_getw()
    178 ////////////////////////////////////////////////////////////////////////////////////
    179 // This blocking function fetches a string of decimal characters (most
    180 // significant digit first) to build a 32-bit unsigned integer.
    181 // The terminal index must be defined in the task context in the boot phase.
    182 // It uses the TTY_GET_IRQ interrupt, anf the associated kernel buffer.
    183 // - Returns necessarily 0 when completed.
    184 //
    185 // - The non-blocking system function _tty_read_irq is called several times,
    186 //   and the decimal characters are written in a 32 characters buffer until a
    187 //   <LF> character is read.
    188 // - The <DEL> character is interpreted, and previous characters can be
    189 //   cancelled. All others characters are ignored.
    190 // - When the <LF> character is received, the string is converted to an
    191 //   unsigned int value. If the number of decimal digit is too large for the 32
    192 //   bits range, the zero value is returned.
    193 ////////////////////////////////////////////////////////////////////////////////////
    194 int giet_tty_getw(unsigned int * val)
     406}
     407
     408///////////////////////////////////////
     409void giet_tty_getw( unsigned int* val )
    195410{
    196411    unsigned char buf[32];
    197     unsigned char byte;
    198     unsigned int save = 0;
    199     unsigned int dec = 0;
    200     unsigned int done = 0;
    201     unsigned int overflow = 0;
    202     unsigned int max = 0;
    203     unsigned int i;
    204     unsigned int ret;
    205 
     412    unsigned int  string_byte   = 0x00000000;    // string containing one single byte
     413    unsigned int  string_cancel = 0x00082008;    // string containing BS/SPACE/BS
     414    unsigned int  save = 0;
     415    unsigned int  dec = 0;
     416    unsigned int  done = 0;
     417    unsigned int  overflow = 0;
     418    unsigned int  length = 0;
     419    unsigned int  i;
     420    unsigned int  channel = 0xFFFFFFFF;
     421    int           ret;      // return value from syscalls
     422 
     423    // get characters
    206424    while (done == 0)
    207425    {
     426        // read one character
    208427        do
    209428        {
    210             ret = sys_call(SYSCALL_TTY_READ,
    211                            (unsigned int)(&byte),
    212                            1,
    213                            0xFFFFFFFF,
    214                            0);
     429            ret = sys_call( SYSCALL_TTY_READ,
     430                            (unsigned int)(&string_byte),
     431                            1,
     432                            channel,
     433                            0);
     434            if ( ret < 0 ) giet_exit("error in giet_tty_getw()");
    215435        }
    216436        while (ret != 1);
    217437
    218         if ((byte > 0x2F) && (byte < 0x3A))  /* decimal character */
    219         {
    220             buf[max] = byte;
    221             max++;
    222             giet_tty_putc(byte);
    223         }
    224         else if ((byte == 0x0A))   /* LF */
     438        // analyse character
     439        if ((string_byte > 0x2F) && (string_byte < 0x3A))  /* decimal character */
     440        {
     441            buf[length] = (unsigned char)string_byte;
     442            length++;
     443
     444            // echo
     445            ret = sys_call( SYSCALL_TTY_WRITE,
     446                            (unsigned int)(&string_byte),
     447                            1,
     448                            channel,
     449                            0 );
     450            if ( ret < 0 ) giet_exit("error in giet_tty_gets()");
     451        }
     452        else if (string_byte == 0x0A)                     /* LF character */
    225453        {
    226454            done = 1;
    227455        }
    228         else if (byte == 0x7F)   /* DEL */
    229         {
    230             if (max > 0)
    231             {
    232                 max--;      /* cancel the character */
    233                 giet_tty_putc(0x08);
    234                 giet_tty_putc(0x20);
    235                 giet_tty_putc(0x08);
    236             }
    237         }
    238         if (max == 32)  /* decimal string overflow */
    239         {
    240             for (i = 0; i < max; i++)
    241             {
    242                 /* cancel the string */
    243                 giet_tty_putc(0x08);
    244                 giet_tty_putc(0x20);
    245                 giet_tty_putc(0x08);
    246             }
    247             giet_tty_putc(0x30);
    248             *val = 0;      /* return 0 value */
    249             return 0;
    250         }
    251     }
    252 
    253     /* string conversion */
    254     for (i = 0; i < max; i++)
    255     {
    256         dec = dec * 10 + (buf[i] - 0x30);
    257         if (dec < save)  overflow = 1;
    258         save = dec;
    259     }
    260 
    261     /* check overflow */
    262     if (overflow == 0)
    263     {
    264         *val = dec; /* return decimal value */
    265     }
    266     else
    267     {
    268         for (i = 0; i < max; i++)
    269         {
    270             /* cancel the string */
    271             giet_tty_putc(0x08);
    272             giet_tty_putc(0x20);
    273             giet_tty_putc(0x08);
    274         }
    275         giet_tty_putc(0x30);
    276         *val = 0;         /* return 0 value */
    277     }
    278     return 0;
    279 }
    280 ////////////////////////////////////////////////////////////////////////////////////
    281 // giet_tty_printf()
    282 ////////////////////////////////////////////////////////////////////////////////////
    283 // This function is a simplified version of the mutek_printf() function.
    284 // The terminal index must be defined in the calling task context.
    285 // It doesn't use the IRQ_PUT interrupt, and the associated kernel buffer.
    286 // Only a limited number of formats are supported:
    287 //   - %d : signed decimal
    288 //   - %u : unsigned decimal
    289 //   - %x : hexadecimal
    290 //   - %c : char
    291 //   - %s : string
    292 // - Returns 0 if success, > 0 if error.
    293 ////////////////////////////////////////////////////////////////////////////////////
    294 int giet_tty_printf(char * format, ...)
    295 {
    296     va_list ap;
    297     va_start(ap, format);
    298     unsigned int ret;
    299 
    300     if (NB_TTY_CHANNELS == 1)
    301     {
    302         ret = sys_call(SYSCALL_TTY_LOCK, 0, 0, 0, 0); // Get TTY lock
    303     }
    304 
    305 printf_text:
    306 
    307     while (*format)
    308     {
    309         unsigned int i;
    310         for (i = 0 ; format[i] && (format[i] != '%') ; i++);
    311         if (i)
    312         {
    313             ret = sys_call(SYSCALL_TTY_WRITE,
    314                            (unsigned int)format,
    315                            i,
    316                            0xFFFFFFFF,
    317                            0);
    318 
    319             if (ret != i) goto return_error;
    320 
    321             format += i;
    322         }
    323         if (*format == '%')
    324         {
    325             format++;
    326             goto printf_arguments;
    327         }
    328     }
    329 
    330     if (NB_TTY_CHANNELS == 1)
    331     {
    332         ret = sys_call(SYSCALL_TTY_LOCK, 1, 0, 0, 0); // Release TTY lock
    333     }
    334 
    335     va_end(ap);
    336     return 0;
    337 
    338 printf_arguments:
    339 
    340     {
    341         int val = va_arg(ap, long);
    342         char buf[20];
    343         char * pbuf;
    344         unsigned int len = 0;
    345         static const char HexaTab[] = "0123456789ABCDEF";
    346         unsigned int i;
    347 
    348         switch (*format++) {
    349             case ('c'):             /* char conversion */
    350                 len = 1;
    351                 buf[0] = val;
    352                 pbuf = buf;
    353                 break;
    354             case ('d'):             /* decimal signed integer */
    355                 if (val < 0)
    356                 {
    357                     val = -val;
    358                     ret = sys_call(SYSCALL_TTY_WRITE,
    359                                    (unsigned int)"-",
    360                                    1,
    361                                    0xFFFFFFFF,
    362                                    0);
    363                     if (ret != 1) goto return_error;
    364                 }
    365             case ('u'):             /* decimal unsigned integer */
    366                 for(i = 0; i < 10; i++)
    367                 {
    368                     buf[9 - i] = HexaTab[val % 10];
    369                     if (!(val /= 10)) break;
    370                 }
    371                 len =  i + 1;
    372                 pbuf = &buf[9 - i];
    373                 break;
    374             case ('x'):             /* hexadecimal integer */
    375                 ret = sys_call(SYSCALL_TTY_WRITE,
    376                                (unsigned int)"0x",
    377                                2,
    378                                0xFFFFFFFF,
    379                                0);
    380                 if (ret != 2) goto return_error;       /* return error */
    381                 for(i = 0; i < 8; i++)
    382                 {
    383                     buf[7 - i] = HexaTab[val % 16U];
    384                     if (!(val /= 16U))  break;
    385                 }
    386                 len =  i + 1;
    387                 pbuf = &buf[7 - i];
    388                 break;
    389             case ('s'):             /* string */
    390                 {
    391                     char * str = (char *) val;
    392                     while (str[len])
    393                     {
    394                         len++;
    395                     }
    396                     pbuf = (char *) val;
    397                 }
    398                 break;
    399             default:
    400                 goto printf_text;
    401         }
    402 
    403         ret = sys_call(SYSCALL_TTY_WRITE,
    404                        (unsigned int)pbuf,
    405                        len,
    406                        0xFFFFFFFF,
    407                        0);
    408         if (ret != len)  goto return_error;
    409        
    410         goto printf_text;
    411     }
    412 
    413 return_error:
    414     if (NB_TTY_CHANNELS == 1)
    415     {
    416         ret = sys_call(SYSCALL_TTY_LOCK, 1, 0, 0, 0); // Release TTY lock
    417     }
    418 
    419     return 1;
    420 }
    421 
     456        else if ( (string_byte == 0x7F) ||                /* DEL character */
     457                  (string_byte == 0x08) )                 /* BS  character */
     458        {
     459            if ( length > 0 )
     460            {
     461                length--;    // cancel the character
     462
     463                ret = sys_call( SYSCALL_TTY_WRITE,
     464                                (unsigned int)(&string_cancel),
     465                                3,
     466                                channel,
     467                                0 );
     468                if ( ret < 0 ) giet_exit("error in giet_tty_gets()");
     469            }
     470        }
     471
     472        // test buffer overflow
     473        if ( length >= 32 ) 
     474        {
     475            overflow = 1;
     476            done     = 1;
     477        }
     478    }  // end while characters
     479
     480    // string to int conversion with overflow detection
     481    if ( overflow == 0 )
     482    {
     483        for (i = 0; (i < length) && (overflow == 0) ; i++)
     484        {
     485            dec = dec * 10 + (buf[i] - 0x30);
     486            if (dec < save)  overflow = 1;
     487            save = dec;
     488        }
     489    }
     490
     491    // final evaluation
     492    if ( overflow == 0 )
     493    {
     494        // return value
     495        *val = dec;
     496    }
     497    else
     498    {
     499        // cancel all echo characters
     500        for (i = 0; i < length ; i++)
     501        {
     502            ret = sys_call( SYSCALL_TTY_WRITE,
     503                            (unsigned int)(&string_cancel),
     504                            3,
     505                            channel,
     506                            0 );
     507            if ( ret < 0 ) giet_exit("error in giet_tty_gets()");
     508        }
     509        // echo character '0'
     510        string_byte = 0x30;
     511        ret = sys_call( SYSCALL_TTY_WRITE,
     512                        (unsigned int)(&string_byte),
     513                        1,
     514                        channel,
     515                        0 );
     516        if ( ret < 0 ) giet_exit();
     517
     518        // return 0 value
     519        *val = 0;
     520    }
     521}
    422522
    423523
     
    426526//////////////////////////////////////////////////////////////////////////////////
    427527
    428 //////////////////////////////////////////////////////////////////////////////////
    429 // giet_timer_start()
    430 //////////////////////////////////////////////////////////////////////////////////
    431 // This function activates the private user timer allocated to the calling task
    432 // in the boot phase.
    433 // - Returns 0 if success, > 0 if error.
    434 //////////////////////////////////////////////////////////////////////////////////
    435 int giet_timer_start()
    436 {
    437     return sys_call( SYSCALL_TIMER_START,
    438                      0, 0, 0, 0 );
    439 }
    440 //////////////////////////////////////////////////////////////////////////////////
    441 // giet_timer_stop()
    442 //////////////////////////////////////////////////////////////////////////////////
    443 // This function activates the user timer allocated to the calling task.
    444 // - Returns 0 if success, > 0 if error.
    445 //////////////////////////////////////////////////////////////////////////////////
    446 int giet_timer_stop()
    447 {
    448     return sys_call( SYSCALL_TIMER_STOP,
    449                      0, 0, 0, 0 );
     528///////////////////////
     529void giet_timer_start()
     530{
     531    if ( sys_call( SYSCALL_TIMER_START, 0, 0, 0, 0 ) )
     532       giet_exit("error in giet_timer_start()");
     533}
     534
     535//////////////////////
     536void giet_timer_stop()
     537{
     538    if ( sys_call( SYSCALL_TIMER_STOP, 0, 0, 0, 0 ) )
     539        giet_exit("error in giet_timer_stop()");
    450540}
    451541
     
    455545//////////////////////////////////////////////////////////////////////////////////
    456546
    457 //////////////////////////////////////////////////////////////////////////////////
    458 // giet_fb_sync_write()
    459 //////////////////////////////////////////////////////////////////////////////////
    460 // This blocking function use a memory copy strategy to transfer data from a
    461 // user buffer to the frame buffer device in kernel space.
    462 //     offset : offset (in bytes) in the frame buffer
    463 //     buffer : base address of the memory buffer
    464 //     length : number of bytes to be transfered
    465 // - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space).
    466 //////////////////////////////////////////////////////////////////////////////////
    467 int giet_fb_sync_write( unsigned int offset,
     547////////////////////////////////////////////
     548void giet_fb_sync_write( unsigned int offset,
    468549                        void *       buffer,
    469550                        unsigned int length )
    470551{
    471     return sys_call( SYSCALL_FB_SYNC_WRITE,
    472                      offset,
    473                      (unsigned int)buffer,
    474                      length,
    475                      0 );
    476 }
    477 //////////////////////////////////////////////////////////////////////////////////
    478 // giet_fb_sync_read()
    479 //////////////////////////////////////////////////////////////////////////////////
    480 // This blocking function use a memory copy strategy to transfer data from the
    481 // frame buffer device in kernel space to an user buffer.
    482 //     offset : offset (in bytes) in the frame buffer
    483 //     buffer : base address of the user buffer
    484 //     length : number of bytes to be transfered
    485 // - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space).
    486 //////////////////////////////////////////////////////////////////////////////////
    487 int giet_fb_sync_read( unsigned int offset,
    488                        void *       buffer,
    489                        unsigned int length )
    490 {
    491     return sys_call( SYSCALL_FB_SYNC_READ,
    492                      offset,
    493                      (unsigned int)buffer,
    494                      length,
    495                      0 );
    496 }
    497 //////////////////////////////////////////////////////////////////////////////////
    498 // giet_fb_cma_init()
    499 //////////////////////////////////////////////////////////////////////////////////
    500 // This function initializes the two chbuf SRC an DST used by the CMA controller
    501 // and activates the CMA channel allocated to the calling task.
    502 // - buf0   : first user buffer virtual address
    503 // - buf0   : second user buffer virtual address
    504 // - length : buffer size (bytes)
    505 // - Returns 0 if success, > 0 if error.
    506 //////////////////////////////////////////////////////////////////////////////////
    507 int giet_fb_cma_init( void *       buf0,
    508                       void *       buf1,
    509                       unsigned int length )
    510 {
    511     return sys_call( SYSCALL_FB_CMA_INIT,
    512                      (unsigned int)buf0,
    513                      (unsigned int)buf1,
    514                      length,
    515                      0 );
    516 }
    517 //////////////////////////////////////////////////////////////////////////////////
    518 // giet_fb_cma_write()
    519 //////////////////////////////////////////////////////////////////////////////////
    520 // This function set the valid status for one of the SRC user buffer.
    521 // and reset the valid status for the DST frame buffer.
    522 // - bufffer_id : 0 => buf0 valid is set / not 0  => buf1 valid is set
    523 // - Returns 0 if success, > 0 if error.
    524 //////////////////////////////////////////////////////////////////////////////////
    525 int giet_fb_cma_write( unsigned int buffer_id )
    526 {
    527     return sys_call( SYSCALL_FB_CMA_WRITE,
    528                      buffer_id,
    529                      0, 0, 0 );
    530 }
    531 //////////////////////////////////////////////////////////////////////////////////
    532 // giet_fb_cma_stop()
    533 //////////////////////////////////////////////////////////////////////////////////
    534 // This function desactivates the CMA channel allocated to the calling task.
    535 // - Returns 0 if success, > 0 if error.
    536 //////////////////////////////////////////////////////////////////////////////////
    537 int giet_fb_cma_stop( )
    538 {
    539     return sys_call( SYSCALL_FB_CMA_STOP,
    540                      0, 0, 0, 0 );
     552    if ( sys_call( SYSCALL_FB_SYNC_WRITE,
     553                   offset,
     554                   (unsigned int)buffer,
     555                   length,
     556                   0 ) )  giet_exit("error in giet_fb_sync_write()");
     557}
     558
     559///////////////////////////////////////////
     560void giet_fb_sync_read( unsigned int offset,
     561                        void *       buffer,
     562                        unsigned int length )
     563{
     564    if ( sys_call( SYSCALL_FB_SYNC_READ,
     565                   offset,
     566                   (unsigned int)buffer,
     567                   length,
     568                   0 ) )   giet_exit("error in giet_fb_sync_read()");
     569}
     570
     571/////////////////////////////////////////
     572void giet_fb_cma_init( void *       buf0,
     573                       void *       buf1,
     574                       unsigned int length )
     575{
     576    if ( sys_call( SYSCALL_FB_CMA_INIT,
     577                   (unsigned int)buf0,
     578                   (unsigned int)buf1,
     579                   length,
     580                   0 ) )   giet_exit("error in giet_fb_cma_init()");
     581}
     582
     583///////////////////////////////////////////////
     584void giet_fb_cma_write( unsigned int buffer_id )
     585{
     586    if ( sys_call( SYSCALL_FB_CMA_WRITE,
     587                   buffer_id,
     588                   0, 0, 0 ) )   giet_exit("error in giet_fb_cma_write()");
     589}
     590
     591////////////////////////
     592void giet_fb_cma_stop()
     593{
     594    if ( sys_call( SYSCALL_FB_CMA_STOP,
     595                   0, 0, 0, 0 ) )    giet_exit("error in giet_fb_cma_stop()");
    541596}
    542597
     
    546601//////////////////////////////////////////////////////////////////////////////////
    547602
    548 //////////////////////////////////////////////////////////////////////////////////
    549 // giet_nic_cma_init()
    550 //////////////////////////////////////////////////////////////////////////////////
    551 // This function initializes the memory chbuf used by the CMA controller,
    552 // activates the NIC channel allocated to the calling task, and the CMA channel.
    553 // - tx     : RX channel if 0 / TX channel if non 0
    554 // - buf0   : first user buffer virtual address
    555 // - buf1   : second user buffer virtual address
    556 // - length : buffer size (bytes)
    557 // - Returns 0 if success, > 0 if error
    558 //////////////////////////////////////////////////////////////////////////////////
    559 int giet_nic_cma_start()
    560 {
    561     return sys_call( SYSCALL_NIC_CMA_START,
    562                      0, 0, 0, 0 );
    563 }
    564 //////////////////////////////////////////////////////////////////////////////////
    565 // giet_nic_cma_stop()
    566 //////////////////////////////////////////////////////////////////////////////////
    567 // This function desactivates the NIC channel and the two CMA channels
    568 // allocated to the calling task.
    569 // - Returns 0 if success, > 0 if error.
    570 //////////////////////////////////////////////////////////////////////////////////
    571 int giet_nic_cma_stop( )
    572 {
    573     return sys_call( SYSCALL_NIC_CMA_STOP,
    574                      0, 0, 0, 0 );
    575 }
    576 
    577 
    578 //////////////////////////////////////////////////////////////////////////////////
    579 ///////////////////// Miscellaneous system calls /////////////////////////////////
    580 //////////////////////////////////////////////////////////////////////////////////
    581 
    582 ///////////////////////////////////////////////////////////////////////////////////
    583 // giet_assert()
    584 ///////////////////////////////////////////////////////////////////////////////////
    585 // This function uses the giet_tty_puts() and giet_exit() system calls.
    586 ///////////////////////////////////////////////////////////////////////////////////
    587 void giet_assert( unsigned int condition,
    588                   char*        string )
    589 {
    590     if ( condition == 0 )
    591     {
    592         giet_tty_puts( string );
    593         giet_exit();
    594     }
    595 }
    596 //////////////////////////////////////////////////////////////////////////////////
    597 // giet_vobj_get_vbase()
    598 //////////////////////////////////////////////////////////////////////////////////
    599 // This function writes in argument (vobj_vaddr) the virtual base address
    600 // of a vobj (defined in the mapping_info data structure), identified by
    601 // the two arguments (vspace_name and vobj_name).
    602 // The (vobj_type) argument is redundant, and used for coherence checking.
    603 // - Returns the address if success,  0 if error ( not defined or wrong type )
    604 //////////////////////////////////////////////////////////////////////////////////
    605 int giet_vobj_get_vbase( char*         vspace_name,
    606                          char*         vobj_name,
    607                          unsigned int  vobj_type,
    608                          unsigned int* vobj_vaddr )
    609 {
    610     return sys_call( SYSCALL_VOBJ_GET_VBASE,
    611                      (unsigned int) vspace_name,
    612                      (unsigned int) vobj_name,
    613                      (unsigned int) vobj_type,
    614                      (unsigned int) vobj_vaddr );
    615 }
    616 ////////////////////////////////////////////////////////////////////////////////////
    617 // giet_proc_number()
    618 ////////////////////////////////////////////////////////////////////////////////////
    619 // This function returns in the buffer argument the number of processors
    620 // in the cluster specified by the cluster_id argument.
    621 // - Returns 0 if success, > 0 if error ( cluster index too large )
    622 ////////////////////////////////////////////////////////////////////////////////////
    623 int giet_proc_number( unsigned int  cluster_id,
    624                       unsigned int* buffer )
    625 {
    626     return sys_call(SYSCALL_PROC_NUMBER, cluster_id, (unsigned int) buffer, 0, 0);
    627 }
    628 //////////////////////////////////////////////////////////////////////////////////
    629 // giet_exit()
    630 //////////////////////////////////////////////////////////////////////////////////
    631 // This function stops execution of the calling task with a TTY message,
    632 // the user task is descheduled and becomes not runable.
    633 // It does not consume processor cycles anymore.
    634 //////////////////////////////////////////////////////////////////////////////////
    635 void giet_exit()
    636 {
    637     sys_call( SYSCALL_EXIT,
    638               0, 0, 0, 0 );
    639 }
    640 //////////////////////////////////////////////////////////////////////////////////
    641 // giet_context_switch()
    642 //////////////////////////////////////////////////////////////////////////////////
    643 // The user task calling this function is descheduled and
    644 // the processor is allocated to another task.
    645 //////////////////////////////////////////////////////////////////////////////////
    646 int giet_context_switch()
    647 {
    648     return sys_call( SYSCALL_CTX_SWITCH,
    649                      0, 0, 0, 0 );
    650 }
    651 //////////////////////////////////////////////////////////////////////////////////
    652 // giet_proc_task_id()
    653 //////////////////////////////////////////////////////////////////////////////////
    654 // This functions returns the local task id.
    655 // If processor has n tasks the local task index is ranging from 0 to n-1
    656 //////////////////////////////////////////////////////////////////////////////////
    657 int giet_proc_task_id()
    658 {
    659     return sys_call( SYSCALL_LOCAL_TASK_ID,
    660                      0, 0, 0, 0 );
    661 }
    662 //////////////////////////////////////////////////////////////////////////////////
    663 // giet_heap_info()
    664 //////////////////////////////////////////////////////////////////////////////////
    665 // This function returns the base address and size of the current task's heap
    666 //////////////////////////////////////////////////////////////////////////////////
    667 int giet_heap_info( unsigned int* vaddr,
    668                              unsigned int* length )
    669 {
    670     return sys_call( SYSCALL_HEAP_INFO,
    671                      (unsigned int)vaddr,
    672                      (unsigned int)length,
    673                      0, 0 );
    674 }
    675 //////////////////////////////////////////////////////////////////////////////////
    676 // giet_global_task_id()
    677 //////////////////////////////////////////////////////////////////////////////////
    678 // This functions returns the global task id, which is unique in all the giet.
    679 //////////////////////////////////////////////////////////////////////////////////
    680 int giet_global_task_id()
    681 {
    682     return sys_call( SYSCALL_GLOBAL_TASK_ID,
    683                      0, 0, 0, 0 );
    684 }
    685 
    686 //////////////////////////////////////////////////////////////////////////////////
    687 // giet_thread_id()
    688 //////////////////////////////////////////////////////////////////////////////////
    689 // This functions returns the thread index of the current task.
    690 //////////////////////////////////////////////////////////////////////////////////
    691 int giet_thread_id()
    692 {
    693     return sys_call( SYSCALL_THREAD_ID,
    694                      0, 0, 0, 0 );
     603/////////////////////////
     604void giet_nic_cma_start()
     605{
     606    if ( sys_call( SYSCALL_NIC_CMA_START, 0, 0, 0, 0 ) ) 
     607       giet_exit("error in giet_nic_cma_start()");
     608}
     609
     610/////////////////////////
     611void giet_nic_cma_stop()
     612{
     613    if ( sys_call( SYSCALL_NIC_CMA_STOP, 0, 0, 0, 0 ) ) 
     614        giet_exit("error in giet_nic_cma_stop()");
    695615}
    696616
     
    699619///////////////////////////////////////////////////////////////////////////////////
    700620
    701 ///////////////////////////////////////////////////////////////////////////////////
    702 // giet_fat_open()
    703 ///////////////////////////////////////////////////////////////////////////////////
    704 // Open a file identified by a pathname, and contained in the system FAT.
    705 // The read/write flags are not supported yet: no effect.
    706 ///////////////////////////////////////////////////////////////////////////////////
     621///////////////////////////////////////////
    707622int giet_fat_open( const char*   pathname,
    708623                   unsigned int  flags )
     
    713628                     0, 0 );
    714629}
     630
     631////////////////////////////////////
     632void giet_fat_read( unsigned int fd,     
     633                    void*        buffer,
     634                    unsigned int count, 
     635                    unsigned int offset )
     636{
     637    if ( sys_call( SYSCALL_FAT_READ,
     638                   fd,
     639                   (unsigned int)buffer,
     640                   count,
     641                   offset ) != count ) giet_exit("in giet_fat_read()");
     642}
     643
     644/////////////////////////////////////
     645void giet_fat_write( unsigned int fd,
     646                     void*        buffer,
     647                     unsigned int count,
     648                     unsigned int offset )
     649{
     650    if ( sys_call( SYSCALL_FAT_WRITE,
     651                   fd,
     652                   (unsigned int)buffer,
     653                   count,
     654                   offset ) != count ) giet_exit("in giet_fat_write()");
     655}
     656
     657/* variant implementing the UNIX spec
    715658///////////////////////////////////////////////////////////////////////////////////
    716 // giet_fat_read()
     659// This system call writes to a file identified by the "fd" file descriptor.
     660// - "buffer" is the source buffer virtual address (must be word aligned).
     661// - "count" is a number of bytes (must be multiple of 4).
     662// It uses the implicit "lseek" pointer in file descriptor.
    717663///////////////////////////////////////////////////////////////////////////////////
    718 // Read "count" sectors from a file identified by "fd", skipping "offset"
    719 // sectors in file, and writing into the user "buffer".
    720 // The user buffer base address shoulb be 64 bytes aligned.
    721 ///////////////////////////////////////////////////////////////////////////////////
    722 // This system call specification should evolve to the UNIX specification:
    723 // - count must be a number of bytes, with no alignment constraint on user buffer.
    724 // - offset argument should be removed and replaced by an implicit "lseek" pointer
    725 //   stored in the file descriptor.
    726 // This suppose to implement a sectors cache
    727 ///////////////////////////////////////////////////////////////////////////////////
    728 int giet_fat_read( unsigned int fd,
    729                    void*        buffer,
    730                    unsigned int count,
    731                    unsigned int offset )
    732 {
    733     return sys_call( SYSCALL_FAT_READ,
    734                      fd,
    735                      (unsigned int)buffer,
    736                      count,
    737                      offset );
    738 }
    739 ///////////////////////////////////////////////////////////////////////////////////
    740 // giet_fat_write()
    741 ///////////////////////////////////////////////////////////////////////////////////
    742 // Write "count" sectors from a file identified by "fd", skipping "offset"
    743 // sectors in file, and reading from the user "buffer".
    744 // The user buffer base address shoulb be 64 bytes aligned.
    745 ///////////////////////////////////////////////////////////////////////////////////
    746 // This system call specification should evolve to the UNIX specification:
    747 // - count must be a number of bytes, with no alignment constraint on buffer
    748 // - offset argument should be removed and replaced by an implicit "lseek" pointer
    749 //   stored in the file descriptor.
    750 // This suppose to implement a sectors cache
    751 ///////////////////////////////////////////////////////////////////////////////////
    752 int giet_fat_write( unsigned int fd,
     664void giet_fat_write( unsigned int fd,
    753665                    void*        buffer,
    754                     unsigned int count,
    755                     unsigned int offset )
     666                    unsigned int count )  // number of bytes
    756667{
    757668    return sys_call( SYSCALL_FAT_WRITE,
    758669                     fd,
    759670                     (unsigned int)buffer,
    760                      count,
    761                      offset );
    762 }
    763 ///////////////////////////////////////////////////////////////////////////////////
    764 // giet_fat_lseek()
    765 ///////////////////////////////////////////////////////////////////////////////////
    766 // Change the lseek file pointer value for a file identified by "fd".
    767 ///////////////////////////////////////////////////////////////////////////////////
    768 int giet_fat_lseek( unsigned int fd,
     671                     count, 0 );
     672}
     673*/
     674
     675/////////////////////////////////////
     676void giet_fat_lseek( unsigned int fd,
    769677                    unsigned int offset,
    770                     unsigned int whence)
    771 {
    772     return sys_call( SYSCALL_FAT_LSEEK,
    773                      fd,
    774                      offset,
    775                      whence,
    776                      0 );
    777 }
    778 
    779 ///////////////////////////////////////////////////////////////////////////////////
    780 // giet_fat_fstat()
    781 ///////////////////////////////////////////////////////////////////////////////////
    782 // Return stats of a file identified by "fd".
    783 // (Only the file_size in sectors for this moment)
    784 ///////////////////////////////////////////////////////////////////////////////////
    785 int giet_fat_fstat( unsigned int fd )
    786 {
    787     return sys_call( SYSCALL_FAT_FSTAT,
    788                      fd,
    789                      0, 0, 0 );
    790 }
    791 
    792 ///////////////////////////////////////////////////////////////////////////////////
    793 // giet_fat_close()
    794 ///////////////////////////////////////////////////////////////////////////////////
    795 // Close a file identified by "fd".
    796 ///////////////////////////////////////////////////////////////////////////////////
    797 int giet_fat_close( unsigned int fd )
    798 {
    799     return sys_call( SYSCALL_FAT_CLOSE,
    800                      fd,
    801                      0, 0, 0 );
    802 }
    803 
    804 
    805 ///////////////////////////////////////////////////////////////////////////////////
    806 ////////////////// Pseudo system calls (no syscall instruction) ///////////////////
    807 ///////////////////////////////////////////////////////////////////////////////////
    808 
    809 ///////////////////////////////////////////////////////////////////////////////////
    810 // giet_rand()
    811 // This function returns a pseudo-random value derived from the processor cycle
    812 // count. This value is comprised between 0 & 65535.
    813 ///////////////////////////////////////////////////////////////////////////////////
     678                    unsigned int whence )
     679{
     680    if ( sys_call( SYSCALL_FAT_LSEEK,
     681                   fd,
     682                   offset,
     683                   whence,
     684                   0 ) ) giet_exit("in giet_fat_lseek()");
     685}
     686
     687//////////////////////////////////////
     688void giet_fat_fstat( unsigned int fd )
     689{
     690    if ( sys_call( SYSCALL_FAT_FSTAT,
     691                   fd,
     692                   0, 0, 0 ) )  giet_exit("in giet_fat_lseek()");
     693}
     694
     695/////////////////////////////////////
     696void giet_fat_close( unsigned int fd )
     697{
     698    if ( sys_call( SYSCALL_FAT_CLOSE,
     699                   fd,
     700                   0, 0, 0 ) )  giet_exit("in giet_fat_close()");
     701}
     702
     703
     704//////////////////////////////////////////////////////////////////////////////////
     705///////////////////// Miscellaneous system calls /////////////////////////////////
     706//////////////////////////////////////////////////////////////////////////////////
     707
     708/////////////////
     709int giet_procid()
     710{
     711    return sys_call( SYSCALL_PROCID,
     712                     0, 0, 0, 0 );
     713}
     714
     715////////////////////
     716int giet_proctime()
     717{
     718    return sys_call( SYSCALL_PROCTIME,
     719                     0, 0, 0, 0 );
     720}
     721
     722///////////////////////
     723int giet_proc_task_id()
     724{
     725    return sys_call( SYSCALL_LOCAL_TASK_ID,
     726                     0, 0, 0, 0 );
     727}
     728
     729/////////////////////////
     730int giet_global_task_id()
     731{
     732    return sys_call( SYSCALL_GLOBAL_TASK_ID,
     733                     0, 0, 0, 0 );
     734}
     735
     736////////////////////
     737int giet_thread_id()
     738{
     739    return sys_call( SYSCALL_THREAD_ID,
     740                     0, 0, 0, 0 );
     741}
     742
     743///////////////
    814744int giet_rand()
    815745{
     
    822752    }
    823753}
     754
     755//////////////////////////////
     756void giet_exit( char* string )
     757{
     758    sys_call( SYSCALL_EXIT,
     759              (unsigned int)string,
     760              0, 0, 0 );
     761}
     762
     763/////////////////////////////////////////
     764void giet_assert( unsigned int condition,
     765                  char*        string )
     766{
     767    if ( condition == 0 ) giet_exit( string );
     768}
     769
     770////////////////////////////////////////////////////
     771void giet_vobj_get_vbase( char*         vspace_name,
     772                          char*         vobj_name,
     773                          unsigned int* vobj_vaddr )
     774{
     775    if ( sys_call( SYSCALL_VOBJ_GET_VBASE,
     776                   (unsigned int) vspace_name,
     777                   (unsigned int) vobj_name,
     778                   (unsigned int) vobj_vaddr,
     779                   0 ) )  giet_exit("in giet_vobj_get_vbase()");
     780}
     781
     782///////////////////////////////////////////////
     783void giet_proc_number( unsigned int  cluster_id,
     784                      unsigned int* buffer )
     785{
     786    if ( sys_call( SYSCALL_PROC_NUMBER,
     787                   cluster_id,
     788                   (unsigned int) buffer,
     789                   0, 0) )  giet_exit("in giet_proc_number()");
     790}
     791
     792//////////////////////////
     793void giet_context_switch()
     794{
     795    sys_call( SYSCALL_CTX_SWITCH,
     796              0, 0, 0, 0 );
     797}
     798
     799/////////////////////////////////////////
     800void giet_heap_info( unsigned int* vaddr,
     801                     unsigned int* length )
     802{
     803    if ( sys_call( SYSCALL_HEAP_INFO,
     804                   (unsigned int)vaddr,
     805                   (unsigned int)length,
     806                   0, 0 ) )  giet_exit("in giet_heap_info()");
     807}
     808
    824809
    825810// Local Variables:
  • soft/giet_vm/giet_libs/stdio.h

    r267 r295  
    1818#define SYSCALL_TIMER_START       0x04
    1919#define SYSCALL_TIMER_STOP        0x05
    20 #define SYSCALL_FREE_06           0x06
    21 #define SYSCALL_FREE_07           0x07
     20#define SYSCALL_TTY_GET_LOCK      0x06
     21#define SYSCALL_TTY_RELEASE_LOCK  0x07
    2222#define SYSCALL_HEAP_INFO         0x08
    2323#define SYSCALL_LOCAL_TASK_ID     0x09
     
    3232#define SYSCALL_FB_SYNC_READ      0x11
    3333#define SYSCALL_THREAD_ID         0x12
    34 #define SYSCALL_TTY_LOCK          0x13
     34#define SYSCALL_FREE_13           0x13
    3535#define SYSCALL_FREE_14           0x14
    3636#define SYSCALL_FREE_15           0x15
     
    9999
    100100//////////////////////////////////////////////////////////////////////////
    101 // MIPS32 related system calls
    102 //////////////////////////////////////////////////////////////////////////
    103 
    104 extern int giet_procid();
    105 
    106 extern int giet_proctime();
    107 
    108 //////////////////////////////////////////////////////////////////////////
    109 // TTY device related system calls
    110 //////////////////////////////////////////////////////////////////////////
    111 
    112 extern int giet_tty_putc(char byte);
    113 
    114 extern int giet_tty_puts(char* buf);
    115 
    116 extern int giet_tty_putw(unsigned int val);
    117 
    118 extern int giet_tty_getc_no_irq(char* byte);
    119 
    120 extern int giet_tty_getc(char* byte);
    121 
    122 extern int giet_tty_gets(char* buf, unsigned int bufsize);
    123 
    124 extern int giet_tty_getw(unsigned int* val);
    125 
    126 extern int giet_tty_printf(char* format,...);
    127 
    128 //////////////////////////////////////////////////////////////////////////
    129 // TIMER device related system calls
    130 //////////////////////////////////////////////////////////////////////////
    131 
    132 extern int giet_timer_start();
    133 
    134 extern int giet_timer_stop();
     101//////////////////////////////////////////////////////////////////////////
     102//               MIPS32 related system calls
     103//////////////////////////////////////////////////////////////////////////
     104//////////////////////////////////////////////////////////////////////////
     105
     106//////////////////////////////////////////////////////////////////////////
     107//////////////////////////////////////////////////////////////////////////
     108//             TTY device related system calls
     109//////////////////////////////////////////////////////////////////////////
     110//////////////////////////////////////////////////////////////////////////
     111
     112//////////////////////////////////////////////////////////////////////////
     113// This function is a modified version of the mutek_printf().
     114// It uses a private terminal allocated to the calling task in the boot.
     115// ("use_tty" argument in xml mapping), and does not take the TTY lock.
     116// It calls several times the _tty_write system function.
     117// Only a limited number of formats are supported:
     118//   - %d : signed decimal
     119//   - %u : unsigned decimal
     120//   - %x : 32 bits hexadecimal
     121//   - %l : 64 bits hexadecimal
     122//   - %c : char
     123//   - %s : string
     124// In case or error returned by syscall, it makes a giet_exit().
     125//////////////////////////////////////////////////////////////////////////
     126extern void giet_tty_printf( char* format, ... );
     127
     128//////////////////////////////////////////////////////////////////////////
     129// This function is a modified version of the mutek_printf().
     130// It uses the kernel TTY0 as a shared terminal, and it takes the
     131// TTY lock to get exclusive access during the format display.
     132// It calls several times the _tty_write system function.
     133// Only a limited number of formats are supported:
     134//   - %d : signed decimal
     135//   - %u : unsigned decimal
     136//   - %x : 32 bits hexadecimal
     137//   - %l : 64 bits hexadecimal
     138//   - %c : char
     139//   - %s : string
     140// In case or error returned by syscall, it makes a giet_exit().
     141//////////////////////////////////////////////////////////////////////////
     142extern void giet_shr_printf( char* format, ... );
     143
     144//////////////////////////////////////////////////////////////////////////
     145// This blocking function fetches a single character from the private
     146// terminal allocated to the calling task in the boot.
     147// It uses the TTY_RX_IRQ interrupt, and the associated kernel buffer.
     148// In case or error returned by syscall, it makes a giet_exit().
     149//////////////////////////////////////////////////////////////////////////
     150extern void giet_tty_getc( char* byte );
     151
     152//////////////////////////////////////////////////////////////////////////
     153// This blocking function fetches a string from the private terminal
     154// allocated to the calling task to a fixed length buffer.
     155// The terminal index must be defined in the task context in the boot.
     156// It uses the TTY_RX_IRQ interrupt, and the associated kernel buffer.
     157// - Up to (bufsize - 1) characters (including the non printable characters)
     158//   are copied into buffer, and the string is completed by a NUL character.
     159// - The <LF> character is interpreted, and the function close the string
     160//   with a NUL character if <LF> is read.
     161// - The <DEL> character is interpreted, and the corresponding character(s)
     162//   are removed from the target buffer.
     163// - It does not provide an echo.
     164// In case or error returned by syscall, it makes a giet_exit().
     165/////////////////////////////////////////////////////////////////////////
     166extern void giet_tty_gets( char* buf, unsigned int bufsize );
     167
     168/////////////////////////////////////////////////////////////////////////
     169// This blocking function fetches a string of decimal characters (most
     170// significant digit first) to build a 32-bit unsigned integer from
     171// the private TTY terminal allocated to the calling task.
     172// The terminal index must be defined in the task context in the boot.
     173// It uses the TTY_RX_IRQ interrupt, and the associated kernel buffer.
     174// - The non-blocking system function _tty_read is called several times,
     175//   and the decimal characters are written in a 32 characters buffer
     176//   until a <LF> character is read.
     177// - It ignores non-decimal characters, and displays an echo
     178//   system function) for each decimal character.
     179// - The <DEL> character is interpreted, and previous characters can be cancelled.
     180// - When the <LF> character is received, the string is converted to an
     181//   unsigned int value. If the number of decimal digit is too large for the 32
     182//   bits range, the zero value is returned.
     183// In case or error returned by syscall, it makes a giet_exit().
     184//////////////////////////////////////////////////////////////////////////
     185extern void giet_tty_getw( unsigned int* val );
     186
     187//////////////////////////////////////////////////////////////////////////
     188//////////////////////////////////////////////////////////////////////////
     189//                TIMER device related system calls
     190//////////////////////////////////////////////////////////////////////////
     191//////////////////////////////////////////////////////////////////////////
     192
     193//////////////////////////////////////////////////////////////////////////
     194// This function activates the private user timer allocated
     195// to the calling task in the boot phase.
     196// In case or error returned by syscall, it makes a giet_exit().
     197//////////////////////////////////////////////////////////////////////////
     198extern void giet_timer_start();
     199
     200//////////////////////////////////////////////////////////////////////////
     201// This function stops the private user timer allocated
     202// to the calling task.
     203// In case or error returned by syscall, it makes a giet_exit().
     204//////////////////////////////////////////////////////////////////////////
     205extern void giet_timer_stop();
    135206 
    136207//////////////////////////////////////////////////////////////////////////
    137 // Frame buffer device related system calls
    138 //////////////////////////////////////////////////////////////////////////
    139 
    140 extern int giet_fb_sync_read( unsigned int offset,
    141                               void*        buffer,
     208//////////////////////////////////////////////////////////////////////////
     209//                Frame buffer device related system calls
     210//////////////////////////////////////////////////////////////////////////
     211//////////////////////////////////////////////////////////////////////////
     212
     213//////////////////////////////////////////////////////////////////////////
     214// This blocking function use a memory copy strategy to transfer data
     215// from the frame buffer device in kernel space to an user buffer.
     216//     offset : offset (in bytes) in the frame buffer
     217//     buffer : base address of the user buffer
     218//     length : number of bytes to be transfered
     219// In case or error returned by syscall, it makes a giet_exit().
     220//////////////////////////////////////////////////////////////////////////
     221extern void giet_fb_sync_read( unsigned int offset,
     222                               void*        buffer,
     223                               unsigned int length );
     224
     225//////////////////////////////////////////////////////////////////////////
     226// This blocking function use a memory copy strategy to transfer data
     227// from a user buffer to the frame buffer device in kernel space.
     228//     offset : offset (in bytes) in the frame buffer
     229//     buffer : base address of the memory buffer
     230//     length : number of bytes to be transfered
     231// In case or error returned by syscall, it makes a giet_exit().
     232//////////////////////////////////////////////////////////////////////////
     233extern void giet_fb_sync_write( unsigned int offset,
     234                                void*        buffer,
     235                                unsigned int length );
     236
     237//////////////////////////////////////////////////////////////////////////
     238// This function initializes the two chbuf SRC an DST used by the CMA
     239// controller and activates the CMA channel allocated to the calling task.
     240// - buf0   : first user buffer virtual address
     241// - buf1   : second user buffer virtual address
     242// - length : buffer size (bytes)
     243// In case or error returned by syscall, it makes a giet_exit().
     244//////////////////////////////////////////////////////////////////////////
     245extern void giet_fb_cma_init( void*        buf0,
     246                              void*        buf1,
    142247                              unsigned int length );
    143248
    144 extern int giet_fb_sync_write(unsigned int offset,
    145                               void*        buffer,
    146                               unsigned int length);
    147 
    148 extern int giet_fb_cma_init(  void*        buf0,
    149                               void*        buf1,
    150                               unsigned int length);
    151 
    152 extern int giet_fb_cma_write(unsigned int buf_id);
    153 
    154 extern int giet_fb_cma_stop();
    155 
    156 //////////////////////////////////////////////////////////////////////////
    157 // Network controller related system calls
    158 //////////////////////////////////////////////////////////////////////////
    159 
    160 extern int giet_nic_cma_start();
    161 
    162 extern int giet_nic_cma_stop();
    163 
    164 //////////////////////////////////////////////////////////////////////////
    165 // FAT related system calls
    166 //////////////////////////////////////////////////////////////////////////
    167 
     249//////////////////////////////////////////////////////////////////////////
     250// This function initializes the two chbuf SRC an DST used by the CMA
     251// controller and activates the CMA channel allocated to the calling task.
     252// - buf0   : first user buffer virtual address
     253// - buf0   : second user buffer virtual address
     254// - length : buffer size (bytes)
     255// In case or error returned by syscall, it makes a giet_exit().
     256//////////////////////////////////////////////////////////////////////////
     257extern void giet_fb_cma_write( unsigned int buf_id );
     258
     259//////////////////////////////////////////////////////////////////////////
     260// This function desactivates the CMA channel allocated to the task.
     261// In case or error returned by syscall, it makes a giet_exit().
     262//////////////////////////////////////////////////////////////////////////
     263extern void giet_fb_cma_stop();
     264
     265//////////////////////////////////////////////////////////////////////////
     266//////////////////////////////////////////////////////////////////////////
     267//                  NIC related system calls
     268//////////////////////////////////////////////////////////////////////////
     269//////////////////////////////////////////////////////////////////////////
     270
     271//////////////////////////////////////////////////////////////////////////
     272// This function initializes the memory chbuf used by the CMA controller,
     273// activates the NIC channel allocated to the calling task,
     274// and activates the two CMA channels.
     275// - tx     : RX channel if 0 / TX channel if non 0
     276// - buf0   : first user buffer virtual address
     277// - buf1   : second user buffer virtual address
     278// - length : buffer size (bytes)
     279// In case or error returned by syscall, it makes a giet_exit().
     280//////////////////////////////////////////////////////////////////////////
     281extern void giet_nic_cma_start();
     282
     283//////////////////////////////////////////////////////////////////////////
     284// This function desactivates the NIC channel and the two CMA channels
     285// allocated to the calling task.
     286// In case or error returned by syscall, it makes a giet_exit().
     287//////////////////////////////////////////////////////////////////////////
     288extern void giet_nic_cma_stop();
     289
     290//////////////////////////////////////////////////////////////////////////
     291//////////////////////////////////////////////////////////////////////////
     292//               FAT related system calls
     293//////////////////////////////////////////////////////////////////////////
     294//////////////////////////////////////////////////////////////////////////
     295
     296//////////////////////////////////////////////////////////////////////////
     297// Open a file identified by a pathname, and contained in the system FAT.
     298// The read/write flags are not supported yet: no effect.
     299// Return -1 in case or error.
     300//////////////////////////////////////////////////////////////////////////
    168301extern int giet_fat_open(  const char*  pathname,
    169302                           unsigned int flags );
    170303
    171 extern int giet_fat_read(  unsigned int fd,
    172                            void*        buffer,
    173                            unsigned int count,
    174                            unsigned int offset );
    175 
    176 extern int giet_fat_write( unsigned int fd,
    177                            void*        buffer,
    178                            unsigned int count,
    179                            unsigned int offset );
    180 
    181 extern int giet_fat_lseek( unsigned int fd,
    182                            unsigned int offset,
    183                            unsigned int whence );
    184 
    185 extern int giet_fat_fstat( unsigned int fd );
    186 
    187 extern int giet_fat_close( unsigned int fd );
    188 
    189 //////////////////////////////////////////////////////////////////////////
    190 // Miscelaneous system calls
    191 //////////////////////////////////////////////////////////////////////////
    192 
    193 extern int giet_vobj_get_vbase( char*         vspace_name,
    194                                 char*         vobj_name,
    195                                 unsigned int  vobj_type,
    196                                 unsigned int* vobj_vaddr);
    197 
    198 extern int giet_procnumber();
    199 
     304///////////////////////////////////////////////////////////////////////////////////
     305// Read "count" sectors from a file identified by "fd", skipping "offset"
     306// sectors in file, and writing into the user "buffer".
     307// The user buffer base address shoulb be 64 bytes aligned.
     308// In case or error returned by syscall, it makes a giet_exit().
     309///////////////////////////////////////////////////////////////////////////////////
     310extern void giet_fat_read(  unsigned int fd,
     311                            void*        buffer,
     312                            unsigned int count,
     313                            unsigned int offset );
     314
     315///////////////////////////////////////////////////////////////////////////////////
     316// Write "count" sectors from a file identified by "fd", skipping "offset"
     317// sectors in file, and reading from the user "buffer".
     318// The user buffer base address shoulb be 64 bytes aligned.
     319// In case or error returned by syscall, it makes a giet_exit().
     320///////////////////////////////////////////////////////////////////////////////////
     321extern void giet_fat_write( unsigned int fd,
     322                            void*        buffer,
     323                            unsigned int count,
     324                            unsigned int offset );
     325
     326///////////////////////////////////////////////////////////////////////////////////
     327// Change the lseek file pointer value for a file identified by "fd".
     328// In case or error returned by syscall, it makes a giet_exit().
     329///////////////////////////////////////////////////////////////////////////////////
     330extern void giet_fat_lseek( unsigned int fd,
     331                            unsigned int offset,
     332                            unsigned int whence );
     333
     334///////////////////////////////////////////////////////////////////////////////////
     335// Returns general informations of a file identified by "fd".
     336// (Only the file_size in sectors for this moment)
     337///////////////////////////////////////////////////////////////////////////////////
     338extern void giet_fat_fstat( unsigned int fd );
     339
     340//////////////////////////////////////////////////////////////////////////
     341// Close a file identified by "fd".
     342//////////////////////////////////////////////////////////////////////////
     343extern void giet_fat_close( unsigned int fd );
     344
     345//////////////////////////////////////////////////////////////////////////
     346//////////////////////////////////////////////////////////////////////////
     347//                    Miscelaneous system calls
     348//////////////////////////////////////////////////////////////////////////
     349//////////////////////////////////////////////////////////////////////////
     350
     351//////////////////////////////////////////////////////////////////////////
     352// This function returns the processor identifier.
     353//////////////////////////////////////////////////////////////////////////
     354extern int giet_procid();
     355
     356//////////////////////////////////////////////////////////////////////////
     357// This function returns the local processor time.
     358//////////////////////////////////////////////////////////////////////////
     359extern int giet_proctime();
     360
     361//////////////////////////////////////////////////////////////////////////
     362// This functions returns the local task id.
     363// If processor has n tasks the local task index is ranging from 0 to n-1
     364//////////////////////////////////////////////////////////////////////////
     365extern int giet_proc_task_id();
     366
     367//////////////////////////////////////////////////////////////////////////
     368// This functions returns the global task id, (unique in the system).
     369//////////////////////////////////////////////////////////////////////////
     370extern int giet_global_task_id();
     371
     372//////////////////////////////////////////////////////////////////////////
     373// This functions returns the thread index of the task in its vspace.
     374//////////////////////////////////////////////////////////////////////////
     375extern int giet_thread_id();
     376
     377//////////////////////////////////////////////////////////////////////////
     378// This function returns a pseudo-random value derived from the processor
     379// cycle count. This value is comprised between 0 & 65535.
     380/////////////////////////////////////////////////////////////////////////
     381extern int giet_rand();
     382
     383//////////////////////////////////////////////////////////////////////////
     384// This function stops execution of the calling task with a TTY message,
     385// the user task is descheduled and becomes not runable.
     386// It does not consume processor cycles anymore.
     387//////////////////////////////////////////////////////////////////////////
    200388extern void giet_exit();
    201389
    202 extern int giet_context_switch();
    203 
    204 extern int giet_proc_task_id();
    205 
    206 extern int giet_heap_info( unsigned int* vaddr,
    207                            unsigned int* size );
    208 
    209 extern int giet_global_task_id();
    210 
    211 extern int giet_thread_id();
    212 
     390//////////////////////////////////////////////////////////////////////////
     391// This function uses the giet_exit() system call
     392// and kill the calling task if the condition is false.
     393//////////////////////////////////////////////////////////////////////////
    213394extern void giet_assert( unsigned int,
    214395                         char* string );
    215396
    216 extern int giet_rand();
     397//////////////////////////////////////////////////////////////////////////
     398// This function writes in argument "vobj_vaddr" the virtual base address
     399// of a vobj (defined in the mapping_info data structure), identified by
     400// the two arguments "vspace_name" and "vobj_name".
     401// In case or error returned by syscall, it makes a giet_exit().
     402// ( vobj not defined or wrong vspace )
     403//////////////////////////////////////////////////////////////////////////
     404extern void giet_vobj_get_vbase( char*         vspace_name,
     405                                 char*         vobj_name,
     406                                 unsigned int* vobj_vaddr);
     407
     408//////////////////////////////////////////////////////////////////////////
     409// This function returns in the "buffer" argument the number of processors
     410// in the cluster specified by the "cluster_xy" argument.
     411// In case or error returned by syscall, it makes a giet_exit().
     412//////////////////////////////////////////////////////////////////////////
     413extern void giet_procnumber( unsigned int cluster_xy,
     414                             unsigned int buffer );
     415
     416//////////////////////////////////////////////////////////////////////////
     417// The user task calling this function is descheduled and
     418// the processor is allocated to another task.
     419//////////////////////////////////////////////////////////////////////////
     420extern void giet_context_switch();
     421
     422//////////////////////////////////////////////////////////////////////////
     423// This function returns the base address and size of the task's heap
     424//////////////////////////////////////////////////////////////////////////
     425extern void giet_heap_info( unsigned int* vaddr,
     426                            unsigned int* size );
     427
    217428
    218429#endif
  • soft/giet_vm/giet_xml/mapping_info.h

    r289 r295  
    3030// - mapping_vspace_t   vspace[] 
    3131// - mapping_vseg_t     vseg[]     
    32 // - mapping_vseg_t     vobj[]   
     32// - mapping_vobj_t     vobj[]   
    3333// - mapping_task_t     task[] 
    3434// - mapping_proc_t     proc[] 
     
    6161#define U_MODE_MASK  0b0001   // user access
    6262
    63 #define IN_MAPPING_SIGNATURE    0xDEADBEEF
     63#define IN_MAPPING_SIGNATURE    0xDACE2014
    6464#define OUT_MAPPING_SIGNATURE   0xBABEF00D
    6565
     
    8585{
    8686    IRQ_TYPE_HWI = 0,        // HARD in map.xml file
    87     IRQ_TYPE_SWI = 1,        // SOFT in map.xml file,
     87    IRQ_TYPE_WTI = 1,        // SOFT in map.xml file,
    8888    IRQ_TYPE_PTI = 2,        // TIME in map.xml file,
    8989};
     
    115115    PERIPH_TYPE_TTY       = 12,
    116116    PERIPH_TYPE_XCU       = 13,
    117 
    118     PERIPH_TYPE_MAX_VALUE = 14,
     117    PERIPH_TYPE_PIC       = 14,
     118
     119    PERIPH_TYPE_MAX_VALUE = 15,
    119120};
    120121
     
    145146    unsigned int globals;            // number of vsegs mapped in all vspaces
    146147    unsigned int vspaces;            // number of virtual spaces
    147     unsigned int increment;          // vseg cluster increment for replicated periphs
     148    unsigned int x_io;               // x coordinate for cluster_io_ext
     149    unsigned int y_io;               // y coordinate for cluster_io_ext
    148150    unsigned int irq_per_proc;       // number of IRQ per processor
    149 
    150     unsigned int cma_cluster;        // index of cluster containing CMA controler
    151     unsigned int cma_cluster_bis;    // index of cluster containing second CMA controler
    152 
    153     unsigned int fbf_cluster;        // index of cluster containing FBF controler
    154     unsigned int fbf_cluster_bis;    // index of cluster containing second FBF controler
    155 
    156     unsigned int iob_cluster;        // index of cluster containing IOB controler
    157     unsigned int iob_cluster_bis;    // index of cluster containing second IOB controler
    158 
    159     unsigned int ioc_cluster;        // index of cluster containing IOC controler
    160     unsigned int ioc_cluster_bis;    // index of cluster containing second IOC controler
    161 
    162     unsigned int nic_cluster;        // index of cluster containing NIC controler
    163     unsigned int nic_cluster_bis;    // index of cluster containing second NIC controler
    164 
    165     unsigned int rom_cluster;        // index of cluster containing ROM controler
    166     unsigned int rom_cluster_bis;    // index of cluster containing second ROM controler
    167 
    168     unsigned int sim_cluster;        // index of cluster containing SIM controler
    169     unsigned int sim_cluster_bis;    // index of cluster containing second SIM controler
    170 
    171     unsigned int tty_cluster;        // index of cluster containing TTY controler
    172     unsigned int tty_cluster_bis;    // index of cluster containing second TTY controler
     151    unsigned int use_ramdisk;        // does not use IOC peripheral if non zero
     152    unsigned int increment;          // vbase address increment (replicated peripherals)
    173153
    174154    unsigned int psegs;              // total number of physical segments (for all clusters)
     
    286266typedef struct __attribute__((packed))  mapping_proc_s
    287267{
    288     unsigned int    irqs;            // number of IRQs allocated to processor
    289     unsigned int    irq_offset;      // index of first IRQ allocated to processor
     268    unsigned int    index;           // processor local index (in cluster)
    290269} mapping_proc_t;
    291 
    292 
    293 /////////////////////////////////////////////////////
    294 typedef struct __attribute__((packed))  mapping_irq_s
    295 {
    296     unsigned int    type;            // HWI / SWI / PTI
    297     unsigned int    icuid;           // IRQ Index for the ICU component
    298     unsigned int    isr;             // ISR Index (defined in irq_handler.h)
    299     unsigned int    channel;         // Channel Index (for multi-channels peripherals)
    300 } mapping_irq_t;
    301270
    302271
     
    323292typedef struct __attribute__((packed))  mapping_periph_s
    324293{
    325     unsigned int    type;         
     294    unsigned int    type;            // legal values defined above
    326295    unsigned int    subtype;         // periph specialization
    327296    unsigned int    psegid;          // pseg index in cluster
    328297    unsigned int    channels;        // number of channels
     298    unsigned int    irqs;            // number of input IRQs (for ICU, XCU or PIC)
     299    unsigned int    irq_offset;      // index of first IRQ (can be HWI/PTI/WTI)
    329300} mapping_periph_t;
     301
     302
     303/////////////////////////////////////////////////////
     304typedef struct __attribute__((packed))  mapping_irq_s
     305{
     306    unsigned int    srctype;         // source IRQ type (HWI / WTI / PTI)
     307    unsigned int    srcid;           // source IRQ index (for ICU/PIC component)
     308    unsigned int    isr;             // ISR type (defined in irq_handler.h)
     309    unsigned int    channel;         // channel index (for multi-channels peripherals)
     310    unsigned int    dstx;            // x coordinate of destination cluster
     311    unsigned int    dsty;            // y coordinate of destination cluster
     312    unsigned int    dstid;           // destination IRQ index (can be PROC or ICU)
     313} mapping_irq_t;
    330314
    331315
  • soft/giet_vm/giet_xml/xml_driver.c

    r289 r295  
    1818
    1919//////////////////////////////////////////////////////
    20 void buildXml(mapping_header_t * header, FILE * fpout) {
     20void buildXml(mapping_header_t * header, FILE * fpout)
     21{
     22    // mnemonics defined in mapping_info.h
    2123    const char * vobj_type[] =
    2224    {
     
    2729        "MWMR",       // MWMR channel
    2830        "LOCK",       // Spin-Lock
    29         "BUFFER",     // Any "no intialiasation needed" objects (stacks...)
     31        "BUFFER",     // Any "no intialiasation needed" object (stacks...)
    3032        "BARRIER",    // Barrier
    3133        "CONST",      // Constant
     
    3436    };
    3537
     38    // mnemonics defined in mapping_info.h
    3639    const char * pseg_type[] =
    3740    {
    3841        "RAM",
    39         "ROM",
     42        "ROM",        // deprecated => use PERI
    4043        "PERI",
    4144    };
    4245
     46    // mnemonics defined in mapping_info.h
    4347    const char * irq_type[] =
    4448    {
    45         "HARD",
    46         "SOFT",
    47         "TIME",
    48     };
    49 
     49        "HWI",                     
     50        "WTI",
     51        "PTI",
     52    };
     53
     54    // mnemonics defined in irq_handler.h
    5055    const char * isr_type[] =
    5156    {
    52         "ISR_DEFAULT",
    53         "ISR_SWITCH",
    54         "ISR_TTY",
    55         "ISR_DMA",
    56         "ISR_IOC",
     57        "ISR_DEFAULT", 
     58        "ISR_TICK",
     59        "ISR_TTY_RX",
     60        "ISR_TTY_TX",
     61        "ISR_BDV",
    5762        "ISR_TIMER",
    58     };
    59 
     63        "ISR_WAKUP",
     64        "ISR_NIC_RX",
     65        "ISR_NIC_TX",
     66        "ISR_CMA",
     67    };
     68
     69    // mnemonics defined in mapping_info.h
    6070    const char * periph_type[] =
    6171    {
     
    7484        "TTY",
    7585        "XCU",
    76     };
    77 
    78     const char * periph_subtype[] =
     86        "PIC",
     87    };
     88
     89    const char * ioc_subtype[] =
    7990    {
    8091        "BDV",
     
    242253    fprintf(fpout, "              x_width      = \"%d\"   \n" , header->x_width);
    243254    fprintf(fpout, "              y_width      = \"%d\"   \n" , header->y_width);
    244     fprintf(fpout, "              vspaces      = \"%d\"   \n" , header->vspaces);
    245     fprintf(fpout, "              increment    = \"%d\"   \n" , header->vspaces);
    246     fprintf(fpout, "              irq_per_proc = \"%d\" >\n\n", header->irq_per_proc);
     255    fprintf(fpout, "              irq_per_proc = \"%d\"   \n" , header->irq_per_proc);
     256    fprintf(fpout, "              use_ramdisk  = \"%d\"   \n" , header->use_ramdisk);
     257    fprintf(fpout, "              x_io         = \"%d\"   \n" , header->x_io);
     258    fprintf(fpout, "              y_io         = \"%d\" >\n\n", header->y_io);
    247259
    248260    ///////////////////// clusters ///////////////////////////////////////////////
     
    271283        for (proc_id = cluster[cluster_id].proc_offset;
    272284             proc_id < cluster[cluster_id].proc_offset + cluster[cluster_id].procs;
    273              proc_id++)
    274         {
    275             fprintf(fpout, "            <proc index = \"%d\" >\n", proc_index);
    276             for (irq_id = proc[proc_id].irq_offset;
    277                  irq_id < proc[proc_id].irq_offset + proc[proc_id].irqs;
    278                  irq_id++)
    279             {
    280                 fprintf(fpout, "                <irq type = \"%s\" ", irq_type[irq[irq_id].type]);
    281                 fprintf(fpout, " icuid = \"0x%x\" ", irq[irq_id].icuid);
    282                 fprintf(fpout, " isr = \"%s\" ", isr_type[irq[irq_id].isr]);
    283                 fprintf(fpout, " channel = \"0x%x\" />\n", irq[irq_id].channel);
    284             }
    285             fprintf(fpout, "            </proc>\n" );
    286         }
    287 
     285             proc_id++, proc_index++)
     286        {
     287            fprintf(fpout, "            <proc index = \"%d\" />\n", proc_index);
     288        }
    288289
    289290        ///////////////////// coprocessors ///////////////////////////////////////////
     
    316317
    317318            if (periph[periph_id].subtype < PERIPH_SUBTYPE_MAX_VALUE)
    318                 fprintf(fpout, " subtype = \"%s\" ", periph_subtype[periph[periph_id].subtype]);
     319                fprintf(fpout, " subtype = \"%s\" ", ioc_subtype[periph[periph_id].subtype]);
    319320
    320321            fprintf(fpout, " psegname = \"%s\" ", pseg[periph[periph_id].psegid].name);
    321             fprintf(fpout, " channels = \"%d\" />\n",  periph[periph_id].channels);
     322            fprintf(fpout, " channels = \"%d\" >\n",  periph[periph_id].channels);
     323            for (irq_id = periph[periph_id].irq_offset;
     324                 irq_id < periph[periph_id].irq_offset + periph[periph_id].irqs;
     325                 irq_id++)
     326            {
     327                fprintf(fpout, "                <irq srctype = \"%s\" ", irq_type[irq[irq_id].srctype]);
     328                fprintf(fpout, " srcid = \"%d\" ", irq[irq_id].srcid);
     329                fprintf(fpout, " isr = \"%s\" ", isr_type[irq[irq_id].isr]);
     330                fprintf(fpout, " channel = \"%d\" ", irq[irq_id].channel);
     331                fprintf(fpout, " dstx = \"%d\" ", irq[irq_id].dstx);
     332                fprintf(fpout, " dsty = \"%d\" ", irq[irq_id].dsty);
     333                fprintf(fpout, " dstid = \"%d\" />\n", irq[irq_id].dstid);
     334            }
     335            fprintf(fpout, "            </periph>\n");
    322336        }
    323337        fprintf(fpout, "        </cluster>\n" );
  • soft/giet_vm/giet_xml/xml_parser.c

    r289 r295  
    104104char found_mmc   = 0;
    105105
    106 
    107 ////////////////////////////////////////////////////////////////////
    108 // These variables are used to generate the hard_config.h file
    109 ////////////////////////////////////////////////////////////////////
    110 
    111 unsigned int nb_proc_max      = 0; // max number of processors per cluster
     106////////////////////////////////////////////////////////////////////////
     107// These variables are used to generate the hard_config.h file.
     108////////////////////////////////////////////////////////////////////////
     109
     110unsigned int nb_procs_max     = 0; // max number of processors per cluster
    112111unsigned int nb_tasks_max     = 0; // max number of tasks (in all vspaces)
    113112
    114 unsigned int tim_channels     = 0; // max number of user timers (per cluster)
    115 unsigned int dma_channels     = 0; // max number of DMA channels (per cluster)
    116 
    117 unsigned int icu_channels     = 0; // total number of channels  in ICU/XICU
    118 unsigned int tty_channels     = 0; // total number of terminals in TTY
    119 unsigned int hba_channels     = 0; // total number of channels  in HBA
    120 unsigned int nic_channels     = 0; // total number of channels  in NIC
    121 unsigned int cma_channels     = 0; // total number of channels  in CMA
     113unsigned int tim_channels     = 0; // number of user timers (per cluster)
     114unsigned int dma_channels     = 0; // number of DMA channels (per cluster)
     115
     116unsigned int tty_channels     = 0; // number of TTY channels
     117unsigned int ioc_channels     = 0; // number of HBA channels
     118unsigned int nic_channels     = 0; // number of NIC channels
     119unsigned int cma_channels     = 0; // number of CMA channels
     120unsigned int pic_channels     = 0; // number of PIC channels
    122121
    123122unsigned int use_iob          = 0; // using IOB component
     123unsigned int use_pic          = 0; // using PIC component
    124124unsigned int use_xcu          = 0; // using XCU (not ICU)
    125125
    126126// These variables define the IOC peripheral subtype
    127 unsigned int use_hba          = 0; // using HBA
    128 unsigned int use_bdv          = 0; // using SoCLIB block device
    129 unsigned int use_spi          = 0; // using SD Card-SPI
     127
     128unsigned int use_hba          = 0; // using SoClib AHCI controller
     129unsigned int use_bdv          = 0; // using SoCLIB block device controller
     130unsigned int use_spi          = 0; // using SDCard-SPI
    130131
    131132////////////////////////////////////////////////////////////////
     
    283284
    284285///////////////////////////////////////////////////////////////////////////////////
    285 // This function set the vbase address for all peripheral types.
    286 // For replicated peripherals with the same type the virtual base address must be:
    287 //   vbase = seg_type_base & 0XFF000000 +
    288 //          (cluster_id * vbase_cluster_increment) & 0x00FF0000
     286// This function set the vbase addresses for all peripheral types, in order
     287// to generate the ldscript file, that contains one single virtual address
     288// for peripherals replicated in all clusters, and one virtual addresses for
     289// each non replicated peripheral type.
     290//
     291// It makes the following checks on the virtual addresses:
     292//
     293// - For replicated peripherals the virtual base address must be:
     294//   vbase = seg_type_base & 0XFF000000 + (cluster_xy * increment) & 0x00FF0000
     295//
     296// - For non-replicated peripherals, the cluster index must be cluster_io.
    289297///////////////////////////////////////////////////////////////////////////////////
    290298void set_periph_vbase_array()
     
    300308    unsigned int cluster_mask = 0x00FF0000;
    301309
    302     // We are analysing all vsegs corresponding to a peripheral
     310#if XML_PARSER_DEBUG
     311printf("\n set peripherals vbase array\n");
     312#endif
    303313
    304314    // scan all vsegs
     
    308318        if ( vobj[vseg[vseg_id]->vobj_offset]->type == VOBJ_TYPE_PERI )
    309319        {
    310             pseg_id    = vseg[vseg_id]->psegid;
     320            pseg_id = vseg[vseg_id]->psegid;
     321
     322#if XML_PARSER_DEBUG
     323printf(" - found vseg %s with psegid = %d", vseg[vseg_id]->name, pseg_id );
     324#endif
    311325
    312326            // scan all periphs to retrieve peripheral type (same psegid)
     
    315329                if( periph[periph_id]->psegid == pseg_id ) // matching !!!
    316330                {
    317                     type = periph[periph_id]->type;
    318                     if ( periph_vbase_array[type] == 0xFFFFFFFF )  // vbase not set
     331                    cluster_id = pseg[pseg_id]->clusterid;
     332                    type       = periph[periph_id]->type;
     333
     334#if XML_PARSER_DEBUG
     335printf(" / matching periph type %d\n", type );
     336#endif
     337
     338                    if ( (type == PERIPH_TYPE_DMA) ||
     339                         (type == PERIPH_TYPE_MMC) ||
     340                         (type == PERIPH_TYPE_ICU) ||
     341                         (type == PERIPH_TYPE_XCU) ||
     342                         (type == PERIPH_TYPE_TIM) )   // replicated peripheral
    319343                    {
    320                         periph_vbase_array[type] = vseg[vseg_id]->vbase & type_mask;   
    321                     }
    322                     else                                 // vbase already set
    323                     {
    324                         // checking mask bits
    325                         if( (vseg[vseg_id]->vbase & type_mask) !=
    326                             (periph_vbase_array[type]) )
     344                        cluster_xy = (cluster[cluster_id]->x << header->y_width) +
     345                                      cluster[cluster_id]->y;
     346
     347                        if( (vseg[vseg_id]->vbase & cluster_mask) !=
     348                            (header->increment * cluster_xy) )
    327349                        {
    328                             printf("[XML ERROR] All peripherals with same type ");
    329                             printf(" should share the same 8 MSB bits in base address\n");
     350                            printf("[XML ERROR] All replicated peripherals "
     351                                   "must have cluster bits = cluster_xy * increment\n");
     352                            printf("periph index = %d / periph type = %d / vbase = %x\n",
     353                                    periph_id, type, vseg[vseg_id]->vbase);
     354                            exit(1);
     355                        }
     356                        else if ( periph_vbase_array[type] == 0xFFFFFFFF ) // vbase not set
     357                        {
     358                            periph_vbase_array[type] = vseg[vseg_id]->vbase & type_mask;   
     359                        }
     360                        else if ((vseg[vseg_id]->vbase & type_mask) != (periph_vbase_array[type]))
     361                        {
     362                            printf("[XML ERROR] All peripherals with same type"
     363                                   " should share the same 8 MSB bits in vbase address\n");
    330364                            printf("periph index = %d / periph type = %d / vbase = %x\n",
    331365                                    periph_id, type, vseg[vseg_id]->vbase);
     
    333367                        }
    334368                    }
    335    
    336                     // checking cluster bits for all replicated peripherals
    337                     if ( (type == PERIPH_TYPE_DMA) ||
    338                          (type == PERIPH_TYPE_MMC) ||
    339                          (type == PERIPH_TYPE_ICU) ||
    340                          (type == PERIPH_TYPE_XCU) ||
    341                          (type == PERIPH_TYPE_TIM) )
     369                    else                               // non replicated peripheral
    342370                    {
    343                         cluster_id = pseg[pseg_id]->clusterid;
    344                         cluster_xy = (cluster[cluster_id]->x << header->y_width) +
    345                                       cluster[cluster_id]->y;
    346 
    347                         if( (vseg[vseg_id]->vbase & cluster_mask) !=
    348                             (header->increment * cluster_xy) )
     371                        if ( (cluster[cluster_id]->x == header->x_io) && 
     372                             (cluster[cluster_id]->y == header->y_io) )   
    349373                        {
    350                             printf("[XML ERROR] All replicated peripherals ");
    351                             printf("must have cluster bits = cluster_id * increment");
    352                             printf("periph index = %d / periph type = %d / vbase = %x\n",
    353                                     periph_id, type, vseg[vseg_id]->vbase);
     374                            periph_vbase_array[type] = vseg[vseg_id]->vbase;   
     375                        }
     376                        else
     377                        {
     378                            printf("[XML ERROR] Non replicated peripherals must be in cluster_io\n");
     379                            printf(" periph index = %d / periph type = %d / vbase = %x"
     380                                   " / pseg index = %d / cluster index = %d\n",
     381                                    periph_id, type, vseg[vseg_id]->vbase, pseg_id, cluster_id);
    354382                            exit(1);
    355383                        }
    356                     } 
     384                    }
    357385                }
    358386            }
     
    428456}
    429457
     458///////////////////////////////////////////////////////////
     459unsigned int alignTo( unsigned int value, unsigned int pow2 )
     460{
     461    unsigned int mask = (1 << pow2) - 1;
     462    return ( (value + mask) & ~mask);
     463}
     464
     465////////////////////
     466void setVsegLength()
     467{
     468    // for a given vseg identified vseg_index
     469    // scan all contained vobjs to compute the vseg lenth
     470
     471    unsigned int vobj_id;
     472    unsigned int cur_length = 0;
     473
     474    unsigned int first = vseg[vseg_index]->vobj_offset;
     475    unsigned int last  = first + vseg[vseg_index]->vobjs;
     476
     477    for ( vobj_id = first ; vobj_id < last ; vobj_id++ )
     478    {
     479        if (vobj[vobj_id]->align)
     480        {
     481            cur_length = alignTo( cur_length, vobj[vobj_id]->align );
     482        }
     483        cur_length += vobj[vobj_id]->length;
     484    }
     485    vseg[vseg_index]->length = alignTo( cur_length, 12 );
     486}
     487
     488///////////////////////
     489void checkVsegOverlap()
     490{
     491    // for a given vseg identified by vseg_index,
     492    // check overlap with all vsegs in same vspace,
     493    // and check overlap with all global vsegs.
     494
     495    unsigned int vseg_id;
     496    unsigned int prev_vbase;                          // previous vseg vbase
     497    unsigned int prev_length;                         // previous vseg length
     498
     499    unsigned int vbase  = vseg[vseg_index]->vbase;    // new vseg vbase
     500    unsigned int length = vseg[vseg_index]->length;   // new vseg length
     501 
     502    // checking overlap with other vsegs in same vspace
     503    if ( header->vspaces > 0 )
     504    {
     505        unsigned int first = vspace[vspace_index]->vseg_offset;   
     506        unsigned int last  = vseg_index;
     507   
     508        for( vseg_id = first ; vseg_id < last ; vseg_id++ )
     509        {
     510            prev_vbase  = vseg[vseg_id]->vbase;
     511            prev_length = vseg[vseg_id]->length;
     512            if ( ((vbase + length) > prev_vbase) && ((prev_vbase + prev_length) > vbase) )
     513            {
     514                printf("[XML ERROR] vseg %s in vspace %s overlaps other vseg %s\n",
     515                vseg[vseg_index]->name, vspace[vspace_index]->name, vseg[vseg_id]->name );
     516                exit(1);
     517            }
     518        }
     519    }
     520
     521    // checking overlap with existing global vsegs
     522    for ( vseg_id = 0 ; vseg_id < header->globals ; vseg_id++ )
     523    {
     524        prev_vbase  = vseg[vseg_id]->vbase;
     525        prev_length = vseg[vseg_id]->length;
     526        if ( ((vbase + length) > prev_vbase) && ((prev_vbase + prev_length) > vbase) )
     527        {
     528            printf("[XML ERROR] vseg %s in vspace %s overlaps global vseg %s\n",
     529            vseg[vseg_index]->name, vspace[vspace_index]->name, vseg[vseg_id]->name );
     530            exit(1);
     531        }
     532    }
     533}
     534
    430535//////////////////////////////////////
    431536void taskNode(xmlTextReaderPtr reader)
     
    466571    }
    467572
    468     ///////// get x coordinate
     573    ///////// get trdid attribute (optional)
    469574    task[task_index]->trdid = getIntValue(reader, "trdid", &ok);
    470575#if XML_PARSER_DEBUG
    471 printf("      x         = %d\n", x);
     576printf("      trdid     = %d\n", x);
    472577#endif
    473578    if ( !ok )
    474579    {
    475580        task[task_index]->trdid = task_loc_index;
    476         printf("[XML WARNING] missing trdid (thread index) attribute "
    477                "for task in vspace %d. Using value %d\n"
    478                , vspace_index, task_loc_index);
    479581    } 
    480582
     
    720822    ////////// get length attribute
    721823    value = getIntValue(reader, "length", &ok);
    722     if (ok) {
    723 #if XML_PARSER_DEBUG
    724 printf("        length = %d\n", value);
     824    if (ok)
     825    {
     826#if XML_PARSER_DEBUG
     827printf("        length = %x\n", value);
    725828#endif
    726829        vobj[vobj_index]->length = value;
     
    734837    ////////// get align attribute (optional : 0 if missing)
    735838    value = getIntValue(reader, "align", &ok);
    736     if (ok) {
     839    if (ok)
     840    {
    737841#if XML_PARSER_DEBUG
    738842printf("        align = %d\n", value);
     
    740844        vobj[vobj_index]->align = value;
    741845    } 
    742     else {
     846    else
     847    {
    743848        vobj[vobj_index]->align = 0;
    744849    }
     
    746851    ////////// get binpath attribute (optional : '\0' if missing)
    747852    str = getStringValue(reader, "binpath", &ok);
    748     if (ok) {
     853    if (ok)
     854    {
    749855#if XML_PARSER_DEBUG
    750856printf("        binpath = %s\n", str);
     
    9581064        {
    9591065            vseg[vseg_index]->vobjs = vobj_count;
     1066            setVsegLength();
     1067            checkVsegOverlap();
    9601068            vseg_index++;
    9611069            vseg_loc_index++;
     
    9841092    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
    9851093
    986     // checking source file consistency
    987     if (vspace_index >= header->vspaces) {
    988         printf("[XML ERROR] The vspace index is too large : %d\n",
    989                 vspace_index);
    990         exit(1);
    991     }
    992 
    9931094#if XML_PARSER_DEBUG
    9941095printf("\n  vspace %d\n", vspace_index);
     
    9961097
    9971098    vspace[vspace_index] = (mapping_vspace_t *) malloc(sizeof(mapping_vspace_t));
     1099    header->vspaces      = header->vspaces + 1;
    9981100
    9991101    ////////// get name attribute
     
    10361138
    10371139    int status = xmlTextReaderRead(reader);
    1038     while (status == 1) {
     1140    while (status == 1)
     1141    {
    10391142        const char * tag = (const char *) xmlTextReaderConstName(reader);
    10401143
     
    10501153        else if (strcmp(tag, "#text")    == 0) { }
    10511154        else if (strcmp(tag, "#comment") == 0) { }
    1052         else if (strcmp(tag, "vspace")   == 0) {
     1155        else if (strcmp(tag, "vspace")   == 0)
     1156        {
    10531157            vspace[vspace_index]->vobjs = vobj_loc_index;
    10541158            vspace[vspace_index]->tasks = task_loc_index ;
     
    10991203} // end vspaceNode()
    11001204
     1205/////////////////////////////////////
     1206void irqNode(xmlTextReaderPtr reader)
     1207{
     1208    unsigned int ok;
     1209    unsigned int value;
     1210    char * str;
     1211
     1212    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
     1213
     1214    if (irq_index >= MAX_IRQS)
     1215    {
     1216        printf("[XML ERROR] The number of irqs is larger than %d\n", MAX_IRQS);
     1217    }
     1218
     1219#if XML_PARSER_DEBUG
     1220printf("      irq %d\n", irq_loc_index);
     1221#endif
     1222
     1223    irq[irq_index] = (mapping_irq_t *) malloc(sizeof(mapping_irq_t));
     1224
     1225    ///////// get srctype attribute
     1226    str = getStringValue(reader, "srctype", &ok);
     1227    if (ok)
     1228    {
     1229#if XML_PARSER_DEBUG
     1230printf("        srctype = %s\n", str);
     1231#endif
     1232        if      ( strcmp(str, "HWI") == 0 ) irq[irq_index]->srctype = IRQ_TYPE_HWI;
     1233        else if ( strcmp(str, "WTI") == 0 ) irq[irq_index]->srctype = IRQ_TYPE_WTI;
     1234        else if ( strcmp(str, "PTI") == 0 ) irq[irq_index]->srctype = IRQ_TYPE_PTI;
     1235        else   
     1236        {
     1237            printf("[XML ERROR] illegal IRQ <srctype> for periph %d in cluster %d\n",
     1238                    cluster_index, periph_loc_index);
     1239            exit(1);
     1240        }
     1241    }
     1242    else
     1243    {
     1244        printf("[XML ERROR] missing IRQ <srctype> for periph %d in cluster %d\n",
     1245                cluster_index, periph_loc_index);
     1246        exit(1);
     1247    }
     1248
     1249    ///////// get srcid attribute
     1250    value = getIntValue(reader, "srcid", &ok);
     1251    if (ok)
     1252    {
     1253#if XML_PARSER_DEBUG
     1254printf("        srcid   = %d\n", value);
     1255#endif
     1256        irq[irq_index]->srcid = value;
     1257        if (value >= 32)
     1258        {
     1259            printf("[XML ERROR] IRQ <srcid> too large for periph %d in cluster %d\n",
     1260                    cluster_index, periph_loc_index);
     1261            exit(1);
     1262        }
     1263    }
     1264    else
     1265    {
     1266        printf("[XML ERROR] missing IRQ <icuid> for periph %d in cluster %d\n",
     1267                cluster_index, periph_loc_index);
     1268        exit(1);
     1269    }
     1270
     1271    ///////// get isr attribute
     1272    str = getStringValue(reader, "isr", &ok);
     1273    if (ok)
     1274    {
     1275#if XML_PARSER_DEBUG
     1276printf("        isr     = %s\n", str);
     1277#endif
     1278        if      (strcmp(str, "ISR_TICK"   ) == 0)  irq[irq_index]->isr = ISR_TICK;
     1279        else if (strcmp(str, "ISR_BDV"    ) == 0)  irq[irq_index]->isr = ISR_BDV;
     1280        else if (strcmp(str, "ISR_CMA"    ) == 0)  irq[irq_index]->isr = ISR_CMA;
     1281        else if (strcmp(str, "ISR_TTY_RX" ) == 0)  irq[irq_index]->isr = ISR_TTY_RX;
     1282        else if (strcmp(str, "ISR_TTY_TX" ) == 0)  irq[irq_index]->isr = ISR_TTY_TX;
     1283        else if (strcmp(str, "ISR_TIMER"  ) == 0)  irq[irq_index]->isr = ISR_TIMER;
     1284        else if (strcmp(str, "ISR_WAKUP"  ) == 0)  irq[irq_index]->isr = ISR_WAKUP;
     1285        else if (strcmp(str, "ISR_NIC_RX" ) == 0)  irq[irq_index]->isr = ISR_NIC_RX;
     1286        else if (strcmp(str, "ISR_NIC_TX" ) == 0)  irq[irq_index]->isr = ISR_NIC_TX;
     1287        else if (strcmp(str, "ISR_DEFAULT") == 0)  irq[irq_index]->isr = ISR_DEFAULT;
     1288        else
     1289        {
     1290            printf("[XML ERROR] illegal IRQ <isr> for periph %d in cluster %d\n",
     1291                    cluster_index, periph_loc_index);
     1292            exit(1);
     1293        }
     1294    } 
     1295    else
     1296    {
     1297        printf("[XML ERROR] missing IRQ <isr> for periph %d in cluster %d\n",
     1298                cluster_index, periph_loc_index);
     1299        exit(1);
     1300    }
     1301
     1302    ///////// get channel attribute (optionnal : 0 if missing)
     1303    value = getIntValue(reader, "channel", &ok);
     1304    if (ok)
     1305    {
     1306#if XML_PARSER_DEBUG
     1307printf("        channel = %d\n", value);
     1308#endif
     1309        irq[irq_index]->channel = value;
     1310    }
     1311    else
     1312    {
     1313        irq[irq_index]->channel = 0;
     1314    }
     1315
     1316    ///////// get dstx attribute
     1317    value = getIntValue(reader, "dstx", &ok);
     1318    if (ok)
     1319    {
     1320#if XML_PARSER_DEBUG
     1321printf("        dstx    = %d\n", value);
     1322#endif
     1323
     1324        if ( value < header->x_size )
     1325        {
     1326            irq[irq_index]->dstx = value;
     1327        }
     1328        else
     1329        {
     1330            printf("[XML ERROR] IRQ <dstx> too large for periph %d in cluster %d\n",
     1331                    cluster_index, periph_loc_index);
     1332            exit(1);
     1333        }
     1334    }
     1335    else
     1336    {
     1337        printf("[XML ERROR] missing IRQ <dstx> for periph %d in cluster %d\n",
     1338                cluster_index, periph_loc_index);
     1339        exit(1);
     1340    }
     1341
     1342    ///////// get dsty attribute
     1343    value = getIntValue(reader, "dsty", &ok);
     1344    if (ok)
     1345    {
     1346#if XML_PARSER_DEBUG
     1347printf("        dsty    = %d\n", value);
     1348#endif
     1349
     1350        if ( value < header->y_size )
     1351        {
     1352            irq[irq_index]->dsty = value;
     1353        }
     1354        else
     1355        {
     1356            printf("[XML ERROR] IRQ <dsty> too large for periph %d in cluster %d\n",
     1357                    cluster_index, periph_loc_index);
     1358            exit(1);
     1359        }
     1360    }
     1361    else
     1362    {
     1363        printf("[XML ERROR] missing IRQ <dsty> for periph %d in cluster %d\n",
     1364                cluster_index, periph_loc_index);
     1365        exit(1);
     1366    }
     1367
     1368    ///////// get dstid attribute
     1369    value = getIntValue(reader, "dstid", &ok);
     1370    if (ok)
     1371    {
     1372#if XML_PARSER_DEBUG
     1373printf("        dstid   = %d\n", value);
     1374#endif
     1375        irq[irq_index]->dstid = value;
     1376        if (value >= 32)
     1377        {
     1378            printf("[XML ERROR] IRQ <dstid> too large for periph %d in cluster %d\n",
     1379                    cluster_index, periph_loc_index);
     1380            exit(1);
     1381        }
     1382    }
     1383    else
     1384    {
     1385        printf("[XML ERROR] missing IRQ <dstid> for periph %d in cluster %d\n",
     1386                cluster_index, periph_loc_index);
     1387        exit(1);
     1388    }
     1389
     1390    irq_index++;
     1391    irq_loc_index++;
     1392
     1393} // end irqNode
     1394
     1395
     1396
    11011397////////////////////////////////////////
    11021398void cpPortNode(xmlTextReaderPtr reader)
     
    11151411
    11161412#if XML_PARSER_DEBUG
    1117     printf("\n  port %d\n", cp_port_index);
     1413printf("\n  port %d\n", cp_port_index);
    11181414#endif
    11191415
     
    11261422    {
    11271423#if XML_PARSER_DEBUG
    1128         printf("      direction = %s\n", str);
     1424printf("      direction = %s\n", str);
    11291425#endif
    11301426        if (strcmp(str, "TO_COPROC")   ==  0)
     
    11531449    str = getStringValue(reader, "vspacename", &ok);
    11541450#if XML_PARSER_DEBUG
    1155     printf("      vspacename = %s\n", str);
     1451printf("      vspacename = %s\n", str);
    11561452#endif
    11571453    if (ok)
     
    11691465    str = getStringValue(reader, "vobjname", &ok);
    11701466#if XML_PARSER_DEBUG
    1171     printf("      vobjname = %s\n", str);
     1467printf("      vobjname = %s\n", str);
    11721468#endif
    11731469    if (ok)
     
    11921488    unsigned int ok;
    11931489
     1490    irq_loc_index = 0;
     1491
    11941492    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
    11951493
     
    12011499
    12021500#if XML_PARSER_DEBUG
    1203     printf("\n  periph %d\n", periph_index);
     1501printf("\n    periph %d\n", periph_index);
    12041502#endif
    12051503
     
    12111509    {
    12121510#if XML_PARSER_DEBUG
    1213         printf("      channels = %d\n", value);
     1511printf("      channels    = %d\n", value);
    12141512#endif
    12151513        periph[periph_index]->channels = value;
     
    12341532    {
    12351533#if XML_PARSER_DEBUG
    1236         printf("      clusterid = %d\n", cluster_index);
    1237         printf("      psegname  = %s\n", str);
    1238         printf("      psegid    = %d\n", index);
     1534printf("      clusterid  = %d\n", cluster_index);
     1535printf("      psegname    = %s\n", str);
     1536printf("      psegid      = %d\n", index);
    12391537#endif
    12401538        periph[periph_index]->psegid = index;
     
    12521550    {
    12531551#if XML_PARSER_DEBUG
    1254         printf("      type      = %s\n", str);
     1552printf("      type        = %s\n", str);
    12551553#endif
    12561554        unsigned int error = 0;
     
    12601558
    12611559        // The CMA, FBF, HBA, IOB, IOC, NIC, ROM, SIM, TTY, peripherals are not
    1262         // replicated in all clusters but can be replicated in two clusters (fault tolerance)
    1263         // In case of replication, the two copies must have same number of channels.
     1560        // replicated in all clusters but can be instanciated twice.
    12641561
    12651562        ////////////////////////////
     
    12671564        {
    12681565            periph[periph_index]->type = PERIPH_TYPE_CMA;
    1269             if (header->cma_cluster == 0xFFFFFFFF) 
     1566            if ( cma_channels < periph[periph_index]->channels )
    12701567            {
    1271                 header->cma_cluster = cluster_index;
    12721568                cma_channels = periph[periph_index]->channels;
    12731569            }
    1274             else if (header->cma_cluster_bis == 0xFFFFFFFF)
    1275             {
    1276                 header->cma_cluster_bis = cluster_index;
    1277                 assert( (cma_channels == periph[periph_index]->channels) &&
    1278                 "[XML ERROR] unconsistent non replicated peripheral");
    1279             }
    1280             else 
    1281             {
    1282                 error = 1;
    1283             }
    12841570        }
    12851571        /////////////////////////////////
     
    12871573        {
    12881574            periph[periph_index]->type = PERIPH_TYPE_FBF;
    1289             if (header->fbf_cluster == 0xFFFFFFFF) 
    1290             {
    1291                 header->fbf_cluster = cluster_index;
    1292             }
    1293             else if (header->fbf_cluster_bis == 0xFFFFFFFF)
    1294             {
    1295                 header->fbf_cluster_bis = cluster_index;
    1296             }
    1297             else 
    1298             {
    1299                 error = 1;
    1300             }
    13011575        }
    13021576        /////////////////////////////////
     
    13051579            periph[periph_index]->type = PERIPH_TYPE_IOB;
    13061580            use_iob = 1;
    1307             if (header->iob_cluster == 0xFFFFFFFF) 
    1308             {
    1309                 header->iob_cluster = cluster_index;
    1310             }
    1311             else if (header->iob_cluster_bis == 0xFFFFFFFF)
    1312             {
    1313                 header->iob_cluster_bis = cluster_index;
    1314             }
    1315             else 
    1316             {
    1317                 error = 1;
    1318             }
    13191581        }
    13201582        /////////////////////////////////
    13211583        else if (strcmp(str, "IOC") == 0)
    13221584        {
    1323             periph[periph_index]->type = PERIPH_TYPE_IOC;
    1324             if (header->ioc_cluster == 0xFFFFFFFF)
    1325             {
    1326                 header->ioc_cluster  = cluster_index;
    1327             }
    1328             else if (header->ioc_cluster_bis == 0xFFFFFFFF)
    1329             {
    1330                 header->ioc_cluster_bis = cluster_index;
    1331             }
    1332             else
    1333             {
    1334                 printf("[XML ERROR] At most two copies for non replicated "
    1335                         "peripheral\n");
    1336                 exit(1);
    1337             }
    1338 
    1339             str = getStringValue(reader, "subtype", &ok);
    1340    
     1585            char* subtype = getStringValue(reader, "subtype", &ok);
    13411586            if (!ok)
    13421587            {
    1343                 printf("[XML ERROR] IOC peripheral needs a subtype parameter: "
    1344                        "BDV, HBA or SPI\n");
     1588                printf("[XML ERROR] IOC peripheral needs a subtype: BDV, HBA or SPI\n");
    13451589                exit(1);
    13461590            }
    13471591
    1348             if (strcmp(str, "BDV") == 0)
    1349             {
     1592            if ( strcmp(subtype, "BDV") == 0 )
     1593            {
     1594                periph[periph_index]->type    = PERIPH_TYPE_IOC;
    13501595                periph[periph_index]->subtype = PERIPH_SUBTYPE_BDV;
    1351                 use_bdv = 1;
     1596                ioc_channels = 1;
     1597                if ( header->use_ramdisk == 0 ) use_bdv = 1;
    13521598            }
    1353             else if (strcmp(str, "HBA") == 0)
     1599            else if ( strcmp(subtype, "HBA") == 0 )
    13541600            {
     1601                periph[periph_index]->type    = PERIPH_TYPE_IOC;
    13551602                periph[periph_index]->subtype = PERIPH_SUBTYPE_HBA;
    1356 
    1357                 if (use_hba == 0)
    1358                 {
    1359                     use_hba      = 1;
    1360                     hba_channels = periph[periph_index]->channels;
    1361                 }
    1362                 else
    1363                 {
    1364                     assert( (hba_channels == periph[periph_index]->channels) &&
    1365                     "[XML ERROR] unconsistent non replicated peripheral");
    1366                 }
     1603                ioc_channels = periph[periph_index]->channels;
     1604                if ( header->use_ramdisk == 0 ) use_hba = 1;
    13671605            }
    1368             else if (strcmp(str, "SPI") == 0)
     1606            else if ( strcmp(subtype, "SPI") == 0 )
    13691607            {
     1608                periph[periph_index]->type    = PERIPH_TYPE_IOC;
    13701609                periph[periph_index]->subtype = PERIPH_SUBTYPE_SPI;
    1371                 use_spi = 1;
     1610                ioc_channels = periph[periph_index]->channels;
     1611                if ( header->use_ramdisk == 0 ) use_spi = 1;
    13721612            }
    13731613            else
     
    13811621        {
    13821622            periph[periph_index]->type = PERIPH_TYPE_NIC;
    1383             if (header->nic_cluster == 0xFFFFFFFF) 
     1623            if ( nic_channels < periph[periph_index]->channels )
    13841624            {
    1385                 header->nic_cluster = cluster_index;
    13861625                nic_channels = periph[periph_index]->channels;
    13871626            }
    1388             else if (header->nic_cluster_bis == 0xFFFFFFFF)
    1389             {
    1390                 header->nic_cluster_bis = cluster_index;
    1391                 assert( (nic_channels == periph[periph_index]->channels) &&
    1392                 "[XML ERROR] unconsistent non replicated peripheral");
    1393             }
    1394             else 
    1395             {
    1396                 error = 1;
    1397             }
    13981627        }
    13991628        /////////////////////////////////
     
    14011630        {
    14021631            periph[periph_index]->type = PERIPH_TYPE_ROM;
    1403             if (header->rom_cluster == 0xFFFFFFFF)
    1404             {
    1405                 header->rom_cluster  = cluster_index;
    1406             }
    1407             else if (header->rom_cluster_bis == 0xFFFFFFFF)
    1408             {
    1409                 header->rom_cluster_bis = cluster_index;
    1410             }
    1411             else
    1412             {
    1413                 error = 1;
    1414             }
    14151632        }
    14161633        /////////////////////////////////
     
    14181635        {
    14191636            periph[periph_index]->type = PERIPH_TYPE_SIM;
    1420             if (header->sim_cluster == 0xFFFFFFFF)
    1421             {
    1422                 header->sim_cluster  = cluster_index;
    1423             }
    1424             else if (header->sim_cluster_bis == 0xFFFFFFFF)
    1425             {
    1426                 header->sim_cluster_bis = cluster_index;
    1427             }
    1428             else
    1429             {
    1430                 error = 1;
    1431             }
    14321637        }
    14331638        /////////////////////////////////
     
    14351640        {
    14361641            periph[periph_index]->type = PERIPH_TYPE_TTY;
    1437             if (header->tty_cluster == 0xFFFFFFFF)
     1642            if ( tty_channels < periph[periph_index]->channels )
    14381643            {
    1439                 header->tty_cluster = cluster_index;
    14401644                tty_channels = periph[periph_index]->channels;
    14411645            }
    1442             else if (header->tty_cluster_bis == 0xFFFFFFFF)
     1646        }
     1647        /////////////////////////////////
     1648        else if (strcmp(str, "PIC") == 0)
     1649        {
     1650            periph[periph_index]->type = PERIPH_TYPE_PIC;
     1651            if ( pic_channels < periph[periph_index]->channels )
    14431652            {
    1444                 header->tty_cluster_bis = cluster_index;
    1445                 assert( (tty_channels == periph[periph_index]->channels) &&
    1446                 "[XML ERROR] unconsistent non replicated peripheral");
     1653                pic_channels = periph[periph_index]->channels;
    14471654            }
    1448             else 
    1449             {
    1450                 error = 1;
    1451             }
    1452         }
     1655            use_pic = 1;
     1656        }
     1657
    14531658
    14541659        // The DMA, ICU, MMC, TIM, XCU peripherals can be replicated in all clusters
    1455         // but it must exist only one component of each type per cluster
     1660        // but no more than one component of each type per cluster
    14561661
    14571662        /////////////////////////////////
     
    14711676            found_icu = 1;
    14721677
    1473             if (icu_channels > 0)
     1678            if ( periph[periph_index]->channels <
     1679                 (header->irq_per_proc * cluster[cluster_index]->procs) )
    14741680            {
    1475                 assert( (periph[periph_index]->channels == icu_channels) &&
    1476                         "[XML ERROR] the number of interruptions per processor "
    1477                         "from the ICU (icu channels) must be the same on all "
    1478                         "clusters");
    1479             }
    1480             else
    1481             {
    1482                 icu_channels = periph[periph_index]->channels;
     1681                printf("[XML ERROR] ICU channels smaller than PROCS * IRQ_PER_PROC\n");
     1682                printf(" - icu channels = %d\n - nprocs = %d\n - irq_per_proc = %d\n",
     1683                       periph[periph_index]->channels,
     1684                       cluster[cluster_index]->procs,
     1685                       header->irq_per_proc );
     1686                exit(1);
    14831687            }
    14841688        }
     
    14981702            found_timer = 1;
    14991703            if (tim_channels < periph[periph_index]->channels)
    1500             {
    15011704                tim_channels = periph[periph_index]->channels;
    1502             }
    15031705        }
    15041706        //////////////////////////////////
     
    15121714            use_xcu      = 1;
    15131715
    1514             if (icu_channels > 0)
     1716            if ( periph[periph_index]->channels <
     1717                 (header->irq_per_proc * cluster[cluster_index]->procs) )
    15151718            {
    1516                 assert( (periph[periph_index]->channels == icu_channels) &&
    1517                         "[XML ERROR] the number of interruptions per processor "
    1518                         "from the ICU (icu channels) must be the same on all "
    1519                         "clusters");
     1719                printf("[XML ERROR] XCU channels smaller than PROCS * IRQ_PER_PROC\n");
     1720                printf(" - xcu channels = %d\n - nprocs = %d\n - irq_per_proc = %d\n",
     1721                       periph[periph_index]->channels,
     1722                       cluster[cluster_index]->procs,
     1723                       header->irq_per_proc );
     1724                exit(1);
     1725            }
     1726        }
     1727        else
     1728        {
     1729            printf("[XML ERROR] illegal peripheral type: %s in cluster %d\n",
     1730                    str, cluster_index);
     1731            exit(1);
     1732        }
     1733
     1734        if (error)
     1735        {
     1736            printf("[XML ERROR] illegal peripheral %s in cluster %d\n",
     1737                    str, cluster_index);
     1738            exit(1);
     1739        }
     1740    }
     1741    else
     1742    {
     1743        printf("[XML ERROR] illegal or missing <type> for peripheral  %d in cluster %d\n",
     1744                periph_loc_index, cluster_index);
     1745        exit(1);
     1746    }
     1747
     1748    ////////////// set irq_offset attribute
     1749    periph[periph_index]->irq_offset = irq_index;
     1750
     1751#if XML_PARSER_DEBUG
     1752printf("      irq_offset  = %d\n", irq_index );
     1753#endif
     1754
     1755    ///////////// get IRQs
     1756    int status = xmlTextReaderRead(reader);
     1757    while (status == 1)
     1758    {
     1759        const char * tag = (const char *) xmlTextReaderConstName(reader);
     1760
     1761        if (strcmp(tag, "irq") == 0)
     1762        {
     1763            if ( (periph[periph_index]->type != PERIPH_TYPE_ICU) &&
     1764                 (periph[periph_index]->type != PERIPH_TYPE_XCU) &&
     1765                 (periph[periph_index]->type != PERIPH_TYPE_PIC) )
     1766            {
     1767                printf("[XML ERROR] periph %d in cluster(%d,%d) "
     1768                       " only ICU, XCU and PIC can contain IRQs",
     1769                periph_loc_index, cluster[cluster_index]->x, cluster[cluster_index]->y);
     1770                exit(1);
    15201771            }
    15211772            else
    15221773            {
    1523                 icu_channels = periph[periph_index]->channels;
     1774                  irqNode(reader);
    15241775            }
    15251776        }
     1777        else if (strcmp(tag, "#text")    == 0) { }
     1778        else if (strcmp(tag, "#comment") == 0) { }
     1779        else if (strcmp(tag, "periph")   == 0)
     1780        {
     1781            periph[periph_index]->irqs = irq_loc_index;
     1782            cluster[cluster_index]->periphs++;
     1783            periph_loc_index++;
     1784            periph_index++;
     1785
     1786#if XML_PARSER_DEBUG
     1787printf("      irqs        = %d\n", irq_loc_index);
     1788printf("      irq_offset  = %d\n", irq_index);
     1789#endif
     1790            return;
     1791        }
    15261792        else
    15271793        {
    1528             printf("[XML ERROR] illegal <type>: %s for peripheral %d in cluster %d\n",
    1529                     str, periph_loc_index, cluster_index);
     1794            printf("[XML ERROR] Unknown tag %s", tag);
    15301795            exit(1);
    15311796        }
    1532 
    1533         if (error)
    1534         {
    1535             printf("[XML ERROR] illegal <type>: %s for peripheral %d in cluster %d\n",
    1536                     str, periph_loc_index, cluster_index);
    1537             exit(1);
    1538         }
    1539     }
    1540     else
    1541     {
    1542         printf("[XML ERROR] missing <type> for peripheral  %d in cluster %d\n",
    1543                 periph_loc_index, cluster_index);
    1544         exit(1);
    1545     }
    1546 
    1547     periph_index++;
    1548     periph_loc_index++;
    1549     cluster[cluster_index]->periphs++;
    1550 
     1797        status = xmlTextReaderRead(reader);
     1798    }
    15511799} // end periphNode
    15521800
     
    15681816
    15691817#if XML_PARSER_DEBUG
    1570     printf("\n  coproc %d\n", coproc_index);
     1818printf("\n  coproc %d\n", coproc_index);
    15711819#endif
    15721820
     
    15781826    {
    15791827#if XML_PARSER_DEBUG
    1580         printf("      name = %s\n", str);
     1828printf("      name = %s\n", str);
    15811829#endif
    15821830        strncpy(coproc[coproc_index]->name, str, 31);
     
    16031851    {
    16041852#if XML_PARSER_DEBUG
    1605         printf("      clusterid = %d\n", cluster_index);
    1606         printf("      psegname  = %s\n", str);
    1607         printf("      psegid    = %d\n", index);
     1853printf("      clusterid = %d\n", cluster_index);
     1854printf("      psegname  = %s\n", str);
     1855printf("      psegid    = %d\n", index);
    16081856#endif
    16091857        coproc[coproc_index]->psegid = index;
    1610         assert(pseg[index]->type == PSEG_TYPE_PERI && "coproc psegname attribute must refer to a pseg of type PERI" );
     1858        assert(pseg[index]->type == PSEG_TYPE_PERI &&
     1859        "coproc psegname attribute must refer to a pseg of type PERI" );
    16111860    }
    16121861    else
     
    16211870
    16221871#if XML_PARSER_DEBUG
    1623     printf("      port_offset = %d\n", cp_port_index);
     1872printf("      port_offset = %d\n", cp_port_index);
    16241873#endif
    16251874
     
    16531902
    16541903
    1655 /////////////////////////////////////
    1656 void irqNode(xmlTextReaderPtr reader)
     1904//////////////////////////////////////
     1905void procNode(xmlTextReaderPtr reader)
    16571906{
    16581907    unsigned int ok;
    16591908    unsigned int value;
    1660     char * str;
    16611909
    16621910    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
    16631911
    1664     if (irq_index >= MAX_IRQS) {
    1665         printf("[XML ERROR] The number of irqs is larger than %d\n", MAX_IRQS);
    1666     }
    1667 
    1668 #if XML_PARSER_DEBUG
    1669     printf("     irq %d\n", irq_loc_index);
    1670 #endif
    1671 
    1672     irq[irq_index] = (mapping_irq_t *) malloc(sizeof(mapping_irq_t));
    1673 
    1674     ///////// get type attribute
    1675     str = getStringValue(reader, "type", &ok);
    1676     if (ok)
    1677     {
    1678 #if XML_PARSER_DEBUG
    1679         printf("        type    = %s\n", str);
    1680 #endif
    1681         if      ( strcmp(str, "HARD") == 0 ) irq[irq_index]->type = IRQ_TYPE_HWI;
    1682         else if ( strcmp(str, "SOFT") == 0 ) irq[irq_index]->type = IRQ_TYPE_SWI;
    1683         else if ( strcmp(str, "TIME") == 0 ) irq[irq_index]->type = IRQ_TYPE_PTI;
    1684         else   
    1685         {
    1686             printf("[XML ERROR] illegal IRQ <type> for processor %d in cluster %d\n",
    1687                     cluster_index, proc_loc_index);
    1688             exit(1);
    1689         }
    1690     }
    1691     else
    1692     {
    1693         printf("[XML ERROR] missing IRQ <type> for processor %d in cluster %d\n",
    1694                 cluster_index, proc_loc_index);
    1695         exit(1);
    1696     }
    1697 
    1698     ///////// get icuid attribute
    1699     value = getIntValue(reader, "icuid", &ok);
    1700     if (ok)
    1701     {
    1702 #if XML_PARSER_DEBUG
    1703         printf("        icuid   = %d\n", value);
    1704 #endif
    1705         irq[irq_index]->icuid = value;
    1706         if (value >= 32)
    1707         {
    1708             printf("[XML ERROR] IRQ <icuid> too large for processor %d in cluster %d\n",
    1709                     cluster_index, proc_loc_index);
    1710             exit(1);
    1711         }
    1712     }
    1713     else
    1714     {
    1715         printf("[XML ERROR] missing IRQ <icuid> for processor %d in cluster %d\n",
    1716                 cluster_index, proc_loc_index);
    1717         exit(1);
    1718     }
    1719 
    1720     ///////// get isr attribute
    1721     str = getStringValue(reader, "isr", &ok);
    1722     if (ok)
    1723     {
    1724 #if XML_PARSER_DEBUG
    1725         printf("        isr     = %s\n", str);
    1726 #endif
    1727         if      (strcmp(str, "ISR_SWITCH" ) == 0)  irq[irq_index]->isr = ISR_SWITCH;
    1728         else if (strcmp(str, "ISR_IOC"    ) == 0)  irq[irq_index]->isr = ISR_IOC;
    1729         else if (strcmp(str, "ISR_DMA"    ) == 0)  irq[irq_index]->isr = ISR_DMA;
    1730         else if (strcmp(str, "ISR_TTY"    ) == 0)  irq[irq_index]->isr = ISR_TTY;
    1731         else if (strcmp(str, "ISR_TIMER"  ) == 0)  irq[irq_index]->isr = ISR_TIMER;
    1732         else if (strcmp(str, "ISR_WAKUP"  ) == 0)  irq[irq_index]->isr = ISR_WAKUP;
    1733         else if (strcmp(str, "ISR_DEFAULT") == 0)  irq[irq_index]->isr = ISR_DEFAULT;
    1734         else
    1735         {
    1736             printf("[XML ERROR] illegal IRQ <isr> for processor %d in cluster %d\n",
    1737                     cluster_index, proc_loc_index);
    1738             exit(1);
    1739         }
    1740 #if XML_PARSER_DEBUG
    1741         printf("        isrnum  = %d\n", irq[irq_index]->isr);
    1742 #endif
    1743     } 
    1744     else
    1745     {
    1746         printf("[XML ERROR] missing IRQ <isr> for processor %d in cluster %d\n",
    1747                 cluster_index, proc_loc_index);
    1748         exit(1);
    1749     }
    1750 
    1751     ///////// get channel attribute (optionnal : 0 if missing)
    1752     value = getIntValue(reader, "channel", &ok);
    1753     if (ok)
    1754     {
    1755 #if XML_PARSER_DEBUG
    1756         printf("        channel = %d\n", value);
    1757 #endif
    1758         irq[irq_index]->channel = value;
    1759     }
    1760     else
    1761     {
    1762         irq[irq_index]->channel = 0;
    1763     }
    1764 
    1765     irq_index++;
    1766     irq_loc_index++;
    1767 
    1768 } // end irqNode
    1769 
    1770 
    1771 //////////////////////////////////////
    1772 void procNode(xmlTextReaderPtr reader)
    1773 {
    1774     unsigned int ok;
    1775     unsigned int value;
    1776 
    1777     irq_loc_index = 0;
    1778 
    1779     if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
    1780 
    17811912    if (proc_index >= MAX_PROCS)
    17821913    {
     
    17861917
    17871918#if XML_PARSER_DEBUG
    1788     printf("\n  proc %d\n", proc_index);
     1919printf("\n    proc %d\n", proc_index);
    17891920#endif
    17901921
     
    17991930        exit(1);
    18001931    }
    1801 
    1802     ////////// set irq_offset attribute
    1803     proc[proc_index]->irq_offset = irq_index;
    1804 
    1805 #if XML_PARSER_DEBUG
    1806     printf("    irq_offset = %d\n", irq_index);
    1807 #endif
    1808 
    1809     int status = xmlTextReaderRead(reader);
    1810     while (status == 1)
    1811     {
    1812         const char * tag = (const char *) xmlTextReaderConstName(reader);
    1813 
    1814         if (strcmp(tag, "irq") == 0)
    1815         {
    1816             irqNode(reader);
    1817         }
    1818         else if (strcmp(tag, "#text")    == 0) { }
    1819         else if (strcmp(tag, "#comment") == 0) { }
    1820         else if (strcmp(tag, "proc")     == 0)
    1821         {
    1822             proc[proc_index]->irqs = irq_loc_index;
    1823             cluster[cluster_index]->procs++;
    1824             proc_loc_index++;
    1825             proc_index++;
    1826             return;
    1827         }
    1828         else
    1829         {
    1830             printf("[XML ERROR] Unknown tag %s", tag);
    1831             exit(1);
    1832         }
    1833         status = xmlTextReaderRead(reader);
    1834     }
     1932    proc[proc_index]->index = proc_loc_index;
     1933
     1934    cluster[cluster_index]->procs++;
     1935    proc_loc_index++;
     1936    proc_index++;
    18351937} // end procNode()
    18361938
     
    18521954
    18531955#if XML_PARSER_DEBUG
    1854     printf("    pseg %d\n", pseg_index);
     1956printf("    pseg %d\n", pseg_index);
    18551957#endif
    18561958
     
    18601962    str = getStringValue(reader, "name", &ok);
    18611963#if XML_PARSER_DEBUG
    1862     printf("      name = %s\n", str);
     1964printf("      name = %s\n", str);
    18631965#endif
    18641966    if (ok)
     
    18761978    str = getStringValue(reader, "type", &ok);
    18771979#if XML_PARSER_DEBUG
    1878     printf("      type = %s\n", str);
     1980printf("      type = %s\n", str);
    18791981#endif
    18801982    if      (ok && (strcmp(str, "RAM" ) == 0)) { pseg[pseg_index]->type = PSEG_TYPE_RAM; }
     
    18911993    ll_value = getPaddrValue(reader, "base", &ok);
    18921994#if XML_PARSER_DEBUG
    1893     printf("      base = 0x%llx\n", ll_value);
     1995printf("      base = 0x%llx\n", ll_value);
    18941996#endif
    18951997    if (ok)
     
    19062008    ll_value = getPaddrValue(reader, "length", &ok);
    19072009#if XML_PARSER_DEBUG
    1908     printf("      length = 0x%llx\n", ll_value);
     2010printf("      length = 0x%llx\n", ll_value);
    19092011#endif
    19102012    if (ok)
     
    19562058    found_mmc   = 0;
    19572059
    1958     if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) {
    1959         return;
    1960     }
     2060    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT)  return;
    19612061
    19622062#if XML_PARSER_DEBUG
     
    20242124        else if (strcmp(tag, "cluster")  == 0)
    20252125        {
    2026 
    2027             ///////// TIMER and ICU peripheral are mandatory //////////////
    2028             if (!found_timer && !found_xcu)
     2126            ///////// TIMER and ICU peripheral are mandatory when nprocs != 0
     2127            unsigned int procs = cluster[cluster_index]->procs;
     2128            if ( procs && !found_timer && !found_xcu)
    20292129            {
    20302130                printf("[XML ERROR] missing timer peripheral in cluster %d\n", cluster_index);
     
    20322132            }
    20332133
    2034             if (!found_icu && !found_xcu)
     2134            if ( procs && !found_icu && !found_xcu)
    20352135            {
    20362136                printf("[XML ERROR] missing icu peripheral in cluster %d\n", cluster_index);
     
    20382138            }
    20392139
    2040             if (nb_proc_max < cluster[cluster_index]->procs)
    2041             {
    2042                 nb_proc_max = cluster[cluster_index]->procs;
    2043             }
     2140            if (nb_procs_max < procs) nb_procs_max = procs;
    20442141
    20452142#if XML_PARSER_DEBUG
     
    20772174        else if (strcmp(tag, "clusterset") == 0)
    20782175        {
    2079             // checking source file consistency
     2176            // checking number of clusters
    20802177            if ( cluster_index != (header->x_size * header->y_size) )
    20812178            {
     
    20842181            }
    20852182
    2086             // At least one TTY terminal for system boot
    2087             if (header->tty_cluster == 0xFFFFFFFF)
     2183            // checking TTY terminal for system boot
     2184            if ( tty_channels == 0 )
    20882185            {
    2089                 printf("[XML ERROR] illegal or missing tty peripheral");
     2186                printf("[XML ERROR] missing TTY peripheral\n");
    20902187                exit(1);
    20912188            }
    20922189
    2093             // the number of ICU channels must be NB_PROCS * irq_per_proc
    2094             if (icu_channels != (header->irq_per_proc * proc_loc_index))
     2190            // checking IOC sub-types
     2191            if ( (use_bdv + use_hba + use_spi) > 1 )
    20952192            {
    2096                 printf("[XML ERROR] illegal ICU number of channels. "
    2097                        "It must be equal to NB_PROCS * IRQ_PER_PROC\n");
     2193                printf("[XML ERROR] all IOC peripherals must have the same type\n");
    20982194                exit(1);
    20992195            }
     
    21342230        const char * tag = (const char *) xmlTextReaderConstName(reader);
    21352231
    2136         if      (strcmp(tag, "vseg")      == 0) { vsegNode(reader); }
     2232        if      (strcmp(tag, "vseg")      == 0)
     2233        {
     2234            vsegNode( reader );
     2235            header->globals = header->globals + 1;
     2236        }
    21372237        else if (strcmp(tag, "#text")     == 0) { }
    21382238        else if (strcmp(tag, "#comment")  == 0) { }
     
    21422242            printf("  end global set\n\n");
    21432243#endif
    2144             header->globals = vseg_index;
    21452244            vseg_loc_index = 0;
    21462245            return;
     
    21782277        else if (strcmp(tag, "vspaceset") == 0 )
    21792278        {
    2180             // checking source file consistency
    2181             if (vspace_index != header->vspaces)
    2182             {
    2183                 printf("[XML ERROR] Wrong number of vspaces\n");
    2184                 exit(1);
    2185             }
    2186             else
    2187             {
    2188                 header->vsegs = vseg_index;
    2189                 header->vobjs = vobj_index;
    2190                 header->tasks = task_index;
    2191                 return;
    2192             }
     2279            header->vsegs = vseg_index;
     2280            header->vobjs = vobj_index;
     2281            header->tasks = task_index;
     2282            return;
    21932283        }
    21942284        else
     
    22822372    }
    22832373
    2284     //check the number of cluster
     2374    /////////// get x_io attribute
     2375    unsigned int x_io = getIntValue(reader, "x_io", &ok);
     2376#if XML_PARSER_DEBUG
     2377        printf("  x_io      = %d\n", x_io);
     2378#endif
     2379    if ( ok && (x_io < x_size) )
     2380    {
     2381        header->x_io = x_io;
     2382    }
     2383    else
     2384    {
     2385        printf("[XML ERROR] illegal or missing <x_io> attribute in header\n");
     2386        exit(1);
     2387    }
     2388
     2389    /////////// get y_io attribute
     2390    unsigned int y_io = getIntValue(reader, "y_io", &ok);
     2391#if XML_PARSER_DEBUG
     2392        printf("  y_io      = %d\n", y_size);
     2393#endif
     2394    if ( ok &&(y_io < y_size) )
     2395    {
     2396        header->y_io = y_io;
     2397    }
     2398    else
     2399    {
     2400        printf("[XML ERROR] illegal or missing <y_io> attribute in header\n");
     2401        exit(1);
     2402    }
     2403
     2404    // check the number of cluster
    22852405    if ( (x_size * y_size) >= MAX_CLUSTERS )
    22862406    {
     
    22892409    }
    22902410
    2291     ///////// get vspaces attribute
    2292     value = getIntValue(reader, "vspaces", &ok);
    2293     if (ok)
    2294     {
    2295         if (value >= MAX_VSPACES)
    2296         {
    2297             printf("[XML ERROR] The number of vspaces is larger than %d\n", MAX_VSPACES);
    2298             exit(1);
    2299         }
    2300 #if XML_PARSER_DEBUG
    2301         printf("  vspaces = %d\n", value);
    2302 #endif
    2303         header->vspaces  = value;
    2304     }
    2305     else
    2306     {
    2307         printf("[XML ERROR] illegal or missing <vspaces> attribute in mapping\n");
    2308         exit(1);
    2309     }
    2310 
    2311     ///////// get increment attribute
    2312     value = getIntValue(reader, "increment", &ok);
    2313     if (ok)
    2314     {
    2315         if ( (value != 0x10000) && (value != 0x8000) &&
    2316              (value != 0x4000)  && (value != 0x2000) )
    2317        
    2318         {
    2319             printf("[XML ERROR] The vseg increment must be one of the following: ");
    2320             printf(" 0x00010000 / 0x00008000 / 0x00004000 / 0x00002000");
    2321             exit(1);
    2322         }
    2323 #if XML_PARSER_DEBUG
    2324         printf("  increment = %d\n", value);
    2325 #endif
    2326         header->increment  = value;
    2327     }
    2328     else
    2329     {
    2330         printf("[XML ERROR] illegal or missing <increment> attribute in mapping\n");
    2331         exit(1);
    2332     }
    2333 
    2334     ///////// get increment attribute
     2411    ///////// get irq_per_proc attribute
    23352412    value = getIntValue(reader, "irq_per_proc", &ok);
    23362413    if (ok)
     
    23472424    }
    23482425
    2349     //////// initialise non replicated peripherals cluster index
    2350     header->cma_cluster     = 0xFFFFFFFF;
    2351     header->cma_cluster_bis = 0xFFFFFFFF;
    2352 
    2353     header->fbf_cluster     = 0xFFFFFFFF;
    2354     header->fbf_cluster_bis = 0xFFFFFFFF;
    2355 
    2356     header->iob_cluster     = 0xFFFFFFFF;
    2357     header->iob_cluster_bis = 0xFFFFFFFF;
    2358 
    2359     header->ioc_cluster     = 0xFFFFFFFF;
    2360     header->ioc_cluster_bis = 0xFFFFFFFF;
    2361 
    2362     header->nic_cluster     = 0xFFFFFFFF;
    2363     header->nic_cluster_bis = 0xFFFFFFFF;
    2364 
    2365     header->rom_cluster     = 0xFFFFFFFF;
    2366     header->rom_cluster_bis = 0xFFFFFFFF;
    2367 
    2368     header->sim_cluster     = 0xFFFFFFFF;
    2369     header->sim_cluster_bis = 0xFFFFFFFF;
    2370 
    2371     header->tty_cluster     = 0xFFFFFFFF;
    2372     header->tty_cluster_bis = 0xFFFFFFFF;
    2373 
    2374     ///////// set signature
     2426    ///////// get use_ramdisk attribute (default = 0)
     2427    value = getIntValue(reader, "use_ramdisk", &ok);
     2428    if (ok)
     2429    {
     2430#if XML_PARSER_DEBUG
     2431        printf("  use_ramdisk = %d\n", value);
     2432#endif
     2433        header->use_ramdisk = value;
     2434    }
     2435    else
     2436    {
     2437        header->use_ramdisk = 0;
     2438    }
     2439
     2440    ///////// set other header fields
     2441    header->increment = 0x10000;
    23752442    header->signature = IN_MAPPING_SIGNATURE;
     2443    header->globals   = 0;
     2444    header->vspaces   = 0;
     2445    header->psegs     = 0;
     2446    header->vsegs     = 0;
     2447    header->vobjs     = 0;
     2448    header->tasks     = 0;
     2449    header->procs     = 0;
     2450    header->irqs      = 0;
     2451    header->coprocs   = 0;
     2452    header->cp_ports  = 0;
     2453    header->periphs   = 0;
     2454
    23762455
    23772456    int status = xmlTextReaderRead(reader);
     
    23802459        const char * tag = (const char *) xmlTextReaderConstName(reader);
    23812460
    2382         if (strcmp(tag, "clusterset") == 0)
    2383         {
    2384             clusterSetNode(reader);
    2385         }
     2461        if      (strcmp(tag, "clusterset")   == 0) { clusterSetNode(reader); }
    23862462        else if (strcmp(tag, "globalset")    == 0) { globalSetNode(reader); }
    23872463        else if (strcmp(tag, "vspaceset")    == 0) { vspaceSetNode(reader); }
     
    25912667    def_int_write(fdout, "X_WIDTH           ", header->x_width);
    25922668    def_int_write(fdout, "Y_WIDTH           ", header->y_width);
     2669    def_int_write(fdout, "X_IO              ", header->x_io);
     2670    def_int_write(fdout, "Y_IO              ", header->y_io);
    25932671
    25942672    file_write(fdout, "\n");
    25952673
    2596     def_int_write(fdout, "NB_PROCS_MAX      ", nb_proc_max);
     2674    def_int_write(fdout, "NB_PROCS_MAX      ", nb_procs_max);
    25972675    def_int_write(fdout, "NB_TASKS_MAX      ", nb_tasks_max);
    25982676
     
    26052683
    26062684    def_int_write(fdout, "NB_TTY_CHANNELS   ", tty_channels);
    2607     def_int_write(fdout, "NB_HBA_CHANNELS   ", hba_channels);
     2685    def_int_write(fdout, "NB_IOC_CHANNELS   ", ioc_channels);
    26082686    def_int_write(fdout, "NB_NIC_CHANNELS   ", nic_channels);
    26092687    def_int_write(fdout, "NB_CMA_CHANNELS   ", cma_channels);
     
    26132691    def_int_write(fdout, "USE_XICU          ", use_xcu);
    26142692    def_int_write(fdout, "USE_IOB           ", use_iob);
    2615     def_int_write(fdout, "USE_HBA           ", use_hba);
    2616     def_int_write(fdout, "USE_BDV           ", use_bdv);
    2617     def_int_write(fdout, "USE_SPI           ", use_spi);
     2693    def_int_write(fdout, "USE_PIC           ", use_pic);
     2694
     2695    file_write(fdout, "\n");
     2696
     2697    def_int_write(fdout, "USE_IOC_RDK       ", header->use_ramdisk);
     2698    def_int_write(fdout, "USE_IOC_HBA       ", use_hba);
     2699    def_int_write(fdout, "USE_IOC_BDV       ", use_bdv);
     2700    def_int_write(fdout, "USE_IOC_SPI       ", use_spi);
    26182701
    26192702    file_write(fdout, "\n");
     
    26382721{
    26392722    int          fdout = open_file(file_path);
    2640     unsigned int count = 0;
     2723    unsigned int count;
    26412724    unsigned int vseg_id;
    26422725    unsigned int base;      // vseg base
     
    26482731    file_write(fdout, prol);
    26492732
    2650     // boot and kernel segments
    2651     for (vseg_id = 0 ; vseg_id < header->vsegs ; vseg_id++)
     2733    // boot mandatory global vsegs
     2734    for (vseg_id = 0 , count = 0 ; vseg_id < header->vsegs ; vseg_id++)
    26522735    {
    26532736        if ( strcmp(vseg[vseg_id]->name, "seg_boot_code") == 0 )
     
    26912774            count++;
    26922775        }
    2693         else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_code") == 0 )
    2694         {
    2695             base = vseg[vseg_id]->vbase;
    2696             size = vobj[vseg[vseg_id]->vobj_offset]->length;
    2697             ld_write(fdout, "seg_kernel_code_base    ", base);
    2698             ld_write(fdout, "seg_kernel_code_size    ", size);
    2699             count++;
    2700         }
    2701         else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_data") == 0 )
    2702         {
    2703             base = vseg[vseg_id]->vbase;
    2704             size = vobj[vseg[vseg_id]->vobj_offset]->length;
    2705             ld_write(fdout, "seg_kernel_data_base    ", base);
    2706             ld_write(fdout, "seg_kernel_data_size    ", size);
    2707             count++;
    2708         }
    2709         else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_uncdata") == 0 )
    2710         {
    2711             base = vseg[vseg_id]->vbase;
    2712             size = vobj[vseg[vseg_id]->vobj_offset]->length;
    2713             ld_write(fdout, "seg_kernel_uncdata_base ", base);
    2714             ld_write(fdout, "seg_kernel_uncdata_size ", size);
    2715             count++;
    2716         }
    2717         else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_init") == 0 )
    2718         {
    2719             base = vseg[vseg_id]->vbase;
    2720             size = vobj[vseg[vseg_id]->vobj_offset]->length;
    2721             ld_write(fdout, "seg_kernel_init_base    ", base);
    2722             ld_write(fdout, "seg_kernel_init_size    ", size);
    2723             count++;
    2724         }
    2725     }
    2726     if ( count != 9 )
     2776    }
     2777
     2778    if ( count != 5 )
    27272779    {
    2728         printf ("[XML ERROR] Missing Boot or Kernel vseg : only %d\n", count);
     2780        printf ("[XML ERROR] Missing mandatory Boot global vseg : only %d\n", count);
    27292781        printf ("Mandatory segments are :\n");
    27302782        printf (" - seg_boot_code\n");
     
    27332785        printf (" - seg_boot_mapping\n");
    27342786        printf (" - seg_boot_buffer\n");
     2787        exit(0);
     2788    }
     2789
     2790    file_write(fdout, "\n");
     2791
     2792    // kernel mandatory global vsegs
     2793    for (vseg_id = 0, count = 0 ; vseg_id < header->vsegs ; vseg_id++)
     2794    {
     2795        if ( strcmp(vseg[vseg_id]->name, "seg_kernel_code") == 0 )
     2796        {
     2797            base = vseg[vseg_id]->vbase;
     2798            size = vobj[vseg[vseg_id]->vobj_offset]->length;
     2799            ld_write(fdout, "seg_kernel_code_base    ", base);
     2800            ld_write(fdout, "seg_kernel_code_size    ", size);
     2801            count++;
     2802        }
     2803        else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_data") == 0 )
     2804        {
     2805            base = vseg[vseg_id]->vbase;
     2806            size = vobj[vseg[vseg_id]->vobj_offset]->length;
     2807            ld_write(fdout, "seg_kernel_data_base    ", base);
     2808            ld_write(fdout, "seg_kernel_data_size    ", size);
     2809            count++;
     2810        }
     2811        else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_uncdata") == 0 )
     2812        {
     2813            base = vseg[vseg_id]->vbase;
     2814            size = vobj[vseg[vseg_id]->vobj_offset]->length;
     2815            ld_write(fdout, "seg_kernel_uncdata_base ", base);
     2816            ld_write(fdout, "seg_kernel_uncdata_size ", size);
     2817            count++;
     2818        }
     2819        else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_init") == 0 )
     2820        {
     2821            base = vseg[vseg_id]->vbase;
     2822            size = vobj[vseg[vseg_id]->vobj_offset]->length;
     2823            ld_write(fdout, "seg_kernel_init_base    ", base);
     2824            ld_write(fdout, "seg_kernel_init_size    ", size);
     2825            count++;
     2826        }
     2827    }
     2828    if ( count != 4 )
     2829    {
     2830        printf ("[XML ERROR] Missing mandatory Kernel global vseg : only %d\n", count);
     2831        printf ("Mandatory segments are :\n");
    27352832        printf (" - seg_kernel_code\n");
    27362833        printf (" - seg_kernel_data\n");
    27372834        printf (" - seg_kernel_uncdata\n");
    27382835        printf (" - seg_kernel_init\n");
    2739     }
    2740 
     2836        exit(0);
     2837    }
     2838
     2839    file_write(fdout, "\n");
     2840
     2841    // boot and kernel optionnal global vsegs (pseudo ROMs)
     2842    unsigned int seg_ram_disk_base    = 0xFFFFFFFF;
     2843    unsigned int seg_ram_disk_size    = 0;
     2844    unsigned int seg_reset_code_base  = 0xFFFFFFFF;
     2845    unsigned int seg_reset_code_size  = 0;
     2846    for (vseg_id = 0 ; vseg_id < header->vsegs ; vseg_id++)
     2847    {
     2848        if ( strcmp(vseg[vseg_id]->name, "seg_reset_code") == 0 )
     2849        {
     2850            seg_reset_code_base = vseg[vseg_id]->vbase;
     2851            seg_reset_code_size = vobj[vseg[vseg_id]->vobj_offset]->length;
     2852        }
     2853        if ( strcmp(vseg[vseg_id]->name, "seg_ram_disk") == 0 )
     2854        {
     2855            seg_ram_disk_base   = vseg[vseg_id]->vbase;
     2856            seg_ram_disk_size   = vobj[vseg[vseg_id]->vobj_offset]->length;
     2857        }
     2858    }
     2859
     2860    ld_write(fdout, "seg_reset_code_base     ", seg_reset_code_base);
     2861    ld_write(fdout, "seg_reset_code_size     ", seg_reset_code_size);
     2862    ld_write(fdout, "seg_ram_disk_base       ", seg_ram_disk_base);
     2863    ld_write(fdout, "seg_ram_disk_size       ", seg_ram_disk_size);
     2864   
    27412865    file_write(fdout, "\n");
    27422866
     
    27442868    set_periph_vbase_array();
    27452869
    2746     // non replicated peripherals
     2870    //  non replicated peripherals
    27472871    ld_write(fdout, "seg_cma_base            ",   periph_vbase_array[PERIPH_TYPE_CMA]);
    27482872    ld_write(fdout, "seg_fbf_base            ",   periph_vbase_array[PERIPH_TYPE_FBF]);
     
    27532877    ld_write(fdout, "seg_sim_base            ",   periph_vbase_array[PERIPH_TYPE_SIM]);
    27542878    ld_write(fdout, "seg_tty_base            ",   periph_vbase_array[PERIPH_TYPE_TTY]);
     2879    ld_write(fdout, "seg_pic_base            ",   periph_vbase_array[PERIPH_TYPE_PIC]);
    27552880
    27562881    file_write(fdout, "\n");
  • soft/giet_vm/hello/main.c

    r254 r295  
    11#include "stdio.h"
     2#include "hard_config.h"
    23
    34__attribute__((constructor)) void main()
     
    67    unsigned int        proc = giet_procid();
    78
    8     giet_tty_printf("Starting task HELLO on processor %d at cycle %d\n",
    9                     giet_procid(), giet_proctime() );
    10  
     9    unsigned int    procid     = giet_procid();
     10    unsigned int    cluster_xy = procid/NB_PROCS_MAX;
     11    unsigned int    lpid       = procid%NB_PROCS_MAX;
     12    unsigned int    x          = cluster_xy >> Y_WIDTH;
     13    unsigned int    y          = cluster_xy & ((1<<Y_WIDTH)-1);
     14
     15    giet_tty_printf( "*** Starting task hello on processor[%d,%d,%d] at cycle %d\n\n",
     16                      x, y, lpid, giet_proctime() );
     17
    1118        while (1)
    1219        {
    13                 giet_tty_printf(" hello from processor %d\n", proc);
     20                giet_tty_printf(" hello world\n");
    1421        giet_tty_getc((void*)&byte);
    1522        if ( byte == 'q' ) giet_exit();
  • soft/giet_vm/mappings/4c_4p_sort_leti.xml

    r292 r295  
    11<?xml version="1.0"?>
    22
    3 <mapping_info signature    = "0xdeadbeef"
    4               name         = "4c_4p_sort_intact"
     3<mapping_info signature    = "0xdace2014"
     4              name         = "4c_4p_sort_leti"
    55              x_size       = "2"
    6               y_size       = "2"
     6              y_size       = "3"
    77              x_width      = "4"
    88              y_width      = "4"
    9               vspaces      = "1"
    10                           increment    = "0x10000"
    11                           irq_per_proc = "4" >
    12 
    13 *** The "increment" parameter is the virtual address cluster increment
    14 *** The physical address cluster increment is 0x10000000000 / NB_CLUSTERS
    15 
    16 *** This first section describes an instance of the "tsar_generic_iob" architecture
    17 *** with 4 clusters, 1 processor per cluster and 40 bits physical address.
     9                          irq_per_proc = "4"
     10              use_ramdisk  = "1"
     11                          x_io         = "0"
     12              y_io         = "0" >
     13
     14*** This mapping is for the "tsar_generic_leti" hardware architecture
     15*** with 4 clusters containing processors and 4 processors per cluster
     16*** 40 bits physical address, and 64 Mbytes per cluster.
     17*** There is 4 IRQ inputs per processor
     18*** It does not use the external peripherals.
     19*** It uses the RAMDISK in cluster(0,0)
     20*** It uses the mono-channel TTY implemented in cluster(0,0).
    1821
    1922    <clusterset>
    20 
    2123        <cluster x = "0" y = "0" >
    22             <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0000000000" length = "0x0000800000" />
     24            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0000000000" length = "0x0400000000" />
    2325            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x00F0000000" length = "0x0000002000" />
    2426            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x00E0000000" length = "0x0000001000" />
    25 
    26 *** Non replicated peripherals (including the ROM containing the preloader code)
    27 
    2827            <pseg name = "PSEG_IOC"  type = "PERI" base = "0x00F2000000" length = "0x0000001000" />
    2928            <pseg name = "PSEG_TTY"  type = "PERI" base = "0x00F4000000" length = "0x0000001000" />
    3029
    31             <proc index  = "0" >
    32                 <irq type = "SOFT" icuid = "0"  isr = "ISR_WAKUP" />
    33                 <irq type = "TIME" icuid = "4"  isr = "ISR_SWITCH" />
    34                 <irq type = "HARD" icuid = "8"  isr = "ISR_DEFAULT" />
    35                 <irq type = "HARD" icuid = "9"  isr = "ISR_IOC" />
    36                 <irq type = "HARD" icuid = "10" isr = "ISR_TTY" />
    37             </proc>
    38             <proc index  = "1" >
    39                 <irq type = "SOFT" icuid = "1"  isr = "ISR_WAKUP" />
    40                 <irq type = "TIME" icuid = "5"  isr = "ISR_SWITCH" />
    41             </proc>
    42             <proc index  = "2" >
    43                 <irq type = "SOFT" icuid = "2"  isr = "ISR_WAKUP" />
    44                 <irq type = "TIME" icuid = "6"  isr = "ISR_SWITCH" />
    45             </proc>
    46             <proc index  = "3" >
    47                 <irq type = "SOFT" icuid = "3"  isr = "ISR_WAKUP" />
    48                 <irq type = "TIME" icuid = "7"  isr = "ISR_SWITCH" />
    49             </proc>
    50 
    51             <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "16" />
    52             <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1"  />
    53             <periph type = "IOC"  psegname = "PSEG_IOC"  channels = "1" subtype = "BDV" />
    54             <periph type = "TTY"  psegname = "PSEG_TTY"  channels = "1"  />
    55 
     30            <proc index  = "0" />
     31            <proc index  = "1" />
     32            <proc index  = "2" />
     33            <proc index  = "3" />
     34
     35            <periph type = "MMC"  psegname = "PSEG_MMC"  >
     36            </periph>
     37            <periph type = "IOC"  psegname = "PSEG_IOC"  subtype = "BDV" >
     38            </periph>
     39            <periph type = "TTY"  psegname = "PSEG_TTY"  channels = "1" >
     40            </periph>
     41            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "16" >
     42                <irq srcid = "0"  srctype = "WTI"  isr = "ISR_WAKUP"                  dstx = "0"  dsty = "0"  dstid = "0" />
     43                <irq srcid = "1"  srctype = "WTI"  isr = "ISR_WAKUP"                  dstx = "0"  dsty = "0"  dstid = "1" />
     44                <irq srcid = "2"  srctype = "WTI"  isr = "ISR_WAKUP"                  dstx = "0"  dsty = "0"  dstid = "2" />
     45                <irq srcid = "3"  srctype = "WTI"  isr = "ISR_WAKUP"                  dstx = "0"  dsty = "0"  dstid = "3" />
     46                <irq srcid = "4"  srctype = "WTI"  isr = "ISR_NIC_RX"  channel = "0"  dstx = "0"  dsty = "0"  dstid = "0" />
     47                <irq srcid = "5"  srctype = "WTI"  isr = "ISR_NIC_RX"  channel = "1"  dstx = "0"  dsty = "0"  dstid = "0" />
     48                <irq srcid = "6"  srctype = "WTI"  isr = "ISR_NIC_TX"  channel = "0"  dstx = "0"  dsty = "0"  dstid = "0" />
     49                <irq srcid = "7"  srctype = "WTI"  isr = "ISR_NIC_TX"  channel = "1"  dstx = "0"  dsty = "0"  dstid = "0" />
     50                <irq srcid = "8"  srctype = "WTI"  isr = "ISR_CMA"     channel = "0"  dstx = "0"  dsty = "0"  dstid = "0" />
     51                <irq srcid = "9"  srctype = "WTI"  isr = "ISR_CMA"     channel = "1"  dstx = "0"  dsty = "0"  dstid = "0" />
     52                <irq srcid = "10" srctype = "WTI"  isr = "ISR_CMA"     channel = "2"  dstx = "0"  dsty = "0"  dstid = "0" />
     53                <irq srcid = "11" srctype = "WTI"  isr = "ISR_CMA"     channel = "3"  dstx = "0"  dsty = "0"  dstid = "0" />
     54                <irq srcid = "12" srctype = "WTI"  isr = "ISR_BDV"     channel = "0"  dstx = "0"  dsty = "0"  dstid = "0" />
     55                <irq srcid = "13" srctype = "WTI"  isr = "ISR_TTY_RX"  channel = "0"  dstx = "0"  dsty = "0"  dstid = "0" />
     56
     57                <irq srcid = "0"  srctype = "PTI"  isr = "ISR_TICK"                   dstx = "0"  dsty = "0"  dstid = "0" />
     58                <irq srcid = "1"  srctype = "PTI"  isr = "ISR_TICK"                   dstx = "0"  dsty = "0"  dstid = "1" />
     59                <irq srcid = "2"  srctype = "PTI"  isr = "ISR_TICK"                   dstx = "0"  dsty = "0"  dstid = "2" />
     60                <irq srcid = "3"  srctype = "PTI"  isr = "ISR_TICK"                   dstx = "0"  dsty = "0"  dstid = "3" />
     61
     62                <irq srcid = "8"  srctype = "HWI"  isr = "ISR_DEFAULT"                dstx = "0"  dsty = "0"  dstid = "0" />
     63                <irq srcid = "9"  srctype = "HWI"  isr = "ISR_BDV"     channel = "0"  dstx = "0"  dsty = "0"  dstid = "0" />
     64                <irq srcid = "10" srctype = "HWI"  isr = "ISR_TTY_RX"  channel = "0"  dstx = "0"  dsty = "0"  dstid = "0" />
     65            </periph>
    5666        </cluster>
    5767
    5868        <cluster x = "0" y = "1" >
    59             <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0100000000" length = "0x0000800000" />
     69            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0100000000" length = "0x0400000000" />
    6070            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x01F0000000" length = "0x0000002000" />
    6171            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x01E0000000" length = "0x0000001000" />
    6272
    63             <proc index  = "0" >
    64                 <irq type = "SOFT" icuid = "0"  isr = "ISR_WAKUP" />
    65                 <irq type = "TIME" icuid = "4"  isr = "ISR_SWITCH" />
    66                 <irq type = "HARD" icuid = "8"  isr = "ISR_DEFAULT" />
    67             </proc>
    68             <proc index  = "1" >
    69                 <irq type = "SOFT" icuid = "1"  isr = "ISR_WAKUP" />
    70                 <irq type = "TIME" icuid = "5"  isr = "ISR_SWITCH" />
    71             </proc>
    72             <proc index  = "2" >
    73                 <irq type = "SOFT" icuid = "2"  isr = "ISR_WAKUP" />
    74                 <irq type = "TIME" icuid = "6"  isr = "ISR_SWITCH" />
    75             </proc>
    76             <proc index  = "3" >
    77                 <irq type = "SOFT" icuid = "3"  isr = "ISR_WAKUP" />
    78                 <irq type = "TIME" icuid = "7"  isr = "ISR_SWITCH" />
    79             </proc>
    80 
    81             <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "16" />
    82             <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
     73            <proc index  = "0" />
     74            <proc index  = "1" />
     75            <proc index  = "2" />
     76            <proc index  = "3" />
     77
     78            <periph type = "MMC"  psegname = "PSEG_MMC" >
     79            </periph>
     80            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "16" >
     81                <irq srcid = "0"  srctype = "WTI"  isr = "ISR_WAKUP"                  dstx = "0"  dsty = "1"  dstid = "0" />
     82                <irq srcid = "1"  srctype = "WTI"  isr = "ISR_WAKUP"                  dstx = "0"  dsty = "1"  dstid = "1" />
     83                <irq srcid = "2"  srctype = "WTI"  isr = "ISR_WAKUP"                  dstx = "0"  dsty = "1"  dstid = "2" />
     84                <irq srcid = "3"  srctype = "WTI"  isr = "ISR_WAKUP"                  dstx = "0"  dsty = "1"  dstid = "3" />
     85
     86                <irq srcid = "0"  srctype = "PTI"  isr = "ISR_TICK"                   dstx = "0"  dsty = "1"  dstid = "0" />
     87                <irq srcid = "1"  srctype = "PTI"  isr = "ISR_TICK"                   dstx = "0"  dsty = "1"  dstid = "1" />
     88                <irq srcid = "2"  srctype = "PTI"  isr = "ISR_TICK"                   dstx = "0"  dsty = "1"  dstid = "2" />
     89                <irq srcid = "3"  srctype = "PTI"  isr = "ISR_TICK"                   dstx = "0"  dsty = "1"  dstid = "3" />
     90
     91                <irq srcid = "8"  srctype = "HWI"  isr = "ISR_DEFAULT"                dstx = "0"  dsty = "1"  dstid = "0" />
     92            </periph>
    8393        </cluster>
    8494
    8595        <cluster x = "1" y = "0" >
    86             <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1000000000" length = "0x0000800000" />
     96            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1000000000" length = "0x0400000000" />
    8797            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x10F0000000" length = "0x0000002000" />
    8898            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x10E0000000" length = "0x0000001000" />
    8999
    90             <proc index  = "0" >
    91                 <irq type = "SOFT" icuid = "0"  isr = "ISR_WAKUP" />
    92                 <irq type = "TIME" icuid = "4"  isr = "ISR_SWITCH" />
    93                 <irq type = "HARD" icuid = "8"  isr = "ISR_DEFAULT" />
    94             </proc>
    95             <proc index  = "1" >
    96                 <irq type = "SOFT" icuid = "1"  isr = "ISR_WAKUP" />
    97                 <irq type = "TIME" icuid = "5"  isr = "ISR_SWITCH" />
    98             </proc>
    99             <proc index  = "2" >
    100                 <irq type = "SOFT" icuid = "2"  isr = "ISR_WAKUP" />
    101                 <irq type = "TIME" icuid = "6"  isr = "ISR_SWITCH" />
    102             </proc>
    103             <proc index  = "3" >
    104                 <irq type = "SOFT" icuid = "3"  isr = "ISR_WAKUP" />
    105                 <irq type = "TIME" icuid = "7"  isr = "ISR_SWITCH" />
    106             </proc>
    107 
    108             <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "16" />
    109             <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
     100            <proc index  = "0" />
     101            <proc index  = "1" />
     102            <proc index  = "2" />
     103            <proc index  = "3" />
     104
     105            <periph type = "MMC"  psegname = "PSEG_MMC" >
     106            </periph>
     107            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "16" >
     108                <irq srcid = "0"  srctype = "WTI"  isr = "ISR_WAKUP"                  dstx = "1"  dsty = "0"  dstid = "0" />
     109                <irq srcid = "1"  srctype = "WTI"  isr = "ISR_WAKUP"                  dstx = "1"  dsty = "0"  dstid = "1" />
     110                <irq srcid = "2"  srctype = "WTI"  isr = "ISR_WAKUP"                  dstx = "1"  dsty = "0"  dstid = "2" />
     111                <irq srcid = "3"  srctype = "WTI"  isr = "ISR_WAKUP"                  dstx = "1"  dsty = "0"  dstid = "3" />
     112
     113                <irq srcid = "0"  srctype = "PTI"  isr = "ISR_TICK"                   dstx = "1"  dsty = "0"  dstid = "0" />
     114                <irq srcid = "1"  srctype = "PTI"  isr = "ISR_TICK"                   dstx = "1"  dsty = "0"  dstid = "1" />
     115                <irq srcid = "2"  srctype = "PTI"  isr = "ISR_TICK"                   dstx = "1"  dsty = "0"  dstid = "2" />
     116                <irq srcid = "3"  srctype = "PTI"  isr = "ISR_TICK"                   dstx = "1"  dsty = "0"  dstid = "3" />
     117
     118                <irq srcid = "8"  srctype = "HWI"  isr = "ISR_DEFAULT"                dstx = "1"  dsty = "0"  dstid = "0" />
     119            </periph>
    110120        </cluster>
    111121
    112122        <cluster x = "1" y = "1" >
    113             <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1100000000" length = "0x0000800000" />
     123            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1100000000" length = "0x0400000000" />
    114124            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x11F0000000" length = "0x0000002000" />
    115125            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x11E0000000" length = "0x0000001000" />
    116126
    117             <proc index  = "0" >
    118                 <irq type = "SOFT" icuid = "0"  isr = "ISR_WAKUP" />
    119                 <irq type = "TIME" icuid = "4"  isr = "ISR_SWITCH" />
    120                 <irq type = "HARD" icuid = "8"  isr = "ISR_DEFAULT" />
    121             </proc>
    122             <proc index  = "1" >
    123                 <irq type = "SOFT" icuid = "1"  isr = "ISR_WAKUP" />
    124                 <irq type = "TIME" icuid = "5"  isr = "ISR_SWITCH" />
    125             </proc>
    126             <proc index  = "2" >
    127                 <irq type = "SOFT" icuid = "2"  isr = "ISR_WAKUP" />
    128                 <irq type = "TIME" icuid = "6"  isr = "ISR_SWITCH" />
    129             </proc>
    130             <proc index  = "3" >
    131                 <irq type = "SOFT" icuid = "3"  isr = "ISR_WAKUP" />
    132                 <irq type = "TIME" icuid = "7"  isr = "ISR_SWITCH" />
    133             </proc>
    134 
    135             <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "16" />
    136             <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
    137         </cluster>
     127            <proc index  = "0" />
     128            <proc index  = "1" />
     129            <proc index  = "2" />
     130            <proc index  = "3" />
     131
     132            <periph type = "MMC"  psegname = "PSEG_MMC" >
     133            </periph>
     134            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "16" >
     135                <irq srcid = "0"  srctype = "WTI"  isr = "ISR_WAKUP"                  dstx = "1"  dsty = "1"  dstid = "0" />
     136                <irq srcid = "1"  srctype = "WTI"  isr = "ISR_WAKUP"                  dstx = "1"  dsty = "1"  dstid = "1" />
     137                <irq srcid = "2"  srctype = "WTI"  isr = "ISR_WAKUP"                  dstx = "1"  dsty = "1"  dstid = "2" />
     138                <irq srcid = "3"  srctype = "WTI"  isr = "ISR_WAKUP"                  dstx = "1"  dsty = "1"  dstid = "3" />
     139
     140                <irq srcid = "0"  srctype = "PTI"  isr = "ISR_TICK"                   dstx = "1"  dsty = "1"  dstid = "0" />
     141                <irq srcid = "1"  srctype = "PTI"  isr = "ISR_TICK"                   dstx = "1"  dsty = "1"  dstid = "1" />
     142                <irq srcid = "2"  srctype = "PTI"  isr = "ISR_TICK"                   dstx = "1"  dsty = "1"  dstid = "2" />
     143                <irq srcid = "3"  srctype = "PTI"  isr = "ISR_TICK"                   dstx = "1"  dsty = "1"  dstid = "3" />
     144
     145                <irq srcid = "8"  srctype = "HWI"  isr = "ISR_DEFAULT"                dstx = "1"  dsty = "1"  dstid = "0" />
     146            </periph>
     147        </cluster>
     148
     149*** empty clusters
     150
     151        <cluster x = "0" y = "2" >
     152        </cluster>
     153        <cluster x = "1" y = "2" >
     154        </cluster>
     155
    138156    </clusterset>
    139157
    140158    <globalset>
    141159
    142 *** Segments used by the boot code / A[31:28] = 0x0 / Identity mapping
    143 - seg_boot_mapping is loaded by the boot-loader. It contains the mapping info. The content is reused by the kernel.
    144 - seg_boot_code and seg_boot data are loaded by the preloader, used by the boot-loader The content is not reused by the kernel.
    145 - seg_boot_stack is contains the stacks used by all processors during reset and boot. The content is not reused by the Kernel.
    146 - seg_boot_buffer is used by the boot-loader. It can contain a complete .elf file. The content is not reused by the kernel.
     160*** Global vsegs associated to peripherals  replicated in all clusters (XCU, MMC, SCHED)
     161*** must respect the following policy (checked by the XML parser) :
     162*** vbase[x,y] = vbase[0,0] + 64K * cluster_xy
     163*** pbase[x,y] = pbase[0,0] + 4G  * cluster_xy
     164*** ( with cluster_xy = x*16 + y )
     165*** the vseg type is entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
     166*** The cluster index must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
     167
     168*** 5 global vsegs used by the boot code / A[31:28] = 0x0 / Identity mapping
     169*** seg_boot_mapping is loaded by the boot-loader. It contains the mapping info.  Reused by the kernel.
     170*** seg_boot_code and seg_boot data are loaded by the preloader, used by the boot-loader.  Not reused by the kernel.
     171*** seg_boot_stack contains the stacks used by all processors during reset and boot.  Not reused by the Kernel.
     172*** seg_boot_buffer is used by the boot-loader. It contains a complete .elf file.  Not reused by the kernel.
    147173
    148174        <vseg name = "seg_boot_code"      vbase = "0x00010000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
     
    153179        </vseg>
    154180        <vseg name = "seg_boot_buffer"    vbase = "0x00040000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
    155             <vobj name = "boot_buffer"    type = "BUFFER" length = "0x00020000" />
    156         </vseg>
    157         <vseg name = "seg_boot_stack"     vbase = "0x00060000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
    158             <vobj name = "boot_stack"     type = "BUFFER" length = "0x00090000" />
     181            <vobj name = "boot_buffer"    type = "BUFFER" length = "0x00060000" />
     182        </vseg>
     183        <vseg name = "seg_boot_stack"     vbase = "0x000A0000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
     184            <vobj name = "boot_stack"     type = "BUFFER" length = "0x00050000" />
    159185        </vseg>
    160186        <vseg name = "seg_boot_mapping"   vbase = "0x000F0000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
    161187            <vobj name = "boot_mapping"   type = "BLOB"   length = "0x00010000" binpath = "map.bin" />
    162188        </vseg>
    163 
    164 *** Segments used by the kernel / A[31:28] = 0x8
     189       
     190*** 4 global vsegs used by the kernel / A[31:28] = 0x8  / No identity mapping constraint
    165191 
    166192        <vseg name = "seg_kernel_code"    vbase = "0x80000000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" >
     
    177203        </vseg>
    178204
    179 *** Segments for non replicated peripherals / A[31:28] = 0xF / Identity mapping
    180 
    181         <vseg name = "seg_ioc"            vbase = "0xF2000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_IOC" ident = "1" >
     205*** 2 global vsegs for non replicated peripherals in cluster(0,0) / A[31:28] = 0xF /
     206
     207        <vseg name = "seg_ioc"            vbase = "0xF2000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_IOC" >
    182208            <vobj name = "ioc"            type = "PERI" length  = "0x00001000" />
    183209        </vseg>
    184         <vseg name = "seg_tty"            vbase = "0xF4000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_TTY" ident = "1" >
     210
     211        <vseg name = "seg_tty"            vbase = "0xF4000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_TTY" >
    185212                        <vobj name = "tty"            type = "PERI" length  = "0x00001000" />
    186213        </vseg>
    187         <vseg name = "seg_preloader"      vbase = "0x00000000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
     214
     215*** 2 global vsegs for pseudo-peripherals (PRELOADER and RAMDISK) / A[31:28] = 0x0
     216
     217        <vseg name = "seg_reset_code"     vbase = "0x00000000" mode = "CX__" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
    188218            <vobj name = "preloader"      type = "BUFFER" length  = "0x00010000" />
    189219        </vseg>
    190220
    191 *** Segments for replicated ICUS / A[31:24] = 0xF0 / Increment = 0x10000 / Identity mapping in cluster 0           
     221        <vseg name = "seg_ram_disk"       vbase = "0x02000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
     222            <vobj name = "ramdisk"        type = "BUFFER" length  = "0x02000000" />
     223        </vseg>
     224
     225*** 4 global vsegs for replicated ICUS / A[31:24] = 0xF0 / Increment = 0x10000 / Identity mapping in cluster (0,0)           
    192226
    193227        <vseg name = "seg_icu_0"          vbase = "0xF0000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_XCU" ident = "1" >
     
    204238        </vseg>
    205239
    206 *** segments for replicated MMC / A[31:24] = 0xE0 / Increment = 0x10000 / Identity mapping in cluster 0
    207 *** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
    208 *** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
     240*** 4 global vsegs for replicated MMC / A[31:24] = 0xE0 / Increment = 0x10000 / Identity mapping in cluster 0
    209241
    210242        <vseg name = "seg_memc_0"         vbase = "0xE0000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_MMC" ident = "1" >
     
    221253        </vseg>
    222254
    223 *** segments for replicated schedulers / A[31:28] = 0xC / Increment = 0x10000
    224 *** The type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
    225 *** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
     255*** 4 global vsegs for replicated schedulers / A[31:28] = 0xC / Increment = 0x10000
    226256
    227257        <vseg name = "seg_sched_0"        vbase = "0xC0000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" >
     
    237267            <vobj name = "sched_3"        type = "SCHED" length  = "0x00008000" />
    238268        </vseg>
    239 ***
     269
    240270    </globalset>
    241271
     
    249279
    250280        <vspace name = "sort" startname = "sort_data" >
    251             <vseg name = "seg_sort_code"   vbase = "0x00400000" mode = "CXWU" x = "1" y = "1" psegname = "PSEG_RAM" >
    252                 <vobj name = "sort_code"   type  = "ELF" length = "0x00010000" binpath = "build/sort/sort.elf" />
    253             </vseg>
    254             <vseg name = "seg_sort_data"   vbase = "0x00500000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" >
    255                 <vobj name = "sort_data"   type  = "ELF" length = "0x00010000" binpath = "build/sort/sort.elf" />
    256             </vseg>
    257             <vseg name = "seg_sort_ptab"   vbase = "0x00600000" mode = "C_W_" x = "1" y = "1" psegname = "PSEG_RAM" >
    258                 <vobj name = "sort_ptab"   type  = "PTAB" length  = "0x00020000" align = "13" />
    259             </vseg>
    260             <vseg name = "seg_sort_stack00" vbase = "0x00800000" mode = "C_WU" x = "0" y = "0" psegname = "PSEG_RAM" >
    261                 <vobj name = "sort_stack0"  type         = "BUFFER" length = "0x00010000" />
    262                 <vobj name = "sort_stack1"  type         = "BUFFER" length = "0x00010000" />
    263                 <vobj name = "sort_stack2"  type         = "BUFFER" length = "0x00010000" />
    264                 <vobj name = "sort_stack3"  type         = "BUFFER" length = "0x00010000" />
    265                 <vobj name = "sort_heap0"   type         = "BUFFER" length = "0x00010000" />
    266             </vseg>
    267             <vseg name = "seg_sort_stack01" vbase = "0x00A00000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" >
    268                 <vobj name = "sort_stack4"  type         = "BUFFER" length = "0x00010000" />
    269                 <vobj name = "sort_stack5"  type         = "BUFFER" length = "0x00010000" />
    270                 <vobj name = "sort_stack6"  type         = "BUFFER" length = "0x00010000" />
    271                 <vobj name = "sort_stack7"  type         = "BUFFER" length = "0x00010000" />
    272                 <vobj name = "sort_heap1"   type         = "BUFFER" length = "0x00010000" />
    273             </vseg>
    274             <vseg name = "seg_sort_stack10" vbase = "0x00C00000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" >
    275                 <vobj name = "sort_stack8"  type         = "BUFFER" length = "0x00010000" />
    276                 <vobj name = "sort_stack9"  type         = "BUFFER" length = "0x00010000" />
    277                 <vobj name = "sort_stack10" type         = "BUFFER" length = "0x00010000" />
    278                 <vobj name = "sort_stack11" type         = "BUFFER" length = "0x00010000" />
    279                 <vobj name = "sort_heap2"   type         = "BUFFER" length = "0x00010000" />
    280             </vseg>
    281             <vseg name = "seg_sort_stack11" vbase = "0x00E00000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" >
    282                 <vobj name = "sort_stack12" type         = "BUFFER" length = "0x00010000" />
    283                 <vobj name = "sort_stack13" type         = "BUFFER" length = "0x00010000" />
    284                 <vobj name = "sort_stack14" type         = "BUFFER" length = "0x00010000" />
    285                 <vobj name = "sort_stack15" type         = "BUFFER" length = "0x00010000" />
    286                 <vobj name = "sort_heap3"   type         = "BUFFER" length = "0x00010000" />
    287             </vseg>
    288                         <vseg name = "seg_params"       vbase = "0x00F00000" mode = "C_WU" x = "0" y = "0" psegname = "PSEG_RAM" >
    289                                 <vobj name = "nb_thread"    type     = "CONST"  length = "0x4" init = "16" />
     281            <vseg name = "seg_sort_code"     vbase = "0x00400000" mode = "CXWU" x = "1" y = "1" psegname = "PSEG_RAM" >
     282                <vobj name = "sort_code"     type  = "ELF" length = "0x00010000" binpath = "build/sort/sort.elf" />
     283            </vseg>
     284            <vseg name = "seg_sort_data"     vbase = "0x00500000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" >
     285                <vobj name = "sort_data"     type  = "ELF" length = "0x00010000" binpath = "build/sort/sort.elf" />
     286            </vseg>
     287            <vseg name = "seg_sort_ptab"     vbase = "0x00600000" mode = "C_W_" x = "1" y = "1" psegname = "PSEG_RAM" >
     288                <vobj name = "sort_ptab"     type  = "PTAB" length  = "0x00020000" align = "13" />
     289            </vseg>
     290            <vseg name = "seg_sort_stack_0"  vbase = "0x00200000" mode = "C_WU" x = "0" y = "0" psegname = "PSEG_RAM" >
     291                <vobj name = "sort_stack_00" type  = "BUFFER" length = "0x00010000" />
     292                <vobj name = "sort_stack_01" type  = "BUFFER" length = "0x00010000" />
     293                <vobj name = "sort_stack_02" type  = "BUFFER" length = "0x00010000" />
     294                <vobj name = "sort_stack_03" type  = "BUFFER" length = "0x00010000" />
     295                <vobj name = "sort_heap_0"   type  = "BUFFER" length = "0x00040000" />
     296            </vseg>
     297            <vseg name = "seg_sort_stack_1"  vbase = "0x00280000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" >
     298                <vobj name = "sort_stack_10" type  = "BUFFER" length = "0x00010000" />
     299                <vobj name = "sort_stack_11" type  = "BUFFER" length = "0x00010000" />
     300                <vobj name = "sort_stack_12" type  = "BUFFER" length = "0x00010000" />
     301                <vobj name = "sort_stack_13" type  = "BUFFER" length = "0x00010000" />
     302                <vobj name = "sort_heap_1"   type  = "BUFFER" length = "0x00040000" />
     303            </vseg>
     304            <vseg name = "seg_sort_stack_2"  vbase = "0x00300000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" >
     305                <vobj name = "sort_stack_20" type  = "BUFFER" length = "0x00010000" />
     306                <vobj name = "sort_stack_21" type  = "BUFFER" length = "0x00010000" />
     307                <vobj name = "sort_stack_22" type  = "BUFFER" length = "0x00010000" />
     308                <vobj name = "sort_stack_23" type  = "BUFFER" length = "0x00010000" />
     309                <vobj name = "sort_heap_2"   type  = "BUFFER" length = "0x00040000" />
     310            </vseg>
     311            <vseg name = "seg_sort_stack_3"  vbase = "0x00380000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" >
     312                <vobj name = "sort_stack_30" type  = "BUFFER" length = "0x00010000" />
     313                <vobj name = "sort_stack_31" type  = "BUFFER" length = "0x00010000" />
     314                <vobj name = "sort_stack_32" type  = "BUFFER" length = "0x00010000" />
     315                <vobj name = "sort_stack_33" type  = "BUFFER" length = "0x00010000" />
     316                <vobj name = "sort_heap_3"   type  = "BUFFER" length = "0x00040000" />
     317            </vseg>
     318
     319*** This vobj emulates a command line argument for the sort application
     320
     321                        <vseg name = "seg_params"       vbase = "0x00100000" mode = "C_WU" x = "0" y = "0" psegname = "PSEG_RAM" >
     322                                <vobj name = "nb_thread"    type  = "CONST"  length = "0x4" init = "16" />
    290323                        </vseg>
    291             <task name = "sort_0"  x = "0" y = "0" proclocid = "0" stackname = "sort_stack0"  heapname = "sort_heap0" startid = "0" usetty = "1" />
    292             <task name = "sort_1"  x = "0" y = "0" proclocid = "1" stackname = "sort_stack1"  heapname = "sort_heap0" startid = "0" usetty = "1" />
    293             <task name = "sort_2"  x = "0" y = "0" proclocid = "2" stackname = "sort_stack2"  heapname = "sort_heap0" startid = "0" usetty = "1" />
    294             <task name = "sort_3"  x = "0" y = "0" proclocid = "3" stackname = "sort_stack3"  heapname = "sort_heap0" startid = "0" usetty = "1" />
    295             <task name = "sort_4"  x = "0" y = "1" proclocid = "0" stackname = "sort_stack4"  heapname = "sort_heap1" startid = "0" usetty = "1" />
    296             <task name = "sort_5"  x = "0" y = "1" proclocid = "1" stackname = "sort_stack5"  heapname = "sort_heap1" startid = "0" usetty = "1" />
    297             <task name = "sort_6"  x = "0" y = "1" proclocid = "2" stackname = "sort_stack6"  heapname = "sort_heap1" startid = "0" usetty = "1" />
    298             <task name = "sort_7"  x = "0" y = "1" proclocid = "3" stackname = "sort_stack7"  heapname = "sort_heap1" startid = "0" usetty = "1" />
    299             <task name = "sort_8"  x = "1" y = "0" proclocid = "0" stackname = "sort_stack8"  heapname = "sort_heap2" startid = "0" usetty = "1" />
    300             <task name = "sort_9"  x = "1" y = "0" proclocid = "1" stackname = "sort_stack9"  heapname = "sort_heap2" startid = "0" usetty = "1" />
    301             <task name = "sort_10" x = "1" y = "0" proclocid = "2" stackname = "sort_stack10" heapname = "sort_heap2" startid = "0" usetty = "1" />
    302             <task name = "sort_11" x = "1" y = "0" proclocid = "3" stackname = "sort_stack11" heapname = "sort_heap2" startid = "0" usetty = "1" />
    303             <task name = "sort_12" x = "1" y = "1" proclocid = "0" stackname = "sort_stack12" heapname = "sort_heap3" startid = "0" usetty = "1" />
    304             <task name = "sort_13" x = "1" y = "1" proclocid = "1" stackname = "sort_stack13" heapname = "sort_heap3" startid = "0" usetty = "1" />
    305             <task name = "sort_14" x = "1" y = "1" proclocid = "2" stackname = "sort_stack14" heapname = "sort_heap3" startid = "0" usetty = "1" />
    306             <task name = "sort_15" x = "1" y = "1" proclocid = "3" stackname = "sort_stack15" heapname = "sort_heap3" startid = "0" usetty = "1" />
    307 
     324
     325            <task name = "sort_00" x = "0" y = "0" proclocid = "0" stackname = "sort_stack_00"  heapname = "sort_heap_0" startid = "0"  />
     326            <task name = "sort_01" x = "0" y = "0" proclocid = "1" stackname = "sort_stack_01"  heapname = "sort_heap_0" startid = "0"  />
     327            <task name = "sort_02" x = "0" y = "0" proclocid = "2" stackname = "sort_stack_02"  heapname = "sort_heap_0" startid = "0"  />
     328            <task name = "sort_03" x = "0" y = "0" proclocid = "3" stackname = "sort_stack_03"  heapname = "sort_heap_0" startid = "0"  />
     329
     330            <task name = "sort_10" x = "0" y = "1" proclocid = "0" stackname = "sort_stack_10"  heapname = "sort_heap_1" startid = "0"  />
     331            <task name = "sort_11" x = "0" y = "1" proclocid = "1" stackname = "sort_stack_11"  heapname = "sort_heap_1" startid = "0"  />
     332            <task name = "sort_12" x = "0" y = "1" proclocid = "2" stackname = "sort_stack_12"  heapname = "sort_heap_1" startid = "0"  />
     333            <task name = "sort_13" x = "0" y = "1" proclocid = "3" stackname = "sort_stack_13"  heapname = "sort_heap_1" startid = "0"  />
     334
     335            <task name = "sort_20" x = "1" y = "0" proclocid = "0" stackname = "sort_stack_20"  heapname = "sort_heap_2" startid = "0"  />
     336            <task name = "sort_21" x = "1" y = "0" proclocid = "1" stackname = "sort_stack_21"  heapname = "sort_heap_2" startid = "0"  />
     337            <task name = "sort_22" x = "1" y = "0" proclocid = "2" stackname = "sort_stack_22"  heapname = "sort_heap_2" startid = "0"  />
     338            <task name = "sort_23" x = "1" y = "0" proclocid = "3" stackname = "sort_stack_23"  heapname = "sort_heap_2" startid = "0"  />
     339
     340            <task name = "sort_30" x = "1" y = "1" proclocid = "0" stackname = "sort_stack_30"  heapname = "sort_heap_3" startid = "0"  />
     341            <task name = "sort_31" x = "1" y = "1" proclocid = "1" stackname = "sort_stack_31"  heapname = "sort_heap_3" startid = "0"  />
     342            <task name = "sort_32" x = "1" y = "1" proclocid = "2" stackname = "sort_stack_32"  heapname = "sort_heap_3" startid = "0"  />
     343            <task name = "sort_33" x = "1" y = "1" proclocid = "3" stackname = "sort_stack_33"  heapname = "sort_heap_3" startid = "0"  />
    308344        </vspace>
    309345    </vspaceset>
  • soft/giet_vm/pgcd/main.c

    r254 r295  
    11#include "stdio.h"
     2#include "hard_config.h"
    23
    34/////////////////////////////////////////
     
    78    unsigned int opy;
    89
    9     giet_tty_printf("Starting task PGCD on processor %d at cycle %d\n",
    10                    giet_procid(), giet_proctime());
     10    unsigned int    procid     = giet_procid();
     11    unsigned int    cluster_xy = procid/NB_PROCS_MAX;
     12    unsigned int    lpid       = procid%NB_PROCS_MAX;
     13    unsigned int    x          = cluster_xy >> Y_WIDTH;
     14    unsigned int    y          = cluster_xy & ((1<<Y_WIDTH)-1);
     15
     16    giet_tty_printf( "*** Starting task pgcd on processor[%d,%d,%d] at cycle %d\n\n",
     17                      x, y, lpid, giet_proctime() );
    1118
    1219    while (1)
  • soft/giet_vm/router/main.c

    r264 r295  
    22#include "mwmr_channel.h"
    33#include "mapping_info.h"
     4#include "hard_config.h"
    45
    5 #define NMAX 200
     6#define NMAX 50
    67
    78/////////////////////////////////////////////
     
    1314    mwmr_channel_t*     mwmr;
    1415
    15     giet_tty_printf( "*** Starting task producer on processor %d", giet_procid() );
    16     giet_tty_printf( " at cycle %d ***\n\n", giet_proctime() );
     16    unsigned int    procid     = giet_procid();
     17    unsigned int    cluster_xy = procid/NB_PROCS_MAX;
     18    unsigned int    lpid       = procid%NB_PROCS_MAX;
     19    unsigned int    x          = cluster_xy >> Y_WIDTH;
     20    unsigned int    y          = cluster_xy & ((1<<Y_WIDTH)-1);
    1721
    18     if( giet_vobj_get_vbase( "router" ,
    19                              "mwmr_in",
    20                              VOBJ_TYPE_MWMR,
    21                              (void*)&mwmr ) )
    22     {
    23         giet_tty_printf( "\n[ERROR] in producer task :\n");
    24         giet_tty_printf( "          undefined <mwmr_in> channel: %d\n", mwmr);
    25         giet_tty_printf( "*** &mwmr_in = %x\n\n", (unsigned int)mwmr );
    26         giet_exit();
    27     }
     22    giet_tty_printf( "*** Starting task producer on processor[%d,%d,%d] at cycle %d\n\n",
     23                      x, y, lpid, giet_proctime() );
     24
     25    giet_vobj_get_vbase( "router" ,
     26                         "mwmr_in",
     27                         (void*)&mwmr );
    2828
    2929    // main loop : display token value = source index
     
    3535    }
    3636
    37     giet_tty_printf( "\n*** Completing producer task at cycle %d ***\n", giet_proctime());
    38     giet_exit();
     37    giet_exit( "Producer task completed");
    3938
    4039} // end producer()
     
    4746    mwmr_channel_t*     mwmr;
    4847
    49     giet_tty_printf( "*** Starting task consumer on processor %d", giet_procid() );
    50     giet_tty_printf( " at cycle %d ***\n\n", giet_proctime() );
     48    unsigned int    procid     = giet_procid();
     49    unsigned int    cluster_xy = procid/NB_PROCS_MAX;
     50    unsigned int    lpid       = procid%NB_PROCS_MAX;
     51    unsigned int    x          = cluster_xy >> Y_WIDTH;
     52    unsigned int    y          = cluster_xy & ((1<<Y_WIDTH)-1);
    5153
    52     if ( giet_vobj_get_vbase( "router" ,
    53                               "mwmr_out",
    54                               VOBJ_TYPE_MWMR,
    55                               (void*)&mwmr ) )
    56     {
    57         giet_tty_printf( "\n[ERROR] in consumer task :\n");
    58         giet_tty_printf( "          undefined <mwmr_out> channel\n");
    59         giet_exit();
    60     }
     54    giet_tty_printf( "*** Starting task consumer on processor[%d,%d,%d] at cycle %d\n\n",
     55                      x, y, lpid, giet_proctime() );
     56
     57    giet_vobj_get_vbase( "router" ,
     58                         "mwmr_out",
     59                         (void*)&mwmr );
    6160
    6261    // main loop : display token arrival index and value
     
    6766    }
    6867
    69     giet_tty_printf( "\n*** Completing consumer task at cycle %d ***\n", giet_proctime());
    70     giet_exit();
     68    giet_exit( "Consumer task completed");
    7169
    7270} // end consumer()
     
    7674{
    7775    unsigned int        buf;
    78     unsigned int        x;
     76    unsigned int        n;
    7977    unsigned int        tempo;
    8078    mwmr_channel_t*     mwmr_in ;
    8179    mwmr_channel_t* mwmr_out ;
    8280
    83    
    84     giet_tty_printf( "*** Starting task router on processor %d", giet_procid() );
    85     giet_tty_printf( " at cycle %d ***\n\n", giet_proctime() );
     81    unsigned int    procid     = giet_procid();
     82    unsigned int    cluster_xy = procid/NB_PROCS_MAX;
     83    unsigned int    lpid       = procid%NB_PROCS_MAX;
     84    unsigned int    x          = cluster_xy >> Y_WIDTH;
     85    unsigned int    y          = cluster_xy & ((1<<Y_WIDTH)-1);
    8686
    87     if ( giet_vobj_get_vbase( "router" ,
    88                               "mwmr_out",
    89                               VOBJ_TYPE_MWMR,
    90                               (void*)&mwmr_out ) )
    91     {
    92         giet_tty_printf( "\n[ERROR] in router task :\n");
    93         giet_tty_printf( "          undefined <mwmr_in> channel\n");
    94         giet_exit();
    95     }
     87    giet_tty_printf( "*** Starting task router on processor[%d,%d,%d] at cycle %d\n\n",
     88                      x, y, lpid, giet_proctime() );
    9689
    97     if (  giet_vobj_get_vbase( "router" ,
    98                                "mwmr_in",
    99                                VOBJ_TYPE_MWMR,
    100                                (void*)&mwmr_in ) )
    101     {
    102         giet_tty_printf( "\n[ERROR] in router task :\n");
    103         giet_tty_printf( "          undefined <mwmr_out> channel\n");
    104         giet_exit();
    105     }
     90    giet_vobj_get_vbase( "router" ,
     91                         "mwmr_out",
     92                         (void*)&mwmr_out );
    10693
     94    giet_vobj_get_vbase( "router" ,
     95                         "mwmr_in",
     96                         (void*)&mwmr_in );
    10797    // main loop
    10898    while(1)
     
    110100        mwmr_read( mwmr_in , &buf , 1 );
    111101        tempo = giet_rand() >> 6;
    112         for ( x = 0 ; x < tempo ; x++ ) asm volatile ("");
     102        for ( n = 0 ; n < tempo ; n++ ) asm volatile ("");
    113103        giet_tty_printf( "token value : %d / temporisation = %d\n", buf, tempo);
    114104        mwmr_write( mwmr_out, &buf , 1 );
  • soft/giet_vm/sort/main.c

    r292 r295  
    11///////////////////////////////////////////////////////////////////////////////
    2 // File :
    3 //     
    4 //      main.c
    5 //
    6 // Date :
    7 //     
    8 //      November 2013
    9 //
    10 // Author :
    11 //
    12 //      Cesar Fuguet Tortolero <cesar.fuguet-tortolero@lip6.fr>
     2// File   :  main.c
     3// Date   :  November 2013
     4// Author :  Cesar Fuguet Tortolero <cesar.fuguet-tortolero@lip6.fr>
    135//
    146// Description :
     
    3830#include "barrier.h"
    3931
    40 #define ARRAY_LENGTH    2048
     32#define ARRAY_LENGTH    512
    4133#define IPT             (ARRAY_LENGTH / *nb_thread) // ITEMS PER THREAD
    4234
     
    4739#define VERBOSE         1
    4840
    49 ///////////////////////////////////////////////////////////////////////
     41////////////////////////////////////////////////////////////////////////////////
    5042// Define printf according to verbosity option and number of available
    5143// TTY
    5244
    5345#if (VERBOSE == 1)
    54 #   define printf(...)     giet_tty_printf(__VA_ARGS__)
    55 #   define puts(...)       giet_tty_puts(__VA_ARGS__)
     46#   define printf(...)     giet_shr_printf(__VA_ARGS__)
    5647#else       // VERBOSE == 0
    5748#   define printf(...)
    58 #   define puts(...)
    5949#endif
    6050
    61 #define task0_printf(...) if(thread_id == 0) giet_tty_printf(__VA_ARGS__)
     51#define task0_printf(...) if(thread_id == 0) giet_shr_printf(__VA_ARGS__)
    6252
    6353#define exit    giet_exit
     
    8979giet_barrier_t barrier[8];
    9080
     81//////////////////////////////////////////
    9182__attribute__ ((constructor)) void sort()
    9283{
     
    10091    unsigned int time_end;   
    10192
    102     if( giet_vobj_get_vbase( "sort" ,
    103                              "nb_thread",
    104                              VOBJ_TYPE_CONST,
    105                              (unsigned int*)&nb_thread ) )
    106     {
    107         printf( "\n[ERROR] in sort task :\n");
    108         printf( "          undefined <nb_thread> constant: %d\n", nb_thread);
    109         exit();
    110     }   
     93    giet_vobj_get_vbase( "sort" ,
     94                         "nb_thread",
     95                         (unsigned int*)&nb_thread );
    11196   
    112     task0_printf("[Thread 0 ] Starting sort application with %d threads "
     97    task0_printf("\n[ Thread 0 ] Starting sort application with %d threads "
    11398                 "at cycle %d\n", *nb_thread, time_start);
    11499
     
    141126    // Parallel sort of array elements
    142127
    143     printf("[ Thread %d ] Stage 0: Processor Sorting...\n\r", thread_id);
     128    printf("[ Thread %d ] Stage 0: Sorting...\n\r", thread_id);
    144129
    145130    bubbleSort(array0, IPT, IPT * thread_id);
     
    154139        if((thread_id % (2 << i)) != 0)
    155140        {
    156             printf("[ Thread %d ] Quits\n\r", thread_id);
    157             exit();
    158         }
    159 
    160         printf("[ Thread %d ] Stage %d: Starting...\n\r", thread_id, i+1);
     141            printf("[ Thread %d ] Quit\n\r", thread_id );
     142            exit("Completed");
     143        }
     144
     145        printf("[ Thread %d ] Stage %d: Sorting...\n\r", thread_id, i+1);
    161146
    162147        if((i % 2) == 0)
     
    203188
    204189        time_end = giet_proctime();
     190
    205191        printf("[ Thread 0 ] Finishing sort application at cycle %d\n"
    206192               "[ Thread 0 ] Time elapsed = %d\n",
     
    209195        if (success)
    210196        {
    211 
    212             printf("[ Thread 0 ] Success!!\n\r");
     197            exit("!!! Success !!!");
    213198        }
    214199        else
    215200        {
    216             printf("[ Thread 0 ] Failure!! Incorrect element: %d\n\r", failure_index);
    217 
    218 
     201            printf("[ Thread 0 ] Failure!! Incorrect element: %d\n\r",
     202                   failure_index);
    219203            for(i=0; i<ARRAY_LENGTH; i++)
    220204            {
    221205                printf("array[%d] = %d\n", i, dst_array[i]);
    222206            }
    223         }
    224     }
    225 
    226     exit();
     207            exit("!!!  Failure !!!");
     208        }
     209    }
     210    exit("Completed");
    227211}
    228212
    229 void bubbleSort(
    230         int * array,
    231         unsigned int length,
    232         unsigned int init_pos)
     213////////////////////////////////////
     214void bubbleSort( int *        array,
     215                 unsigned int length,
     216                 unsigned int init_pos )
    233217{
    234218    int i;
     
    250234}
    251235
     236/////////////
    252237void merge(
    253238        int * array,
Note: See TracChangeset for help on using the changeset viewer.