Changeset 238 for soft


Ignore:
Timestamp:
May 29, 2013, 1:24:09 AM (12 years ago)
Author:
alain
Message:

Major evolution to support physical addresses larger than 32 bits.
The map.xml format has been modified: the vsegs associated to schedulers
are now explicitely defined and mapped in the page tables.

Location:
soft/giet_vm
Files:
1 added
33 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/Makefile

    r232 r238  
    55DU = mipsel-unknown-elf-objdump
    66
    7 MAP_XML      = mappings/4c_1p_four.xml
     7MAP_XML      = mappings/4c_1p_40.xml
    88
    99SYS_OBJS     = build/sys/vm_handler.o \
  • soft/giet_vm/boot/boot_init.c

    r236 r238  
    77// The boot_init.c file is part of the GIET-VM nano-kernel.
    88// This code is executed in the boot phase by proc[0] to initialize the
    9 //  peripherals and the kernel data structures:
     9// peripherals and the kernel data structures:
    1010// - pages tables for the various vspaces
    1111// - shedulers for processors (including the tasks contexts and interrupt vectors)
     12//
     13// This nano-kernel has been written for the MIPS32 processor.
     14// The virtual adresses are on 32 bits and use the (unsigned int) type, but the
     15// physicals addresses can have up to 40 bits, and use the  (unsigned long long) type.
    1216//
    1317// The GIET-VM uses the paged virtual memory and the MAPPING_INFO binary file
     
    2024// The MAPPING_INFO binary data structure must be loaded in the the seg_boot_mapping
    2125// segment (at address seg_mapping_base).
    22 // This MAPPING_INFO data structure defines both the hardware architecture
    23 // and the mapping:
    24 // - physical segmentation of the physical address space,
    25 // - virtual spaces definition (one multi-task application per vspace),
    26 // - placement of virtual objects (vobj) in the virtual segments (vseg).
    27 // - placement of virtual segments (vseg) in the physical segments (pseg).
    28 // - placement of tasks on the processors,
     26// This MAPPING_INFO data structure defines
     27// - the hardware architecture: number of clusters, number or processors,
     28//   size of the memory segments, and peripherals in each cluster.
     29// - The structure of the various multi-threaded software applications:
     30//   number of tasks, communication channels.
     31// - The mapping: placement of virtual objects (vobj) in the virtual segments (vseg),
     32//   placement of virtual segments (vseg) in the physical segments (pseg), placement
     33//   of software tasks on the processors,
    2934//
    3035// The page table are statically build in the boot phase, and they do not
     
    3540// The max number of virtual spaces (GIET_NB_VSPACE_MAX) is a configuration parameter.
    3641//
    37 // Each page table (one page table per virtual space) is monolithic, and
    38 // contains one PT1 and (GIET_NB_PT2_MAX) PT2s. The PT1 is addressed using the ix1 field
     42// Each page table (one page table per virtual space) is monolithic, and contains
     43// one PT1 and up to (GIET_NB_PT2_MAX) PT2s. The PT1 is addressed using the ix1 field
    3944// (11 bits) of the VPN, and the selected PT2 is addressed using the ix2 field (9 bits).
    40 // - PT1[2048] : a first 8K aligned array of unsigned int, indexed by the (ix1) field of VPN.
     45// - PT1[2048] : a first 8K aligned array of unsigned int, indexed by (ix1) field of VPN.
    4146//   Each entry in the PT1 contains a 32 bits PTD. The MSB bit PTD[31] is
    4247//   the PTD valid bit, and LSB bits PTD[19:0] are the 20 MSB bits of the physical base
     
    4449//   The PT1 contains 2048 PTD of 4 bytes => 8K bytes.
    4550// - PT2[1024][GIET_NB_PT2_MAX] : an array of array of unsigned int.
    46 //   Each PT2[1024] must be 4K aligned,  and each entry in a PT2 contains two unsigned int:
     51//   Each PT2[1024] must be 4K aligned, each entry in a PT2 contains two unsigned int:
    4752//   the first word contains the protection flags, and the second word contains the PPN.
    4853//   Each PT2 contains 512 PTE2 of 8bytes => 4K bytes.
     
    6469#include <stdarg.h>
    6570
    66 
    6771#if !defined(NB_CLUSTERS)
    6872# error The NB_CLUSTERS value must be defined in the 'giet_config.h' file !
     
    7983////////////////////////////////////////////////////////////////////////////
    8084//      Global variables for boot code
    81 // As both the page tables and the schedulers are physically distributed,
    82 // these global variables are just arrays of pointers.
     85// Both the page tables for the various virtual spaces, and the schedulers
     86// for the processors are physically distributed on the clusters.
     87// These global variables are just arrays of pointers.
    8388////////////////////////////////////////////////////////////////////////////
    8489
    85 // Page table pointers array
    86 page_table_t * boot_ptabs_vaddr[GIET_NB_VSPACE_MAX];
    87 page_table_t * boot_ptabs_paddr[GIET_NB_VSPACE_MAX];
    88 
    89 // Scheduler pointers array
    90 static_scheduler_t * boot_schedulers_paddr[NB_CLUSTERS * NB_PROCS_MAX];
     90// Page table addresses arrays
     91paddr_t      boot_ptabs_paddr[GIET_NB_VSPACE_MAX];
     92unsigned int boot_ptabs_vaddr[GIET_NB_VSPACE_MAX];
     93
     94// Scheduler pointers array (virtual addresses)
     95static_scheduler_t* boot_schedulers[NB_CLUSTERS * NB_PROCS_MAX];
    9196
    9297// Next free PT2 index array
     
    102107// boot_procid()
    103108//////////////////////////////////////////////////////////////////////////////
    104 inline unsigned int boot_procid() {
     109inline unsigned int boot_procid()
     110{
    105111    unsigned int ret;
    106112    asm volatile ("mfc0 %0, $15, 1":"=r" (ret));
     
    108114}
    109115
    110 
    111116//////////////////////////////////////////////////////////////////////////////
    112117// boot_proctime()
    113118//////////////////////////////////////////////////////////////////////////////
    114 inline unsigned int boot_proctime() {
     119inline unsigned int boot_proctime()
     120{
    115121    unsigned int ret;
    116122    asm volatile ("mfc0 %0, $9":"=r" (ret));
     
    118124}
    119125
    120 
    121126//////////////////////////////////////////////////////////////////////////////
    122127// boot_exit()
    123128//////////////////////////////////////////////////////////////////////////////
    124 void boot_exit() {
    125     while (1) {
    126         asm volatile ("nop");
    127     }
    128 }
    129 
     129void boot_exit()
     130{
     131    while (1) { asm volatile ("nop"); }
     132}
    130133
    131134//////////////////////////////////////////////////////////////////////////////
     
    134137// in all task contexts (when the task has never been executed.
    135138/////////////////////////////////"/////////////////////////////////////////////
    136 void boot_eret() {
     139void boot_eret()
     140{
    137141    asm volatile ("eret");
    138142}
    139143
    140 
    141 //////////////////////////////////////////////////////////////////////////////
    142 // boot_scheduler_set_context()
    143 // This function set a context slot in a scheduler, after a temporary
    144 // desactivation of the DTLB (because we use the scheduler physical address).
    145 // - gpid   : global processor/scheduler index
    146 // - ltid   : local task index
    147 // - slotid : context slot index
    148 // - value  : value to be written
    149 //////////////////////////////////////////////////////////////////////////////
    150 inline void boot_scheduler_set_context(unsigned int gpid,
    151         unsigned int ltid,
    152         unsigned int slotid,
    153         unsigned int value) {
    154     // get scheduler physical address
    155     static_scheduler_t * psched = boot_schedulers_paddr[gpid];
    156 
    157     // get slot physical address
    158     unsigned int * pslot = &(psched->context[ltid][slotid]);
    159 
    160     asm volatile ("li      $26,    0xB     \n"
    161             "mtc2    $26,    $1      \n"    /* desactivate DTLB */
    162             "sw      %1,     0(%0)   \n"    /* *pslot <= value  */
    163             "li      $26,    0xF     \n"
    164             "mtc2    $26,    $1      \n"    /* activate DTLB    */
     144////////////////////////////////////////////////////////////////////////////
     145// boot_physical_read()
     146// This function makes a physical read access to a 32 bits word in memory,
     147// after a temporary DTLB de-activation and paddr extension.
     148////////////////////////////////////////////////////////////////////////////
     149unsigned int boot_physical_read(paddr_t paddr)
     150{
     151    unsigned int value;
     152    unsigned int lsb = (unsigned int)paddr;
     153    unsigned int msb = (unsigned int)(paddr >> 32);
     154
     155    asm volatile(
     156            "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE   */
     157            "andi   $3,     $2,        0xb     \n"
     158            "mtc2   $3,     $1                 \n"     /* DTLB off         */   
     159
     160            "mtc2   %2,     $24                \n"     /* PADDR_EXT <= msb */   
     161            "lw     %0,     0(%1)              \n"     /* value <= *paddr  */
     162            "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0   */   
     163
     164            "mtc2   $2,     $1                 \n"     /* restore MMU_MODE */
     165            : "=r" (value)
     166            : "r" (lsb), "r" (msb)
     167            : "$2", "$3");
     168    return value;
     169}
     170
     171////////////////////////////////////////////////////////////////////////////
     172// boot_physical_write()
     173// This function makes a physical write access to a 32 bits word in memory,
     174// after a temporary DTLB de-activation and paddr extension.
     175////////////////////////////////////////////////////////////////////////////
     176void boot_physical_write(paddr_t      paddr,
     177                         unsigned int value)
     178{
     179    unsigned int lsb = (unsigned int)paddr;
     180    unsigned int msb = (unsigned int)(paddr >> 32);
     181
     182    asm volatile(
     183            "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE   */
     184            "andi   $3,     $2,        0xb     \n"
     185            "mtc2   $3,     $1                 \n"     /* DTLB off         */   
     186
     187            "mtc2   %2,     $24                \n"     /* PADDR_EXT <= msb */   
     188            "sw     %0,     0(%1)              \n"     /* *paddr <= value  */
     189            "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0   */   
     190
     191            "mtc2   $2,     $1                 \n"     /* restore MMU_MODE */
    165192            :
    166             :"r" (pslot), "r"(value)
    167             :"$26");
    168 }
    169 
    170 
    171 //////////////////////////////////////////////////////////////////////////////
    172 // boot_scheduler_set_itvector()
    173 // This function set an interrupt vector slot in a scheduler, after a temporary
    174 // desactivation of the DTLB (because we use the scheduler physical address).
    175 // - gpid   : global processor/scheduler index
    176 // - slotid : context slot index
    177 // - value  : value to be written
    178 //////////////////////////////////////////////////////////////////////////////
    179 inline void boot_scheduler_set_itvector(unsigned int gpid,
    180         unsigned int slotid,
    181         unsigned int value) {
    182     // get scheduler physical address
    183     static_scheduler_t * psched = boot_schedulers_paddr[gpid];
    184 
    185     // get slot physical address
    186     unsigned int * pslot = &(psched->interrupt_vector[slotid]);
    187 
    188     asm volatile ("li      $26,    0xB     \n"
    189             "mtc2    $26,    $1      \n"    /* desactivate DTLB */
    190             "sw      %1,     0(%0)   \n"    /* *pslot <= value  */
    191             "li      $26,    0xF     \n"
    192             "mtc2    $26,    $1      \n"    /* activate DTLB    */
    193             :
    194             :"r" (pslot), "r"(value)
    195             :"$26");
    196 }
    197 
    198 
    199 //////////////////////////////////////////////////////////////////////////////
    200 // boot_scheduler_get_itvector()
    201 // This function get an interrupt vector slot in a scheduler, after a temporary
    202 // desactivation of the DTLB (because we use the scheduler physical address).
    203 // - gpid   : global processor/scheduler index
    204 // - slotid : context slot index
    205 // - return the content of the slot
    206 //////////////////////////////////////////////////////////////////////////////
    207 unsigned int boot_scheduler_get_itvector(unsigned int gpid, unsigned int slotid) {
    208     unsigned int value;
    209 
    210     // get scheduler physical address
    211     static_scheduler_t * psched = boot_schedulers_paddr[gpid];
    212 
    213     // get slot physical address
    214     unsigned int * pslot = &(psched->interrupt_vector[slotid]);
    215 
    216     asm volatile ("li      $26,    0xB     \n"
    217             "mtc2    $26,    $1      \n"    /* desactivate DTLB */
    218             "lw      %0,     0(%1)   \n"    /* *pslot <= value  */
    219             "li      $26,    0xF     \n"
    220             "mtc2    $26,    $1      \n"    /* activate DTLB    */
    221             :"=r" (value)
    222             :"r"(pslot)
    223             :"$26");
    224     return value;
    225 }
    226 
    227 
    228 //////////////////////////////////////////////////////////////////////////////
    229 // boot_scheduler_get_tasks()
    230 // This function returns the "tasks" field of a scheduler, after temporary
    231 // desactivation of the DTLB (because we use the scheduler physical address).
    232 // - gpid   : global processor/scheduler index
    233 //////////////////////////////////////////////////////////////////////////////
    234 inline unsigned int boot_scheduler_get_tasks(unsigned int gpid) {
    235     unsigned int ret;
    236 
    237     // get scheduler physical address
    238     static_scheduler_t * psched = boot_schedulers_paddr[gpid];
    239 
    240     // get tasks physical address
    241     unsigned int * ptasks = &(psched->tasks);
    242 
    243     asm volatile ("li      $26,    0xB     \n"
    244             "mtc2    $26,    $1      \n"    /* desactivate DTLB */
    245             "lw      %0,     0(%1)   \n"    /* ret <= *ptasks   */
    246             "li      $26,    0xF     \n"
    247             "mtc2    $26,    $1      \n"    /* activate DTLB    */
    248             :"=r" (ret)
    249             :"r"(ptasks)
    250             :"$26");
    251     return ret;
    252 }
    253 
    254 
    255 //////////////////////////////////////////////////////////////////////////////
    256 // boot_scheduler_set_tasks()
    257 // This function set the "tasks" field of a scheduler, after temporary
    258 // desactivation of the DTLB (because we use the scheduler physical address).
    259 // - gpid   : global processor/scheduler index
    260 // - value  : value to be written
    261 //////////////////////////////////////////////////////////////////////////////
    262 inline void boot_scheduler_set_tasks(unsigned int gpid, unsigned int value) {
    263     // get scheduler physical address
    264     static_scheduler_t * psched = boot_schedulers_paddr[gpid];
    265 
    266     // get tasks physical address
    267     unsigned int * ptasks = &(psched->tasks);
    268 
    269     asm volatile ("li      $26,    0xB     \n"
    270             "mtc2    $26,    $1      \n"    /* desactivate DTLB */
    271             "sw      %1,     0(%0)   \n"    /* *ptasks <= value */
    272             "li      $26,    0xF     \n"
    273             "mtc2    $26,    $1      \n"    /* activate DTLB    */
    274             :
    275             :"r" (ptasks), "r"(value)
    276             :"$26");
    277 }
    278 
    279 
    280 //////////////////////////////////////////////////////////////////////////////
    281 // boot_scheduler_set_current()
    282 // This function set the "current" field of a scheduler, after temporary
    283 // desactivation of the DTLB (because we use the scheduler physical address).
    284 // - gpid   : global processor/scheduler index
    285 // - value  : value to be written
    286 //////////////////////////////////////////////////////////////////////////////
    287 inline void boot_scheduler_set_current(unsigned int gpid, unsigned int value) {
    288     // get scheduler physical address
    289     static_scheduler_t *psched = boot_schedulers_paddr[gpid];
    290 
    291     // get tasks physical address
    292     unsigned int * pcur = &(psched->current);
    293 
    294     asm volatile ("li      $26,    0xB     \n"
    295             "mtc2    $26,    $1      \n"    /* desactivate DTLB */
    296             "sw      %1,     0(%0)   \n"    /* *pcur   <= value */
    297             "li      $26,    0xF     \n"
    298             "mtc2    $26,    $1      \n"    /* activate DTLB    */
    299             :
    300             :"r" (pcur), "r"(value)
    301             :"$26");
    302 }
    303 
     193            : "r" (value), "r" (lsb), "r" (msb)
     194            : "$2", "$3");
     195}
    304196
    305197//////////////////////////////////////////////////////////////////////////////
     
    307199// This function set a new value for the MMU PTPR register.
    308200//////////////////////////////////////////////////////////////////////////////
    309 inline void boot_set_mmu_ptpr(unsigned int val) {
     201inline void boot_set_mmu_ptpr(unsigned int val)
     202{
    310203    asm volatile ("mtc2  %0, $0"::"r" (val));
    311204}
    312 
    313205
    314206//////////////////////////////////////////////////////////////////////////////
     
    316208// This function set a new value for the MMU MODE register.
    317209//////////////////////////////////////////////////////////////////////////////
    318 inline void boot_set_mmu_mode(unsigned int val) {
     210inline void boot_set_mmu_mode(unsigned int val)
     211{
    319212    asm volatile ("mtc2  %0, $1"::"r" (val));
    320213}
    321 
    322214
    323215////////////////////////////////////////////////////////////////////////////
    324216// boot_puts()
    325 // (it uses TTY0)
     217// display a string on TTY0
    326218////////////////////////////////////////////////////////////////////////////
    327 void boot_puts(const char * buffer) {
     219void boot_puts(const char * buffer)
     220{
    328221    unsigned int *tty_address = (unsigned int *) &seg_tty_base;
    329222    unsigned int n;
    330223
    331     for (n = 0; n < 100; n++) {
    332         if (buffer[n] == 0) {
    333             break;
    334         }
     224    for (n = 0; n < 100; n++)
     225    {
     226        if (buffer[n] == 0)  break;
    335227        tty_address[TTY_WRITE] = (unsigned int) buffer[n];
    336228    }
    337229}
    338 
    339230
    340231////////////////////////////////////////////////////////////////////////////
    341232// boot_putx()
    342 // (it uses TTY0)
     233// display a 32 bits unsigned int as an hexadecimal string on TTY0
    343234////////////////////////////////////////////////////////////////////////////
    344 void boot_putx(unsigned int val) {
     235void boot_putx(unsigned int val)
     236{
    345237    static const char HexaTab[] = "0123456789ABCDEF";
    346238    char buf[11];
     
    351243    buf[10] = 0;
    352244
    353     for (c = 0; c < 8; c++) {
     245    for (c = 0; c < 8; c++)
     246    {
    354247        buf[9 - c] = HexaTab[val & 0xF];
    355248        val = val >> 4;
     
    358251}
    359252
     253////////////////////////////////////////////////////////////////////////////
     254// boot_putl()
     255// display a 64 bits unsigned long as an hexadecimal string on TTY0
     256////////////////////////////////////////////////////////////////////////////
     257void boot_putl(paddr_t val)
     258{
     259    static const char HexaTab[] = "0123456789ABCDEF";
     260    char buf[19];
     261    unsigned int c;
     262
     263    buf[0] = '0';
     264    buf[1] = 'x';
     265    buf[18] = 0;
     266
     267    for (c = 0; c < 16; c++)
     268    {
     269        buf[17 - c] = HexaTab[(unsigned int)val & 0xF];
     270        val = val >> 4;
     271    }
     272    boot_puts(buf);
     273}
    360274
    361275////////////////////////////////////////////////////////////////////////////
    362276// boot_putd()
    363 // (it uses TTY0)
     277// display a 32 bits unsigned int as a decimal string on TTY0
    364278////////////////////////////////////////////////////////////////////////////
    365 void boot_putd(unsigned int val) {
     279void boot_putd(unsigned int val)
     280{
    366281    static const char DecTab[] = "0123456789";
    367282    char buf[11];
     
    371286    buf[10] = 0;
    372287
    373     for (i = 0; i < 10; i++) {
    374         if ((val != 0) || (i == 0)) {
     288    for (i = 0; i < 10; i++)
     289    {
     290        if ((val != 0) || (i == 0))
     291        {
    375292            buf[9 - i] = DecTab[val % 10];
    376293            first = 9 - i;
    377294        }
    378         else {
     295        else
     296        {
    379297            break;
    380298        }
     
    384302}
    385303
    386 
    387304/////////////////////////////////////////////////////////////////////////////
    388305//  mapping_info data structure access functions
    389306/////////////////////////////////////////////////////////////////////////////
    390 inline mapping_cluster_t *boot_get_cluster_base(mapping_header_t * header) {
     307inline mapping_cluster_t *boot_get_cluster_base(mapping_header_t * header)
     308{
    391309    return (mapping_cluster_t *) ((char *) header + MAPPING_HEADER_SIZE);
    392310}
    393 
    394 
    395311/////////////////////////////////////////////////////////////////////////////
    396 inline mapping_pseg_t *boot_get_pseg_base(mapping_header_t * header) {
     312inline mapping_pseg_t *boot_get_pseg_base(mapping_header_t * header)
     313{
    397314    return (mapping_pseg_t *) ((char *) header +
    398315            MAPPING_HEADER_SIZE +
    399316            MAPPING_CLUSTER_SIZE * header->clusters);
    400317}
    401 
    402 
    403318/////////////////////////////////////////////////////////////////////////////
    404 inline mapping_vspace_t *boot_get_vspace_base(mapping_header_t * header) {
     319inline mapping_vspace_t *boot_get_vspace_base(mapping_header_t * header)
     320{
    405321    return (mapping_vspace_t *) ((char *) header +
    406322            MAPPING_HEADER_SIZE +
     
    408324            MAPPING_PSEG_SIZE * header->psegs);
    409325}
    410 
    411 
    412326/////////////////////////////////////////////////////////////////////////////
    413 inline mapping_vseg_t *boot_get_vseg_base(mapping_header_t * header) {
     327inline mapping_vseg_t *boot_get_vseg_base(mapping_header_t * header)
     328{
    414329    return (mapping_vseg_t *) ((char *) header +
    415330            MAPPING_HEADER_SIZE +
     
    418333            MAPPING_VSPACE_SIZE * header->vspaces);
    419334}
    420 
    421 
    422335/////////////////////////////////////////////////////////////////////////////
    423 inline mapping_vobj_t *boot_get_vobj_base(mapping_header_t * header) {
     336inline mapping_vobj_t *boot_get_vobj_base(mapping_header_t * header)
     337{
    424338    return (mapping_vobj_t *) ((char *) header +
    425339            MAPPING_HEADER_SIZE +
     
    429343            MAPPING_VSEG_SIZE * header->vsegs);
    430344}
    431 
    432 
    433345/////////////////////////////////////////////////////////////////////////////
    434 inline mapping_task_t *boot_get_task_base(mapping_header_t * header) {
     346inline mapping_task_t *boot_get_task_base(mapping_header_t * header)
     347{
    435348    return (mapping_task_t *) ((char *) header +
    436349            MAPPING_HEADER_SIZE +
     
    441354            MAPPING_VOBJ_SIZE * header->vobjs);
    442355}
    443 
    444 
    445356/////////////////////////////////////////////////////////////////////////////
    446 inline mapping_proc_t *boot_get_proc_base(mapping_header_t * header) {
     357inline mapping_proc_t *boot_get_proc_base(mapping_header_t * header)
     358{
    447359    return (mapping_proc_t *) ((char *) header +
    448360            MAPPING_HEADER_SIZE +
     
    454366            MAPPING_TASK_SIZE * header->tasks);
    455367}
    456 
    457 
    458368/////////////////////////////////////////////////////////////////////////////
    459 inline mapping_irq_t *boot_get_irq_base(mapping_header_t * header) {
     369inline mapping_irq_t *boot_get_irq_base(mapping_header_t * header)
     370{
    460371    return (mapping_irq_t *) ((char *) header +
    461372            MAPPING_HEADER_SIZE +
     
    468379            MAPPING_PROC_SIZE * header->procs);
    469380}
    470 
    471 
    472381/////////////////////////////////////////////////////////////////////////////
    473 inline mapping_coproc_t *boot_get_coproc_base(mapping_header_t * header) {
     382inline mapping_coproc_t *boot_get_coproc_base(mapping_header_t * header)
     383{
    474384    return (mapping_coproc_t *) ((char *) header +
    475385            MAPPING_HEADER_SIZE +
     
    483393            MAPPING_IRQ_SIZE * header->irqs);
    484394}
    485 
    486 
    487395///////////////////////////////////////////////////////////////////////////////////
    488 inline mapping_cp_port_t *boot_get_cp_port_base(mapping_header_t * header) {
     396inline mapping_cp_port_t *boot_get_cp_port_base(mapping_header_t * header)
     397{
    489398    return (mapping_cp_port_t *) ((char *) header +
    490399            MAPPING_HEADER_SIZE +
     
    499408            MAPPING_COPROC_SIZE * header->coprocs);
    500409}
    501 
    502 
    503410///////////////////////////////////////////////////////////////////////////////////
    504 inline mapping_periph_t *boot_get_periph_base(mapping_header_t * header) {
     411inline mapping_periph_t *boot_get_periph_base(mapping_header_t * header)
     412{
    505413    return (mapping_periph_t *) ((char *) header +
    506414            MAPPING_HEADER_SIZE +
     
    517425}
    518426
    519 
    520427//////////////////////////////////////////////////////////////////////////////
    521428//     boot_pseg_get()
     
    523430// identified  by the pseg index.
    524431//////////////////////////////////////////////////////////////////////////////
    525 mapping_pseg_t *boot_pseg_get(unsigned int seg_id) {
     432mapping_pseg_t *boot_pseg_get(unsigned int seg_id)
     433{
    526434    mapping_header_t * header = (mapping_header_t *) & seg_mapping_base;
    527435    mapping_pseg_t * pseg = boot_get_pseg_base(header);
    528436
    529437    // checking argument
    530     if (seg_id >= header->psegs) {
     438    if (seg_id >= header->psegs)
     439    {
    531440        boot_puts("\n[BOOT ERROR] : seg_id argument too large\n");
    532441        boot_puts("               in function boot_pseg_get()\n");
     
    535444
    536445    return &pseg[seg_id];
    537 }                // end boot_pseg_get()
    538 
     446
    539447
    540448//////////////////////////////////////////////////////////////////////////////
    541449// boot_add_pte()
    542 // This function registers a new PTE in the page table pointed
     450// This function registers a new PTE in the page table defined
    543451// by the vspace_id argument, and updates both PT1 and PT2.
    544452// A new PT2 is used when required.
    545453// As the set of PT2s is implemented as a fixed size array (no dynamic
    546454// allocation), this function checks a possible overflow of the PT2 array.
    547 //
    548 // The global parameter is a boolean indicating wether a global vseg is
    549 // being mapped.
    550455//////////////////////////////////////////////////////////////////////////////
    551456void boot_add_pte(unsigned int vspace_id,
    552         unsigned int vpn, unsigned int flags, unsigned int ppn) {
     457                  unsigned int vpn,
     458                  unsigned int flags,
     459                  unsigned int ppn,
     460                  unsigned int verbose)
     461{
    553462    unsigned int ix1;
    554463    unsigned int ix2;
    555     unsigned int ptba;      // PT2 base address
    556     unsigned int pt2_id;    // PT2 index
    557     unsigned int *pt_flags; // pointer on the pte_flags = &PT2[2*ix2]   
    558     unsigned int *pt_ppn;   // pointer on the pte_ppn   = &PT2[2*ix2+1] 
     464    paddr_t      pt1_pbase;     // PT1 physical base address
     465    paddr_t      pt2_pbase;     // PT2 physical base address
     466    paddr_t      pte_paddr;     // PTE physucal address
     467    unsigned int pt2_id;        // PT2 index
     468    unsigned int ptd;           // PTD : entry in PT1
     469    unsigned int max_pt2;       // max number of PT2s for a given vspace
    559470
    560471    ix1 = vpn >> 9;         // 11 bits
     
    562473
    563474    // check that the boot_max_pt2[vspace_id] has been set
    564     unsigned int max_pt2 = boot_max_pt2[vspace_id];
    565 
    566     if (max_pt2 == 0) {
    567         boot_puts("Unfound page table for vspace ");
     475    max_pt2 = boot_max_pt2[vspace_id];
     476
     477    if (max_pt2 == 0)
     478    {
     479        boot_puts("Undefined page table for vspace ");
    568480        boot_putd(vspace_id);
    569481        boot_puts("\n");
    570482        boot_exit();
    571483    }
    572     // get page table physical address
    573     page_table_t *pt = boot_ptabs_paddr[vspace_id];
    574 
    575     if ((pt->pt1[ix1] & PTE_V) == 0) { // set a new PTD in PT1
     484
     485    // get page table physical base address
     486    pt1_pbase = boot_ptabs_paddr[vspace_id];
     487
     488    // get ptd in PT1
     489    ptd = boot_physical_read( pt1_pbase + 4*ix1 );
     490
     491    if ((ptd & PTE_V) == 0)    // invalid PTD: compute PT2 base address,
     492                               // and set a new PTD in PT1
     493    {
    576494        pt2_id = boot_next_free_pt2[vspace_id];
    577         if (pt2_id == max_pt2) {
     495        if (pt2_id == max_pt2)
     496        {
    578497            boot_puts("\n[BOOT ERROR] in boot_add_pte() function\n");
    579498            boot_puts("the length of the ptab vobj is too small\n");
    580499            boot_exit();
    581500        }
    582         else {
    583             ptba = (unsigned int) pt + PT1_SIZE + PT2_SIZE * pt2_id;
    584             pt->pt1[ix1] = PTE_V | PTE_T | (ptba >> 12);
     501        else
     502        {
     503            pt2_pbase = pt1_pbase + PT1_SIZE + PT2_SIZE * pt2_id;
     504            ptd = PTE_V | PTE_T | (unsigned int)(pt2_pbase >> 12);
     505            boot_physical_write( pt1_pbase + 4*ix1 , ptd);
    585506            boot_next_free_pt2[vspace_id] = pt2_id + 1;
    586507        }
    587508    }
    588     else {
    589         ptba = pt->pt1[ix1] << 12;
    590     }
    591 
    592     // set PTE2
    593     pt_flags = (unsigned int *) (ptba + 8 * ix2);
    594     pt_ppn = (unsigned int *) (ptba + 8 * ix2 + 4);
    595 
    596     *pt_flags = flags;
    597     *pt_ppn = ppn;
    598 
    599 /*
    600 if ( vpn == 0x00000300)
    601 {
    602 boot_puts("vpn       = ");
    603 boot_putx( vpn );
    604 boot_puts("\n");
    605 boot_puts("pt_flags  = ");
    606 boot_putx( (unsigned int)pt_flags );
    607 boot_puts("\n");
    608 boot_puts("*pt_flags = ");
    609 boot_putx( *pt_flags );
    610 boot_puts("\n");
    611 boot_exit();
    612 }
    613 
    614     if ((*pt_flags & PTE_V) != 0) {  // page already mapped
    615         boot_puts("\n[BOOT ERROR] double mapping in vspace ");
    616         boot_putd(vspace_id);
    617         boot_puts(" for vpn = ");
    618         boot_putx(vpn);
    619         boot_puts("\n");
    620         boot_exit();
    621     }
    622 */
    623 }                // end boot_add_pte()
     509    else                       // valid PTD: compute PT2 base address
     510    {
     511        pt2_pbase = ((paddr_t)(ptd & 0x0FFFFFFF)) << 12;
     512    }
     513
     514    // set PTE in PT2 : flags & PPN in two 32 bits words
     515    pte_paddr = pt2_pbase + 8*ix2;
     516    boot_physical_write( pte_paddr     , flags);
     517    boot_physical_write( pte_paddr + 4 , ppn);
     518
     519if ( verbose )
     520{
     521boot_puts("     / pt1_pbase = ");
     522boot_putl( pt1_pbase );
     523boot_puts(" / ptd = ");
     524boot_putl( ptd );
     525boot_puts(" / pt2_pbase = ");
     526boot_putl( pt2_pbase );
     527boot_puts(" / pte_paddr = ");
     528boot_putl( pte_paddr );
     529boot_puts(" / ppn = ");
     530boot_putx( ppn );
     531boot_puts("/\n");
     532}
     533
     534}   // end boot_add_pte()
    624535
    625536
     
    627538// This function build the page table for a given vspace.
    628539// The physical base addresses for all vsegs (global and private)
    629 // must have been previously computed.
     540// must have been previously computed and stored in the mapping.
    630541// It initializes the MWMR channels.
    631542/////////////////////////////////////////////////////////////////////
    632 void boot_vspace_pt_build(unsigned int vspace_id) {
     543void boot_vspace_pt_build(unsigned int vspace_id)
     544{
    633545    unsigned int vseg_id;
    634546    unsigned int npages;
     
    637549    unsigned int flags;
    638550    unsigned int page_id;
     551    unsigned int verbose = 0;   // can be used to activate trace in add_pte()
    639552
    640553    mapping_header_t * header = (mapping_header_t *) & seg_mapping_base;
    641554    mapping_vspace_t * vspace = boot_get_vspace_base(header);
    642     mapping_vseg_t * vseg = boot_get_vseg_base(header);
     555    mapping_vseg_t   * vseg  = boot_get_vseg_base(header);
    643556
    644557    // private segments
    645558    for (vseg_id = vspace[vspace_id].vseg_offset;
    646             vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs);
    647             vseg_id++) {
     559         vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs);
     560         vseg_id++)
     561    {
    648562        vpn = vseg[vseg_id].vbase >> 12;
    649         ppn = vseg[vseg_id].pbase >> 12;
     563        ppn = (unsigned int)(vseg[vseg_id].pbase >> 12);
    650564        npages = vseg[vseg_id].length >> 12;
    651         if ((vseg[vseg_id].length & 0xFFF) != 0) {
    652             npages++;
    653         }
     565        if ((vseg[vseg_id].length & 0xFFF) != 0) npages++;
    654566
    655567        flags = PTE_V;
    656         if (vseg[vseg_id].mode & C_MODE_MASK) {
    657             flags = flags | PTE_C;
    658         }
    659         if (vseg[vseg_id].mode & X_MODE_MASK) {
    660             flags = flags | PTE_X;
    661         }
    662         if (vseg[vseg_id].mode & W_MODE_MASK) {
    663             flags = flags | PTE_W;
    664         }
    665         if (vseg[vseg_id].mode & U_MODE_MASK) {
    666             flags = flags | PTE_U;
    667         }
     568        if (vseg[vseg_id].mode & C_MODE_MASK)  flags = flags | PTE_C;
     569        if (vseg[vseg_id].mode & X_MODE_MASK)  flags = flags | PTE_X;
     570        if (vseg[vseg_id].mode & W_MODE_MASK)  flags = flags | PTE_W;
     571        if (vseg[vseg_id].mode & U_MODE_MASK)  flags = flags | PTE_U;
    668572
    669573#if BOOT_DEBUG_PT
     
    674578        boot_putd(npages);
    675579        boot_puts(" / pbase = ");
    676         boot_putx(vseg[vseg_id].pbase);
     580        boot_putl(vseg[vseg_id].pbase);
    677581        boot_puts("\n");
    678582#endif
    679583        // loop on 4K pages
    680         for (page_id = 0; page_id < npages; page_id++) {
    681             boot_add_pte(vspace_id, vpn, flags, ppn);
     584        for (page_id = 0; page_id < npages; page_id++)
     585        {
     586            boot_add_pte(vspace_id, vpn, flags, ppn, verbose);
    682587            vpn++;
    683588            ppn++;
     
    686591
    687592    // global segments
    688     for (vseg_id = 0; vseg_id < header->globals; vseg_id++) {
     593    for (vseg_id = 0; vseg_id < header->globals; vseg_id++)
     594    {
    689595        vpn = vseg[vseg_id].vbase >> 12;
    690         ppn = vseg[vseg_id].pbase >> 12;
     596        ppn = (unsigned int)(vseg[vseg_id].pbase >> 12);
    691597        npages = vseg[vseg_id].length >> 12;
    692         if ((vseg[vseg_id].length & 0xFFF) != 0) {
    693             npages++;
    694         }
     598        if ((vseg[vseg_id].length & 0xFFF) != 0) npages++;
    695599
    696600        flags = PTE_V;
    697         if (vseg[vseg_id].mode & C_MODE_MASK) {
    698             flags = flags | PTE_C;
    699         }
    700         if (vseg[vseg_id].mode & X_MODE_MASK) {
    701             flags = flags | PTE_X;
    702         }
    703         if (vseg[vseg_id].mode & W_MODE_MASK) {
    704             flags = flags | PTE_W;
    705         }
    706         if (vseg[vseg_id].mode & U_MODE_MASK) {
    707             flags = flags | PTE_U;
    708         }
     601        if (vseg[vseg_id].mode & C_MODE_MASK)  flags = flags | PTE_C;
     602        if (vseg[vseg_id].mode & X_MODE_MASK)  flags = flags | PTE_X;
     603        if (vseg[vseg_id].mode & W_MODE_MASK)  flags = flags | PTE_W;
     604        if (vseg[vseg_id].mode & U_MODE_MASK)  flags = flags | PTE_U;
    709605
    710606#if BOOT_DEBUG_PT
    711607        boot_puts(vseg[vseg_id].name);
    712         boot_puts(" / flags = ");
     608        boot_puts(" : flags = ");
    713609        boot_putx(flags);
    714610        boot_puts(" / npages = ");
    715611        boot_putd(npages);
    716612        boot_puts(" / pbase = ");
    717         boot_putx(vseg[vseg_id].pbase);
     613        boot_putl(vseg[vseg_id].pbase);
    718614        boot_puts("\n");
    719615#endif
    720616        // loop on 4K pages
    721         for (page_id = 0; page_id < npages; page_id++) {
    722             boot_add_pte(vspace_id, vpn, flags, ppn);
     617        for (page_id = 0; page_id < npages; page_id++)
     618        {
     619            boot_add_pte(vspace_id, vpn, flags, ppn, verbose);
    723620            vpn++;
    724621            ppn++;
    725622        }
    726623    }
    727 }                // end boot_vspace_pt_build()
     624}   // end boot_vspace_pt_build()
    728625
    729626
    730627///////////////////////////////////////////////////////////////////////////
    731 // Align the value "toAlign" to the required alignement indicated by
    732 // alignPow2 ( the logarithme of 2 the alignement).
     628// Align the value of paddr or vaddr to the required alignement,
     629// defined by alignPow2 == L2(alignement).
    733630///////////////////////////////////////////////////////////////////////////
    734 unsigned int align_to(unsigned int toAlign, unsigned int alignPow2) {
     631paddr_t paddr_align_to(paddr_t paddr, unsigned int alignPow2)
     632{
     633    paddr_t mask = (1 << alignPow2) - 1;
     634    return ((paddr + mask) & ~mask);
     635}
     636
     637unsigned int vaddr_align_to(unsigned int vaddr, unsigned int alignPow2)
     638{
    735639    unsigned int mask = (1 << alignPow2) - 1;
    736     return ((toAlign + mask) & ~mask);
    737 }
    738 
     640    return ((vaddr + mask) & ~mask);
     641}
    739642
    740643///////////////////////////////////////////////////////////////////////////
    741 // This function compute the physical base address for a vseg
     644// This function computes the physical base address for a vseg
    742645// as specified in the mapping info data structure.
    743646// It updates the pbase and the length fields of the vseg.
     
    747650// It is a global vseg if vspace_id = (-1).
    748651///////////////////////////////////////////////////////////////////////////
    749 void boot_vseg_map(mapping_vseg_t * vseg, unsigned int vspace_id) {
     652void boot_vseg_map(mapping_vseg_t * vseg, unsigned int vspace_id)
     653{
    750654    unsigned int vobj_id;
    751655    unsigned int cur_vaddr;
    752     unsigned int cur_paddr;
     656    paddr_t      cur_paddr;
     657    unsigned int offset;
     658
    753659    mapping_header_t * header = (mapping_header_t *) & seg_mapping_base;
    754     mapping_vobj_t * vobj = boot_get_vobj_base(header);
     660    mapping_vobj_t   * vobj  = boot_get_vobj_base(header);
    755661
    756662    // get physical segment pointer
    757     mapping_pseg_t * pseg = boot_pseg_get(vseg->psegid);
     663    mapping_pseg_t* pseg = boot_pseg_get(vseg->psegid);
    758664
    759665    // compute vseg physical base address
    760     if (vseg->ident != 0) {   // identity mapping required
     666    if (vseg->ident != 0)                   // identity mapping required
     667    {
    761668        vseg->pbase = vseg->vbase;
    762669    }
    763     else {  // unconstrained mapping
     670    else                                   // unconstrained mapping
     671    {
    764672        vseg->pbase = pseg->next_base;
    765673
    766674        // test alignment constraint
    767         if (vobj[vseg->vobj_offset].align) {
    768             vseg->pbase = align_to(vseg->pbase, vobj[vseg->vobj_offset].align);
     675        if (vobj[vseg->vobj_offset].align)
     676        {
     677            vseg->pbase = paddr_align_to(vseg->pbase, vobj[vseg->vobj_offset].align);
    769678        }
    770679    }
     
    778687    cur_paddr = vseg->pbase;
    779688
    780     for (vobj_id = vseg->vobj_offset; vobj_id < (vseg->vobj_offset + vseg->vobjs); vobj_id++) {
    781         if (vobj[vobj_id].align) {
    782             cur_paddr = align_to(cur_paddr, vobj[vobj_id].align);
    783             cur_vaddr = align_to(cur_vaddr, vobj[vobj_id].align);
     689    for (vobj_id = vseg->vobj_offset;
     690         vobj_id < (vseg->vobj_offset + vseg->vobjs); vobj_id++)
     691    {
     692        if (vobj[vobj_id].align)
     693        {
     694            cur_paddr = paddr_align_to(cur_paddr, vobj[vobj_id].align);
     695            cur_vaddr = vaddr_align_to(cur_vaddr, vobj[vobj_id].align);
    784696        }
    785697        // set vaddr/paddr for current vobj
     
    787699        vobj[vobj_id].paddr = cur_paddr;
    788700       
    789         // initialise boot_ptabs_vaddr[] if current vobj is a PTAB
    790         if (vobj[vobj_id].type == VOBJ_TYPE_PTAB) {
    791             if (vspace_id == ((unsigned int) -1)) {   // global vseg
     701        // initialise boot_ptabs_vaddr[] & boot_ptabs-paddr[] if PTAB
     702        if (vobj[vobj_id].type == VOBJ_TYPE_PTAB)
     703        {
     704            if (vspace_id == ((unsigned int) -1))    // global vseg
     705            {
    792706                boot_puts("\n[BOOT ERROR] in boot_vseg_map() function: ");
    793707                boot_puts("a PTAB vobj cannot be global");
    794708                boot_exit();
    795709            }
    796             // we need at least one PT2 => ( boot_max_pt2[vspace_id] >= 1)
    797             if (vobj[vobj_id].length < (PT1_SIZE + PT2_SIZE)) {
     710            // we need at least one PT2
     711            if (vobj[vobj_id].length < (PT1_SIZE + PT2_SIZE))
     712            {
    798713                boot_puts("\n[BOOT ERROR] in boot_vseg_map() function, ");
    799714                boot_puts("PTAB too small, minumum size is: ");
     
    802717            }
    803718            // register both physical and virtual page table address
    804             boot_ptabs_vaddr[vspace_id] = (page_table_t *) vobj[vobj_id].vaddr;
    805             boot_ptabs_paddr[vspace_id] = (page_table_t *) vobj[vobj_id].paddr;
    806 
    807             /* computing the number of second level page */
     719            boot_ptabs_vaddr[vspace_id] = vobj[vobj_id].vaddr;
     720            boot_ptabs_paddr[vspace_id] = vobj[vobj_id].paddr;
     721
     722            // reset all valid bits in PT1
     723            for ( offset = 0 ; offset < 8192 ; offset = offset + 4)
     724            {
     725                boot_physical_write( cur_paddr + offset, 0);
     726            }
     727
     728            // computing the number of second level pages
    808729            boot_max_pt2[vspace_id] = (vobj[vobj_id].length - PT1_SIZE) / PT2_SIZE;
    809730        }
     731
    810732        // set next vaddr/paddr
    811         cur_vaddr += vobj[vobj_id].length;
    812         cur_paddr += vobj[vobj_id].length;
    813 
     733        cur_vaddr = cur_vaddr + vobj[vobj_id].length;
     734        cur_paddr = cur_paddr + vobj[vobj_id].length;
    814735    } // end for vobjs
    815736
    816737    //set the vseg length
    817     vseg->length = align_to((cur_paddr - vseg->pbase), 12);
     738    vseg->length = vaddr_align_to((unsigned int)(cur_paddr - vseg->pbase), 12);
    818739
    819740    // checking pseg overflow
    820741    if ((vseg->pbase < pseg->base) ||
    821             ((vseg->pbase + vseg->length) > (pseg->base + pseg->length))) {
     742        ((vseg->pbase + vseg->length) > (pseg->base + pseg->length)))
     743    {
    822744        boot_puts("\n[BOOT ERROR] in boot_vseg_map() function\n");
    823745        boot_puts("impossible mapping for virtual segment: ");
     
    825747        boot_puts("\n");
    826748        boot_puts("vseg pbase = ");
    827         boot_putx(vseg->pbase);
     749        boot_putl(vseg->pbase);
    828750        boot_puts("\n");
    829751        boot_puts("vseg length = ");
     
    831753        boot_puts("\n");
    832754        boot_puts("pseg pbase = ");
    833         boot_putx(pseg->base);
     755        boot_putl(pseg->base);
    834756        boot_puts("\n");
    835757        boot_puts("pseg length = ");
    836         boot_putx(pseg->length);
     758        boot_putl(pseg->length);
    837759        boot_puts("\n");
    838760        boot_exit();
     
    846768    boot_putx(vseg->vbase);
    847769    boot_puts(" / pbase = ");
    848     boot_putx(vseg->pbase);
     770    boot_putl(vseg->pbase);
    849771    boot_puts("\n");
    850772#endif
    851773
    852     // set the next_base field in vseg
    853     if (vseg->ident == 0 && pseg->type != PSEG_TYPE_PERI) {
     774    // set the next_base field in pseg when it's a RAM
     775    if ( pseg->type == PSEG_TYPE_RAM )
     776    {
    854777        pseg->next_base = vseg->pbase + vseg->length;
    855778    }
    856 
    857 }                // end boot_vseg_map()
     779}    // end boot_vseg_map()
    858780
    859781/////////////////////////////////////////////////////////////////////
     
    861783// structure (soft), and the giet_config file (hard).
    862784/////////////////////////////////////////////////////////////////////
    863 void boot_check_mapping() {
     785void boot_check_mapping()
     786{
    864787    mapping_header_t * header = (mapping_header_t *) & seg_mapping_base;
    865788    mapping_cluster_t * cluster = boot_get_cluster_base(header);
     
    867790
    868791    // checking mapping availability
    869     if (header->signature != IN_MAPPING_SIGNATURE) {
     792    if (header->signature != IN_MAPPING_SIGNATURE)
     793    {
    870794        boot_puts("\n[BOOT ERROR] Illegal mapping signature: ");
    871795        boot_putx(header->signature);
     
    874798    }
    875799    // checking number of clusters
    876     if (header->clusters != NB_CLUSTERS) {
     800    if (header->clusters != NB_CLUSTERS)
     801    {
    877802        boot_puts("\n[BOOT ERROR] Incoherent NB_CLUSTERS");
    878803        boot_puts("\n             - In giet_config,  value = ");
     
    884809    }
    885810    // checking number of virtual spaces
    886     if (header->vspaces > GIET_NB_VSPACE_MAX) {
     811    if (header->vspaces > GIET_NB_VSPACE_MAX)
     812    {
    887813        boot_puts("\n[BOOT ERROR] : number of vspaces > GIET_NB_VSPACE_MAX\n");
    888814        boot_puts("\n");
     
    894820    unsigned int tty_found = 0;
    895821    unsigned int nic_found = 0;
    896     for (cluster_id = 0; cluster_id < NB_CLUSTERS; cluster_id++) {
     822    for (cluster_id = 0; cluster_id < NB_CLUSTERS; cluster_id++)
     823    {
    897824        // NB_PROCS_MAX
    898         if (cluster[cluster_id].procs > NB_PROCS_MAX) {
     825        if (cluster[cluster_id].procs > NB_PROCS_MAX)
     826        {
    899827            boot_puts("\n[BOOT ERROR] too many processors in cluster ");
    900828            boot_putd(cluster_id);
     
    907835        for (periph_id = cluster[cluster_id].periph_offset;
    908836                periph_id < cluster[cluster_id].periph_offset + cluster[cluster_id].periphs;
    909                 periph_id++) {
    910             // NB_TTYS
    911             if (periph[periph_id].type == PERIPH_TYPE_TTY) {
    912                 if (tty_found) {
     837                periph_id++)
     838        {
     839            // NB_TTY_CHANNELS
     840            if (periph[periph_id].type == PERIPH_TYPE_TTY)
     841            {
     842                if (tty_found)
     843                {
    913844                    boot_puts("\n[BOOT ERROR] TTY component should not be replicated\n");
    914845                    boot_exit();
    915846                }
    916                 if (periph[periph_id].channels > NB_TTYS) {
    917                     boot_puts("\n[BOOT ERROR] Wrong NB_TTYS in cluster ");
     847                if (periph[periph_id].channels > NB_TTY_CHANNELS)
     848                {
     849                    boot_puts("\n[BOOT ERROR] Wrong NB_TTY_CHANNELS in cluster ");
    918850                    boot_putd(cluster_id);
    919851                    boot_puts(" : ttys = ");
     
    924856                tty_found = 1;
    925857            }
    926             // NB_NICS
    927             if (periph[periph_id].type == PERIPH_TYPE_NIC) {
    928                 if (nic_found) {
     858            // NB_NIC_CHANNELS
     859            if (periph[periph_id].type == PERIPH_TYPE_NIC)
     860            {
     861                if (nic_found)
     862                {
    929863                    boot_puts("\n[BOOT ERROR] NIC component should not be replicated\n");
    930864                    boot_exit();
    931865                }
    932                 if (periph[periph_id].channels != NB_NICS) {
    933                     boot_puts("\n[BOOT ERROR] Wrong NB_NICS in cluster ");
     866                if (periph[periph_id].channels != NB_NIC_CHANNELS)
     867                {
     868                    boot_puts("\n[BOOT ERROR] Wrong NB_NIC_CHANNELS in cluster ");
    934869                    boot_putd(cluster_id);
    935870                    boot_puts(" : nics = ");
     
    941876            }
    942877            // NB_TIMERS
    943             if (periph[periph_id].type == PERIPH_TYPE_TIM) {
    944                 if (periph[periph_id].channels > NB_TIMERS_MAX) {
     878            if (periph[periph_id].type == PERIPH_TYPE_TIM)
     879            {
     880                if (periph[periph_id].channels > NB_TIM_CHANNELS)
     881                {
    945882                    boot_puts("\n[BOOT ERROR] Too much user timers in cluster ");
    946883                    boot_putd(cluster_id);
     
    952889            }
    953890            // NB_DMAS
    954             if (periph[periph_id].type == PERIPH_TYPE_DMA) {
    955                 if (periph[periph_id].channels != NB_DMAS_MAX) {
     891            if (periph[periph_id].type == PERIPH_TYPE_DMA)
     892            {
     893                if (periph[periph_id].channels != NB_DMA_CHANNELS)
     894                {
    956895                    boot_puts("\n[BOOT ERROR] Too much DMA channels in cluster ");
    957896                    boot_putd(cluster_id);
    958897                    boot_puts(" : channels = ");
    959898                    boot_putd(periph[periph_id].channels);
    960                     boot_puts(" - NB_DMAS_MAX : ");
    961                     boot_putd(NB_DMAS_MAX);
     899                    boot_puts(" - NB_DMA_CHANNELS : ");
     900                    boot_putd(NB_DMA_CHANNELS);
    962901                    boot_puts("\n");
    963902                    boot_exit();
     
    968907} // end boot_check_mapping()
    969908
    970 
    971909/////////////////////////////////////////////////////////////////////
    972910// This function initialises the physical pages table allocators
    973911// for all psegs (i.e. next_base field of the pseg).
    974 // In each cluster containing processors, it reserve space for the
    975 // schedulers in the first RAM pseg found (4k bytes per processor).
    976912/////////////////////////////////////////////////////////////////////
    977 void boot_psegs_init() {
    978     mapping_header_t * header = (mapping_header_t *) &seg_mapping_base;
    979 
    980     mapping_cluster_t * cluster = boot_get_cluster_base(header);
    981     mapping_pseg_t * pseg = boot_get_pseg_base(header);
     913void boot_psegs_init()
     914{
     915    mapping_header_t* header   = (mapping_header_t *) &seg_mapping_base;
     916    mapping_cluster_t* cluster = boot_get_cluster_base(header);
     917    mapping_pseg_t* pseg      = boot_get_pseg_base(header);
    982918
    983919    unsigned int cluster_id;
    984920    unsigned int pseg_id;
    985     unsigned int found;
    986921
    987922#if BOOT_DEBUG_PT
    988     boot_puts
    989         ("\n[BOOT DEBUG] ****** psegs allocators nitialisation ******\n");
    990 #endif
    991 
    992     for (cluster_id = 0; cluster_id < header->clusters; cluster_id++) {
    993         if (cluster[cluster_id].procs > NB_PROCS_MAX) {
     923boot_puts ("\n[BOOT DEBUG] ****** psegs allocators initialisation ******\n");
     924#endif
     925
     926    for (cluster_id = 0; cluster_id < header->clusters; cluster_id++)
     927    {
     928        if (cluster[cluster_id].procs > NB_PROCS_MAX)
     929        {
    994930            boot_puts("\n[BOOT ERROR] The number of processors in cluster ");
    995931            boot_putd(cluster_id);
     
    998934        }
    999935
    1000         found = 0;
    1001 
    1002936        for (pseg_id = cluster[cluster_id].pseg_offset;
    1003937                pseg_id < cluster[cluster_id].pseg_offset + cluster[cluster_id].psegs;
    1004                 pseg_id++) {
    1005             unsigned int free = pseg[pseg_id].base;
    1006 
    1007             if ((pseg[pseg_id].type == PSEG_TYPE_RAM) && (found == 0)) {
    1008                 free = free + (cluster[cluster_id].procs << 12);
    1009                 found = 1;
    1010             }
    1011             pseg[pseg_id].next_base = free;
     938                pseg_id++)
     939        {
     940            pseg[pseg_id].next_base = pseg[pseg_id].base;
    1012941
    1013942#if BOOT_DEBUG_PT
    1014             boot_puts("cluster ");
    1015             boot_putd(cluster_id);
    1016             boot_puts(" / pseg ");
    1017             boot_puts(pseg[pseg_id].name);
    1018             boot_puts(" : next_base = ");
    1019             boot_putx(pseg[pseg_id].next_base);
    1020             boot_puts("\n");
     943boot_puts("cluster ");
     944boot_putd(cluster_id);
     945boot_puts(" / pseg ");
     946boot_puts(pseg[pseg_id].name);
     947boot_puts(" : next_base = ");
     948boot_putl(pseg[pseg_id].next_base);
     949boot_puts("\n");
    1021950#endif
    1022951        }
    1023952    }
    1024953} // end boot_psegs_init()
    1025 
    1026954
    1027955/////////////////////////////////////////////////////////////////////
    1028956// This function builds the page tables for all virtual spaces
    1029 // defined in the mapping_info data structure.
    1030 // For each virtual space, it maps both the global vsegs
    1031 // (replicated in all vspaces), and the private vsegs.
     957// defined in the mapping_info data structure, in three steps:
     958// - step 1 : It computes the physical base address for global vsegs
     959//            and for all associated vobjs.
     960// - step 2 : It computes the physical base address for all private
     961//            vsegs and all vobjs in each virtual space.
     962// - step 3 : It actually fill the page table for each vspace.
    1032963/////////////////////////////////////////////////////////////////////
    1033 void boot_pt_init() {
     964void boot_pt_init()
     965{
    1034966    mapping_header_t * header = (mapping_header_t *) &seg_mapping_base;
    1035 
    1036967    mapping_vspace_t * vspace = boot_get_vspace_base(header);
    1037     mapping_vseg_t * vseg = boot_get_vseg_base(header);
     968    mapping_vseg_t   * vseg  = boot_get_vseg_base(header);
    1038969
    1039970    unsigned int vspace_id;
     
    1041972
    1042973#if BOOT_DEBUG_PT
    1043     boot_puts("\n[BOOT DEBUG] ****** mapping global vsegs ******\n");
    1044 #endif
    1045 
    1046     // step 1 : first loop on virtual spaces to map global vsegs
    1047     for (vseg_id = 0; vseg_id < header->globals; vseg_id++) {
     974boot_puts("\n[BOOT DEBUG] ****** mapping global vsegs ******\n");
     975#endif
     976
     977    // step 1 : loop on virtual spaces to map global vsegs
     978    for (vseg_id = 0; vseg_id < header->globals; vseg_id++)
     979    {
    1048980        boot_vseg_map(&vseg[vseg_id], ((unsigned int) (-1)));
    1049981    }
    1050982
    1051983    // step 2 : loop on virtual vspaces to map private vsegs
    1052     for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) {
     984    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++)
     985    {
    1053986
    1054987#if BOOT_DEBUG_PT
    1055         boot_puts("\n[BOOT DEBUG] ****** mapping private vsegs in vspace ");
    1056         boot_puts(vspace[vspace_id].name);
    1057         boot_puts(" ******\n");
     988boot_puts("\n[BOOT DEBUG] ****** mapping private vsegs in vspace ");
     989boot_puts(vspace[vspace_id].name);
     990boot_puts(" ******\n");
    1058991#endif
    1059992
    1060993        for (vseg_id = vspace[vspace_id].vseg_offset;
    1061994                vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs);
    1062                 vseg_id++) {
     995                vseg_id++)
     996        {
    1063997            boot_vseg_map(&vseg[vseg_id], vspace_id);
    1064998        }
     
    10661000
    10671001    // step 3 : loop on the vspaces to build the page tables
    1068     for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) {
    1069 
     1002    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++)
     1003    {
    10701004#if BOOT_DEBUG_PT
    1071         boot_puts("\n[BOOT DEBUG] ****** building page table for vspace ");
    1072         boot_puts(vspace[vspace_id].name);
    1073         boot_puts(" ******\n");
    1074 #endif
    1075 
     1005boot_puts("\n[BOOT DEBUG] ****** building page table for vspace ");
     1006boot_puts(vspace[vspace_id].name);
     1007boot_puts(" ******\n");
     1008#endif
    10761009        boot_vspace_pt_build(vspace_id);
    10771010
    10781011#if BOOT_DEBUG_PT
    1079         boot_puts("\n>>> page table physical address = ");
    1080         boot_putx((unsigned int) boot_ptabs_paddr[vspace_id]);
    1081         boot_puts(", page table number of PT2 = ");
    1082         boot_putd((unsigned int) boot_max_pt2[vspace_id]);
    1083         boot_puts("\n");
     1012boot_puts("\n>>> page table physical address = ");
     1013boot_putl(boot_ptabs_paddr[vspace_id]);
     1014boot_puts(", number of PT2 = ");
     1015boot_putd((unsigned int) boot_max_pt2[vspace_id]);
     1016boot_puts("\n");
    10841017#endif
    10851018    }
    10861019} // end boot_pt_init()
    1087 
    10881020
    10891021///////////////////////////////////////////////////////////////////////////////
     
    10911023// such as mwmr channels, barriers and locks, because these vobjs
    10921024// are not known, and not initialized by the compiler.
     1025// Warning : The MMU is supposed to be activated...
    10931026///////////////////////////////////////////////////////////////////////////////
    1094 void boot_vobjs_init() {
    1095     mapping_header_t * header = (mapping_header_t *) & seg_mapping_base;
    1096     mapping_vspace_t * vspace = boot_get_vspace_base(header);
    1097     mapping_vobj_t * vobj = boot_get_vobj_base(header);
     1027void boot_vobjs_init()
     1028{
     1029    mapping_header_t* header = (mapping_header_t *) & seg_mapping_base;
     1030    mapping_vspace_t* vspace = boot_get_vspace_base(header);
     1031    mapping_vobj_t* vobj     = boot_get_vobj_base(header);
    10981032
    10991033    unsigned int vspace_id;
    11001034    unsigned int vobj_id;
    11011035
    1102     // loop on the vspaces
    1103     for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) {
     1036    // loop on the vspaces
     1037    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++)
     1038    {
    11041039
    11051040#if BOOT_DEBUG_VOBJS
    1106         boot_puts("\n[BOOT DEBUG] ****** vobjs initialisation in vspace ");
    1107         boot_puts(vspace[vspace_id].name);
    1108         boot_puts(" ******\n");
     1041boot_puts("\n[BOOT DEBUG] ****** vobjs initialisation in vspace ");
     1042boot_puts(vspace[vspace_id].name);
     1043boot_puts(" ******\n");
    11091044#endif
    11101045
     
    11131048        // loop on the vobjs
    11141049        for (vobj_id = vspace[vspace_id].vobj_offset;
    1115                 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs);
    1116                 vobj_id++) {
    1117             switch (vobj[vobj_id].type) {
     1050             vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs);
     1051             vobj_id++)
     1052        {
     1053            switch (vobj[vobj_id].type)
     1054            {
    11181055                case VOBJ_TYPE_MWMR:    // storage capacity is (vobj.length/4 - 5) words
    11191056                {
    1120                     mwmr_channel_t * mwmr = (mwmr_channel_t *) (vobj[vobj_id].paddr);
     1057                    mwmr_channel_t* mwmr = (mwmr_channel_t *) (vobj[vobj_id].vaddr);
    11211058                    mwmr->ptw = 0;
    11221059                    mwmr->ptr = 0;
     
    11261063                    mwmr->lock = 0;
    11271064#if BOOT_DEBUG_VOBJS
    1128                     boot_puts("MWMR    : ");
    1129                     boot_puts(vobj[vobj_id].name);
    1130                     boot_puts(" / depth = ");
    1131                     boot_putd(mwmr->depth);
    1132                     boot_puts(" / width = ");
    1133                     boot_putd(mwmr->width);
    1134                     boot_puts("\n");
     1065boot_puts("MWMR    : ");
     1066boot_puts(vobj[vobj_id].name);
     1067boot_puts(" / depth = ");
     1068boot_putd(mwmr->depth);
     1069boot_puts(" / width = ");
     1070boot_putd(mwmr->width);
     1071boot_puts("\n");
    11351072#endif
    11361073                    break;
     
    11391076                {
    11401077#if BOOT_DEBUG_VOBJS
    1141                     boot_puts("ELF     : ");
    1142                     boot_puts(vobj[vobj_id].name);
    1143                     boot_puts(" / length = ");
    1144                     boot_putx(vobj[vobj_id].length);
    1145                     boot_puts("\n");
     1078boot_puts("ELF     : ");
     1079boot_puts(vobj[vobj_id].name);
     1080boot_puts(" / length = ");
     1081boot_putx(vobj[vobj_id].length);
     1082boot_puts("\n");
    11461083#endif
    11471084                    break;
     
    11501087                {
    11511088#if BOOT_DEBUG_VOBJS
    1152                     boot_puts("BLOB     : ");
    1153                     boot_puts(vobj[vobj_id].name);
    1154                     boot_puts(" / length = ");
    1155                     boot_putx(vobj[vobj_id].length);
    1156                     boot_puts("\n");
     1089boot_puts("BLOB     : ");
     1090boot_puts(vobj[vobj_id].name);
     1091boot_puts(" / length = ");
     1092boot_putx(vobj[vobj_id].length);
     1093boot_puts("\n");
    11571094#endif
    11581095                    break;
     
    11601097                case VOBJ_TYPE_BARRIER:    // init is the number of participants
    11611098                {
    1162                     giet_barrier_t * barrier = (giet_barrier_t *) (vobj[vobj_id].paddr);
     1099                    giet_barrier_t* barrier = (giet_barrier_t *) (vobj[vobj_id].vaddr);
    11631100                    barrier->count = vobj[vobj_id].init;
    11641101                    barrier->init = vobj[vobj_id].init;
    11651102#if BOOT_DEBUG_VOBJS
    1166                     boot_puts("BARRIER : ");
    1167                     boot_puts(vobj[vobj_id].name);
    1168                     boot_puts(" / init_value = ");
    1169                     boot_putd(barrier->init);
    1170                     boot_puts("\n");
     1103boot_puts("BARRIER : ");
     1104boot_puts(vobj[vobj_id].name);
     1105boot_puts(" / init_value = ");
     1106boot_putd(barrier->init);
     1107boot_puts("\n");
    11711108#endif
    11721109                    break;
    11731110                }
    1174                 case VOBJ_TYPE_LOCK:    // init is "not taken"
    1175                 {
    1176                     unsigned int * lock = (unsigned int *) (vobj[vobj_id].paddr);
     1111                case VOBJ_TYPE_LOCK:    // init value is "not taken"
     1112                {
     1113                    unsigned int* lock = (unsigned int *) (vobj[vobj_id].vaddr);
    11771114                    *lock = 0;
    11781115#if BOOT_DEBUG_VOBJS
    1179                     boot_puts("LOCK    : ");
    1180                     boot_puts(vobj[vobj_id].name);
    1181                     boot_puts("\n");
     1116boot_puts("LOCK    : ");
     1117boot_puts(vobj[vobj_id].name);
     1118boot_puts("\n");
    11821119#endif
    11831120                    break;
     
    11861123                {
    11871124#if BOOT_DEBUG_VOBJS
    1188                     boot_puts("BUFFER  : ");
    1189                     boot_puts(vobj[vobj_id].name);
    1190                     boot_puts(" / paddr = ");
    1191                     boot_putx(vobj[vobj_id].paddr);
    1192                     boot_puts(" / length = ");
    1193                     boot_putx(vobj[vobj_id].length);
    1194                     boot_puts("\n");
     1125boot_puts("BUFFER  : ");
     1126boot_puts(vobj[vobj_id].name);
     1127boot_puts(" / paddr = ");
     1128boot_putx(vobj[vobj_id].paddr);
     1129boot_puts(" / length = ");
     1130boot_putx(vobj[vobj_id].length);
     1131boot_puts("\n");
    11951132#endif
    11961133                    break;
     
    11981135                case VOBJ_TYPE_MEMSPACE:
    11991136                {
    1200                     giet_memspace_t * memspace = (giet_memspace_t *) vobj[vobj_id].paddr;
     1137                    giet_memspace_t* memspace = (giet_memspace_t *) vobj[vobj_id].vaddr;
    12011138                    memspace->buffer = (void *) vobj[vobj_id].vaddr + 8;
    12021139                    memspace->size = vobj[vobj_id].length - 8;
    12031140#if BOOT_DEBUG_VOBJS
    1204                     boot_puts("MEMSPACE  : ");
    1205                     boot_puts(vobj[vobj_id].name);
    1206                     boot_puts(" / paddr = ");
    1207                     boot_putx(vobj[vobj_id].paddr);
    1208                     boot_puts(" / vaddr = ");
    1209                     boot_putx(vobj[vobj_id].vaddr);
    1210                     boot_puts(" / length = ");
    1211                     boot_putx(vobj[vobj_id].length);
    1212                     boot_puts(" / buffer = ");
    1213                     boot_putx(memspace->buffer);
    1214                     boot_puts(" / size = ");
    1215                     boot_putx(memspace->size);
    1216                     boot_puts("\n");
     1141boot_puts("MEMSPACE  : ");
     1142boot_puts(vobj[vobj_id].name);
     1143boot_puts(" / vaddr = ");
     1144boot_putx(vobj[vobj_id].vaddr);
     1145boot_puts(" / length = ");
     1146boot_putx(vobj[vobj_id].length);
     1147boot_puts(" / buffer = ");
     1148boot_putx((unsigned int)memspace->buffer);
     1149boot_puts(" / size = ");
     1150boot_putx(memspace->size);
     1151boot_puts("\n");
    12171152#endif
    12181153                    break;
     
    12221157                    ptab_found = 1;
    12231158#if BOOT_DEBUG_VOBJS
    1224                     boot_puts("PTAB    : ");
    1225                     boot_puts(vobj[vobj_id].name);
    1226                     boot_puts(" / length = ");
    1227                     boot_putx(vobj[vobj_id].length);
    1228                     boot_puts("\n");
     1159boot_puts("PTAB    : ");
     1160boot_puts(vobj[vobj_id].name);
     1161boot_puts(" / length = ");
     1162boot_putx(vobj[vobj_id].length);
     1163boot_puts("\n");
    12291164#endif
    12301165                    break;
     
    12321167                case VOBJ_TYPE_CONST:
    12331168                {
    1234                     unsigned int *addr = (unsigned int *) vobj[vobj_id].paddr;
     1169                    unsigned int* addr = (unsigned int *) vobj[vobj_id].vaddr;
    12351170                    *addr = vobj[vobj_id].init;
    12361171#if BOOT_DEBUG_VOBJS
    1237                     boot_puts("CONST   : ");
    1238                     boot_puts(vobj[vobj_id].name);
    1239                     boot_puts(" / Paddr :");
    1240                     boot_putx(vobj[vobj_id].paddr);
    1241                     boot_puts(" / init = ");
    1242                     boot_putx(*addr);
    1243                     boot_puts("\n");
     1172boot_puts("CONST   : ");
     1173boot_puts(vobj[vobj_id].name);
     1174boot_puts(" / Paddr :");
     1175boot_putx(vobj[vobj_id].paddr);
     1176boot_puts(" / init = ");
     1177boot_putx(*addr);
     1178boot_puts("\n");
    12441179#endif
    12451180                    break;
     
    12471182                default:
    12481183                {
    1249                     boot_puts("\n[INIT ERROR] illegal vobj type: ");
     1184                    boot_puts("\n[BOOT ERROR] illegal vobj type: ");
    12501185                    boot_putd(vobj[vobj_id].type);
    12511186                    boot_puts("\n");
     
    12541189            }            // end switch type
    12551190        }            // end loop on vobjs
    1256         if (ptab_found == 0) {
    1257             boot_puts("\n[INIT ERROR] Missing PTAB for vspace ");
     1191        if (ptab_found == 0)
     1192        {
     1193            boot_puts("\n[BOOT ERROR] Missing PTAB for vspace ");
    12581194            boot_putd(vspace_id);
    12591195            boot_exit();
     
    12621198} // end boot_vobjs_init()
    12631199
    1264 
    1265 void mwmr_hw_init(void * coproc, enum mwmrPortDirection way,
    1266         unsigned int no, const mwmr_channel_t * pmwmr) {
    1267     volatile unsigned int *cbase = (unsigned int *) coproc;
    1268 
    1269     cbase[MWMR_CONFIG_FIFO_WAY] = way;
    1270     cbase[MWMR_CONFIG_FIFO_NO] = no;
    1271     cbase[MWMR_CONFIG_STATUS_ADDR] = (unsigned int) pmwmr;
    1272     cbase[MWMR_CONFIG_WIDTH] = pmwmr->width;
    1273     cbase[MWMR_CONFIG_DEPTH] = pmwmr->depth;
    1274     cbase[MWMR_CONFIG_BUFFER_ADDR] = (unsigned int) &pmwmr->data;
    1275     cbase[MWMR_CONFIG_RUNNING] = 1;
    1276 }
    1277 
     1200////////////////////////////////////////////////////////////////////////////////
     1201// This function initializes one MWMR controller channel.
     1202// - coproc_pbase  : physical base address of the Coproc configuration segment
     1203// - channel_pbase : physical base address of the MWMR channel segment
     1204// Warning : the channel physical base address should be on 32 bits, as the
     1205// MWMR controller configuration registers are 32 bits.
     1206// TODO : Introduce a MWMR_CONFIG_PADDR_EXT register in the MWMR coprocessor
     1207//        To support addresses > 32 bits and remove this limitation...
     1208///////////////////////////////////////////////////////////////////////////////
     1209void mwmr_hw_init(paddr_t                coproc_pbase,
     1210                  enum mwmrPortDirection way,
     1211                  unsigned int           no,
     1212                  paddr_t                channel_pbase)
     1213{
     1214    if ( (channel_pbase>>32) != 0 )
     1215    {
     1216        boot_puts("\n[BOOT ERROR] MWMR controller does not support address > 32 bits\n");
     1217        boot_exit();
     1218    }
     1219
     1220    unsigned int lsb = (unsigned int)channel_pbase;
     1221//  unsigned int msb = (unsigned int)(channel_pbase>>32);
     1222
     1223    unsigned int depth = boot_physical_read( channel_pbase + 16 );
     1224    unsigned int width = boot_physical_read( channel_pbase + 20 );
     1225
     1226    boot_physical_write( coproc_pbase + MWMR_CONFIG_FIFO_WAY*4, way );
     1227    boot_physical_write( coproc_pbase + MWMR_CONFIG_FIFO_NO*4, no );
     1228    boot_physical_write( coproc_pbase + MWMR_CONFIG_WIDTH*4, width);
     1229    boot_physical_write( coproc_pbase + MWMR_CONFIG_DEPTH*4, depth);
     1230    boot_physical_write( coproc_pbase + MWMR_CONFIG_STATUS_ADDR*4, lsb);
     1231    boot_physical_write( coproc_pbase + MWMR_CONFIG_BUFFER_ADDR*4, lsb + 24 );
     1232//  boot_physical_write( coproc_pbase + MWMR_CONFIG_PADDR_EXT*4, msb);
     1233    boot_physical_write( coproc_pbase + MWMR_CONFIG_RUNNING*4, 1 );
     1234}
    12781235
    12791236////////////////////////////////////////////////////////////////////////////////
     
    12811238// in the mapping_info file.
    12821239////////////////////////////////////////////////////////////////////////////////
    1283 void boot_peripherals_init() {
     1240void boot_peripherals_init()
     1241{
    12841242    mapping_header_t * header = (mapping_header_t *) & seg_mapping_base;
    12851243    mapping_cluster_t * cluster = boot_get_cluster_base(header);
     
    12971255    unsigned int channel_id;
    12981256
    1299     for (cluster_id = 0; cluster_id < header->clusters; cluster_id++) {
     1257    for (cluster_id = 0; cluster_id < header->clusters; cluster_id++)
     1258    {
    13001259
    13011260#if BOOT_DEBUG_PERI
    1302         boot_puts
    1303             ("\n[BOOT DEBUG] ****** peripheral initialisation in cluster ");
    1304         boot_putd(cluster_id);
    1305         boot_puts(" ******\n");
     1261boot_puts("\n[BOOT DEBUG] ****** peripherals initialisation in cluster ");
     1262boot_putd(cluster_id);
     1263boot_puts(" ******\n");
    13061264#endif
    13071265
    13081266        for (periph_id = cluster[cluster_id].periph_offset;
    1309                 periph_id < cluster[cluster_id].periph_offset +
    1310                 cluster[cluster_id].periphs; periph_id++) {
     1267             periph_id < cluster[cluster_id].periph_offset +
     1268             cluster[cluster_id].periphs; periph_id++)
     1269        {
    13111270            unsigned int type = periph[periph_id].type;
    13121271            unsigned int channels = periph[periph_id].channels;
    13131272            unsigned int pseg_id = periph[periph_id].psegid;
    13141273
    1315             unsigned int * pseg_base = (unsigned int *) pseg[pseg_id].base;
     1274            paddr_t pbase = pseg[pseg_id].base;
    13161275
    13171276#if BOOT_DEBUG_PERI
    1318             boot_puts("- peripheral type : ");
    1319             boot_putd(type);
    1320             boot_puts(" / address = ");
    1321             boot_putx((unsigned int) pseg_base);
    1322             boot_puts(" / channels = ");
    1323             boot_putd(channels);
    1324             boot_puts("\n");
    1325 #endif
    1326 
    1327             switch (type) {
     1277boot_puts("- peripheral type : ");
     1278boot_putd(type);
     1279boot_puts(" / pbase = ");
     1280boot_putl(pbase);
     1281boot_puts(" / channels = ");
     1282boot_putd(channels);
     1283boot_puts("\n");
     1284#endif
     1285
     1286            switch (type)
     1287            {
    13281288                case PERIPH_TYPE_IOC:    // vci_block_device component
    1329                     pseg_base[BLOCK_DEVICE_IRQ_ENABLE] = 1;
     1289                {
     1290                    paddr_t paddr = pbase + BLOCK_DEVICE_IRQ_ENABLE*4;
     1291                    boot_physical_write(paddr, 1);
    13301292#if BOOT_DEBUG_PERI
    1331                     boot_puts("- IOC initialised\n");
    1332 #endif
    1333                     break;
    1334 
     1293boot_puts("- IOC initialised\n");
     1294#endif
     1295                }
     1296                break;
    13351297                case PERIPH_TYPE_DMA:    // vci_multi_dma component
    1336                     for (channel_id = 0; channel_id < channels; channel_id++) {
    1337                         pseg_base[DMA_IRQ_DISABLE + channel_id * DMA_SPAN] = 0;
     1298                    for (channel_id = 0; channel_id < channels; channel_id++)
     1299                    {
     1300                        paddr_t paddr = pbase + (channel_id*DMA_SPAN + DMA_IRQ_DISABLE) * 4;
     1301                        boot_physical_write(paddr, 0);
    13381302                    }
    13391303#if BOOT_DEBUG_PERI
    1340                     boot_puts("- DMA initialised\n");
    1341 #endif
    1342                     break;
    1343 
     1304boot_puts("- DMA initialised\n");
     1305#endif
     1306                break;
    13441307                case PERIPH_TYPE_NIC:    // vci_multi_nic component
    1345                     for (channel_id = 0; channel_id < channels; channel_id++) {
     1308                    for (channel_id = 0; channel_id < channels; channel_id++)
     1309                    {
    13461310                        // TODO
    13471311                    }
    13481312#if BOOT_DEBUG_PERI
    1349                     boot_puts("- NIC initialised\n");
    1350 #endif
    1351                     break;
    1352 
     1313boot_puts("- NIC initialised\n");
     1314#endif
     1315                break;
    13531316                case PERIPH_TYPE_TTY:    // vci_multi_tty component
    13541317#if BOOT_DEBUG_PERI
    1355                     boot_puts("- TTY initialised\n");
    1356 #endif
    1357                     break;
    1358 
     1318boot_puts("- TTY initialised\n");
     1319#endif
     1320                break;
    13591321                case PERIPH_TYPE_IOB:    // vci_io_bridge component
    1360                     if (IOMMU_ACTIVE) {
     1322                    if (IOMMU_ACTIVE)
     1323                    {
    13611324                        // TODO
    13621325                        // get the iommu page table physical address
     
    13681331                    }
    13691332#if BOOT_DEBUG_PERI
    1370                     boot_puts("- IOB initialised\n");
    1371 #endif
    1372                     break;
    1373             }            // end switch periph type
    1374         }            // end for periphs
     1333boot_puts("- IOB initialised\n");
     1334#endif
     1335                break;
     1336            }  // end switch periph type
     1337        }  // end for periphs
    13751338
    13761339#if BOOT_DEBUG_PERI
    1377         boot_puts
    1378             ("\n[BOOT DEBUG] ****** coprocessors initialisation in cluster ");
    1379         boot_putd(cluster_id);
    1380         boot_puts(" ******\n");
     1340boot_puts("\n[BOOT DEBUG] ****** coprocessors initialisation in cluster ");
     1341boot_putd(cluster_id);
     1342boot_puts(" ******\n");
    13811343#endif
    13821344
    13831345        for (coproc_id = cluster[cluster_id].coproc_offset;
    1384                 coproc_id < cluster[cluster_id].coproc_offset +
    1385                 cluster[cluster_id].coprocs; coproc_id++) {
    1386             unsigned no_fifo_to = 0;    //FIXME: should it be the map.xml who define the order?
     1346             coproc_id < cluster[cluster_id].coproc_offset +
     1347             cluster[cluster_id].coprocs; coproc_id++)
     1348        {
     1349            unsigned no_fifo_to = 0;    //FIXME: should the map.xml define the order?
    13871350            unsigned no_fifo_from = 0;
    1388             unsigned int cpseg = pseg[coproc[coproc_id].psegid].base;
     1351
     1352            // Get physical base address for MWMR controler
     1353            paddr_t coproc_pbase = pseg[coproc[coproc_id].psegid].base;
    13891354
    13901355#if BOOT_DEBUG_PERI
    1391             boot_puts("- coprocessor name : ");
    1392             boot_puts(coproc[coproc_id].name);
    1393             boot_puts(" / nb ports = ");
    1394             boot_putd((unsigned int) coproc[coproc_id].ports);
    1395             boot_puts("\n");
     1356boot_puts("- coprocessor name : ");
     1357boot_puts(coproc[coproc_id].name);
     1358boot_puts(" / nb ports = ");
     1359boot_putd((unsigned int) coproc[coproc_id].ports);
     1360boot_puts("\n");
    13961361#endif
    13971362
    13981363            for (cp_port_id = coproc[coproc_id].port_offset;
    1399                     cp_port_id < coproc[coproc_id].port_offset + coproc[coproc_id].ports;
    1400                     cp_port_id++) {
    1401                 //FIXME: the vspace_id should be the same for all ports: put it in the coproc?
     1364                 cp_port_id < coproc[coproc_id].port_offset + coproc[coproc_id].ports;
     1365                 cp_port_id++)
     1366            {
    14021367                unsigned int vspace_id = cp_port[cp_port_id].vspaceid;
    1403                 unsigned int vobj_id = cp_port[cp_port_id].mwmr_vobjid + vspace[vspace_id].vobj_offset;
    1404 
    1405                 mwmr_channel_t * pmwmr = (mwmr_channel_t *) (vobj[vobj_id].paddr);
    1406 
    1407                 if (cp_port[cp_port_id].direction == PORT_TO_COPROC) {
     1368                unsigned int vobj_id = cp_port[cp_port_id].mwmr_vobjid +
     1369                                          vspace[vspace_id].vobj_offset;
     1370
     1371                // Get MWMR channel base address
     1372                paddr_t channel_pbase = vobj[vobj_id].paddr;
     1373
     1374                if (cp_port[cp_port_id].direction == PORT_TO_COPROC)
     1375                {
    14081376#if BOOT_DEBUG_PERI
    1409                     boot_puts("     port direction: PORT_TO_COPROC");
    1410 #endif
    1411                     mwmr_hw_init((void *) cpseg, PORT_TO_COPROC, no_fifo_to, pmwmr);
     1377boot_puts("     port direction: PORT_TO_COPROC");
     1378#endif
     1379                    mwmr_hw_init(coproc_pbase,
     1380                                 PORT_TO_COPROC,
     1381                                 no_fifo_to,
     1382                                 channel_pbase);
    14121383                    no_fifo_to++;
    14131384                }
    1414                 else {
     1385                else
     1386                {
    14151387#if BOOT_DEBUG_PERI
    1416                     boot_puts("     port direction: PORT_FROM_COPROC");
    1417 #endif
    1418                     mwmr_hw_init((void *) cpseg, PORT_FROM_COPROC, no_fifo_from, pmwmr);
     1388boot_puts("     port direction: PORT_FROM_COPROC");
     1389#endif
     1390                    mwmr_hw_init(coproc_pbase,
     1391                                 PORT_FROM_COPROC,
     1392                                 no_fifo_from,
     1393                                 channel_pbase);
    14191394                    no_fifo_from++;
    14201395                }
    14211396#if BOOT_DEBUG_PERI
    1422                 boot_puts(", with mwmr: ");
    1423                 boot_puts(vobj[vobj_id].name);
    1424                 boot_puts(" of vspace: ");
    1425                 boot_puts(vspace[vspace_id].name);
    1426 #endif
    1427             }
     1397boot_puts(", with mwmr: ");
     1398boot_puts(vobj[vobj_id].name);
     1399boot_puts(" of vspace: ");
     1400boot_puts(vspace[vspace_id].name);
     1401#endif
     1402            } // end for cp_ports
    14281403        } // end for coprocs
    14291404    } // end for clusters
    14301405} // end boot_peripherals_init()
    14311406
     1407///////////////////////////////////////////////////////////////////////////////
     1408// This function returns in the vbase and length buffers the virtual base
     1409// address and the length of the  segment allocated to the schedulers array
     1410// in the cluster defined by the clusterid argument.
     1411///////////////////////////////////////////////////////////////////////////////
     1412void boot_get_sched_vaddr( unsigned int  cluster_id,
     1413                           unsigned int* vbase,
     1414                           unsigned int* length )
     1415{
     1416    mapping_header_t* header = (mapping_header_t *) & seg_mapping_base;
     1417    mapping_vobj_t*   vobj   = boot_get_vobj_base(header);
     1418    mapping_vseg_t*   vseg   = boot_get_vseg_base(header);
     1419    mapping_pseg_t*   pseg   = boot_get_pseg_base(header);
     1420
     1421    unsigned int vseg_id;
     1422    unsigned int found = 0;
     1423
     1424    for ( vseg_id = 0 ; (vseg_id < header->vsegs) && (found == 0) ; vseg_id++ )
     1425    {
     1426        if ( (vobj[vseg[vseg_id].vobj_offset].type == VOBJ_TYPE_SCHED) &&
     1427             (pseg[vseg[vseg_id].psegid].cluster == cluster_id ) )
     1428        {
     1429            *vbase  = vseg[vseg_id].vbase;
     1430            *length = vobj[vseg[vseg_id].vobj_offset].length;
     1431            found = 1;
     1432        }
     1433    }
     1434    if ( found == 0 )
     1435    {
     1436        boot_puts("\n[BOOT ERROR] No vobj of type SCHED in cluster ");
     1437        boot_putd(cluster_id);
     1438        boot_puts("\n");
     1439        boot_exit();
     1440    }
     1441} // end boot_get_sched_vaddr()
    14321442
    14331443///////////////////////////////////////////////////////////////////////////////
    14341444// This function initialises all processors schedulers.
    14351445// This is done by processor 0, and the MMU must be activated.
    1436 // It initialises the boot_schedulers_paddr[gpid] pointers array.
     1446// It initialises the boot_chedulers[gpid] pointers array.
    14371447// Finally, it scan all tasks in all vspaces to initialise the tasks contexts,
    14381448// as specified in the mapping_info data structure.
    14391449// For each task, a TTY channel, a TIMER channel, a FBDMA channel, and a NIC
    1440 // channel can be allocated if required.
     1450// channel are allocated if required.
    14411451///////////////////////////////////////////////////////////////////////////////
    1442 void boot_schedulers_init() {
    1443     mapping_header_t * header = (mapping_header_t *) & seg_mapping_base;
    1444     mapping_cluster_t * cluster = boot_get_cluster_base(header);
    1445     mapping_pseg_t * pseg = boot_get_pseg_base(header);
    1446     mapping_vspace_t * vspace = boot_get_vspace_base(header);
    1447     mapping_task_t * task = boot_get_task_base(header);
    1448     mapping_vobj_t * vobj = boot_get_vobj_base(header);
    1449     mapping_proc_t * proc = boot_get_proc_base(header);
    1450     mapping_irq_t * irq = boot_get_irq_base(header);
    1451 
    1452     unsigned int alloc_tty_channel;    // TTY channel allocator
    1453     unsigned int alloc_nic_channel;    // NIC channel allocator
     1452void boot_schedulers_init()
     1453{
     1454    mapping_header_t*  header  = (mapping_header_t *) & seg_mapping_base;
     1455    mapping_cluster_t* cluster = boot_get_cluster_base(header);
     1456    mapping_vspace_t*  vspace  = boot_get_vspace_base(header);
     1457    mapping_task_t*    task    = boot_get_task_base(header);
     1458    mapping_vobj_t*    vobj    = boot_get_vobj_base(header);
     1459    mapping_proc_t*    proc    = boot_get_proc_base(header);
     1460    mapping_irq_t*     irq     = boot_get_irq_base(header);
     1461
     1462    unsigned int cluster_id;    // cluster index in mapping_info
     1463    unsigned int proc_id;       // processor index in mapping_info
     1464    unsigned int irq_id;        // irq index in mapping_info
     1465    unsigned int vspace_id;     // vspace index in mapping_info
     1466    unsigned int task_id;       // task index in mapping_info
     1467
     1468    unsigned int alloc_tty_channel = 1;            // TTY channel allocator
     1469    unsigned int alloc_nic_channel = 0;            // NIC channel allocator
     1470    unsigned int alloc_cma_channel = 0;            // CMA channel allocator
     1471    unsigned int alloc_ioc_channel = 0;            // IOC channel allocator
    14541472    unsigned int alloc_dma_channel[NB_CLUSTERS];   // DMA channel allocators
    1455     unsigned int alloc_timer_channel[NB_CLUSTERS]; // user TIMER allocators
    1456 
    1457     unsigned int cluster_id; // cluster global index
    1458     unsigned int proc_id;    // processor global index
    1459     unsigned int irq_id;     // irq global index
    1460     unsigned int pseg_id;    // pseg global index
    1461     unsigned int vspace_id;  // vspace global index
    1462     unsigned int task_id;    // task global index;
    1463 
    1464     // Step 0 : TTY, NIC, TIMERS and DMA channels allocators initialisation
    1465     //          global_id = cluster_id*NB_*_MAX + loc_id
    1466     //          - TTY[0] is reserved for the kernel
    1467     //          - In all clusters the first NB_PROCS_MAX timers
    1468     //            are reserved for the kernel (context switch)
    1469 
    1470     alloc_tty_channel = 1;
    1471     alloc_nic_channel = 0;
    1472 
    1473     for (cluster_id = 0; cluster_id < header->clusters; cluster_id++) {
     1473    unsigned int alloc_tim_channel[NB_CLUSTERS];   // user TIMER allocators
     1474
     1475    /////////////////////////////////////////////////////////////////////////
     1476    // Step 1 : loop on the clusters and on the processors
     1477    //          to initialize the schedulers[] array of pointers and
     1478    //          the interrupt vectors.
     1479    // Implementation note:
     1480    // We need to use both proc_id to scan the mapping info structure,
     1481    // and lpid to access the schedulers array.
     1482    // - the boot_schedulers[] array of pointers can contain "holes", because
     1483    //   it is indexed by the global pid = cluster_id*NB_PROCS_MAX + ltid
     1484    // - the mapping info array of processors is contiguous, it is indexed
     1485    //   by proc_id, and use an offset specific in each cluster.
     1486
     1487    for (cluster_id = 0; cluster_id < header->clusters; cluster_id++)
     1488    {
     1489
     1490#if BOOT_DEBUG_SCHED
     1491boot_puts("\n[BOOT DEBUG] Initialise schedulers in cluster ");
     1492boot_putd(cluster_id);
     1493boot_puts("\n");
     1494#endif
     1495
     1496        // TTY, NIC, CMA, IOC, TIM and DMA channels allocators
     1497        // - TTY[0] is reserved for the kernel
     1498        // - In all clusters the first NB_PROCS_MAX timers
     1499        //   are reserved for the kernel (context switch)
     1500
    14741501        alloc_dma_channel[cluster_id] = 0;
    1475         alloc_timer_channel[cluster_id] = 0;
    1476     }
    1477 
    1478     // Step 1 : loop on the clusters and on the processors
    1479     //          - initialise the boot_schedulers_paddr[] pointers array
    1480     //          - initialise the interrupt vectors for each processor.
    1481 
    1482     for (cluster_id = 0; cluster_id < header->clusters; cluster_id++) {
    1483 
    1484 #if BOOT_DEBUG_SCHED
    1485         boot_puts("\n[BOOT DEBUG] Initialise schedulers / IT vector in cluster ");
    1486         boot_putd(cluster_id);
    1487         boot_puts("\n");
    1488 #endif
    1489         unsigned int found = 0;
    1490         unsigned int pseg_pbase;    // pseg base address
    1491         unsigned int lpid;    // processor local index
    1492 
    1493         // get the physical base address of the first PSEG_TYPE_RAM pseg in cluster
    1494         for (pseg_id = cluster[cluster_id].pseg_offset;
    1495                 pseg_id < cluster[cluster_id].pseg_offset + cluster[cluster_id].psegs;
    1496                 pseg_id++) {
    1497             if (pseg[pseg_id].type == PSEG_TYPE_RAM) {
    1498                 pseg_pbase = pseg[pseg_id].base;
    1499                 found = 1;
    1500                 break;
    1501             }
    1502         }
    1503 
    1504         if ((cluster[cluster_id].procs > 0) && (found == 0)) {
    1505             boot_puts("\n[BOOT ERROR] Missing RAM pseg in cluster ");
     1502        alloc_tim_channel[cluster_id] = NB_PROCS_MAX;
     1503
     1504        unsigned int  lpid;          // processor local index in cluster
     1505        unsigned int  sched_vbase;   // schedulers segment virtual base address
     1506        unsigned int  sched_length;  // schedulers segment length
     1507        unsigned int  nprocs;        // number of processors in cluster
     1508
     1509        nprocs = cluster[cluster_id].procs;
     1510
     1511        // checking processors number
     1512        if ( nprocs > NB_PROCS_MAX )
     1513        {
     1514            boot_puts("\n[BOOT ERROR] Too much processors in cluster ");
    15061515            boot_putd(cluster_id);
    15071516            boot_puts("\n");
    15081517            boot_exit();
    15091518        }
    1510         // 4 Kbytes per scheduler
    1511         for (lpid = 0; lpid < cluster[cluster_id].procs; lpid++) {
    1512             boot_schedulers_paddr[cluster_id * NB_PROCS_MAX + lpid] = (static_scheduler_t *) (pseg_pbase + (lpid << 12));
     1519 
     1520        // get scheduler array virtual base address for cluster_id
     1521        boot_get_sched_vaddr( cluster_id, &sched_vbase, &sched_length );
     1522
     1523        // each processor scheduler requires 1 Kbytes
     1524        if ( sched_length < (nprocs<<10) )
     1525        {
     1526            boot_puts("\n[BOOT ERROR] Schedulers segment too small in cluster ");
     1527            boot_putd(cluster_id);
     1528            boot_puts("\n");
     1529            boot_exit();
    15131530        }
    15141531
    1515         for (proc_id = cluster[cluster_id].proc_offset;
    1516                 proc_id < cluster[cluster_id].proc_offset + cluster[cluster_id].procs;
    1517                 proc_id++) {
     1532        for ( proc_id = cluster[cluster_id].proc_offset, lpid = 0 ;
     1533              proc_id < cluster[cluster_id].proc_offset + cluster[cluster_id].procs;
     1534              proc_id++, lpid++ )
     1535        {
     1536            // set the schedulers pointers array
     1537            boot_schedulers[cluster_id * NB_PROCS_MAX + lpid] =
     1538               (static_scheduler_t*)( sched_vbase + (lpid<<10) );
    15181539
    15191540#if BOOT_DEBUG_SCHED
    1520             boot_puts("\nProc ");
    1521             boot_putd(proc_id);
    1522             boot_puts(" : scheduler pbase = ");
    1523             boot_putx(pseg_pbase + (proc_id << 12));
    1524             boot_puts("\n");
    1525 #endif
    1526             // initialise the "tasks" variable in scheduler
    1527             boot_scheduler_set_tasks(proc_id, 0);
     1541boot_puts("\nProc ");
     1542boot_putd(lpid);
     1543boot_puts(" : scheduler virtual base address = ");
     1544boot_putx( sched_vbase + (lpid<<10) );
     1545boot_puts("\n");
     1546#endif
     1547            // current processor scheduler pointer : psched
     1548            static_scheduler_t* psched = (static_scheduler_t*)(sched_vbase+(lpid<<10));
     1549
     1550            // initialise the "tasks" variable
     1551            psched->tasks = 0;
    15281552
    15291553            // initialise the interrupt_vector with ISR_DEFAULT
    15301554            unsigned int slot;
    1531             for (slot = 0; slot < 32; slot++) {
    1532                 boot_scheduler_set_itvector(proc_id, slot, 0);
    1533             }
     1555            for (slot = 0; slot < 32; slot++) psched->interrupt_vector[slot] = 0;
    15341556
    15351557            // scan the IRQs actually allocated to current processor
    15361558            for (irq_id = proc[proc_id].irq_offset;
    1537                     irq_id < proc[proc_id].irq_offset + proc[proc_id].irqs;
    1538                     irq_id++) {
     1559                 irq_id < proc[proc_id].irq_offset + proc[proc_id].irqs;
     1560                 irq_id++)
     1561            {
    15391562                unsigned int type = irq[irq_id].type;
    15401563                unsigned int icu_id = irq[irq_id].icuid;
     
    15421565                unsigned int channel = irq[irq_id].channel;
    15431566                unsigned int value = isr_id | (type << 8) | (channel << 16);
    1544                 boot_scheduler_set_itvector(proc_id, icu_id, value);
     1567                psched->interrupt_vector[icu_id] = value;
    15451568
    15461569#if BOOT_DEBUG_SCHED
    1547                 boot_puts("- IRQ : icu = ");
    1548                 boot_putd(icu_id);
    1549                 boot_puts(" / type = ");
    1550                 boot_putd(type);
    1551                 boot_puts(" / isr = ");
    1552                 boot_putd(isr_id);
    1553                 boot_puts(" / channel = ");
    1554                 boot_putd(channel);
    1555                 boot_puts("\n");
     1570boot_puts("- IRQ : icu = ");
     1571boot_putd(icu_id);
     1572boot_puts(" / type = ");
     1573boot_putd(type);
     1574boot_puts(" / isr = ");
     1575boot_putd(isr_id);
     1576boot_puts(" / channel = ");
     1577boot_putd(channel);
     1578boot_puts(" => vector_entry = ");
     1579boot_putx( value );
     1580boot_puts("\n");
    15561581#endif
    15571582            }
     
    15591584    } // end for clusters
    15601585
     1586    ///////////////////////////////////////////////////////////////////
    15611587    // Step 2 : loop on the vspaces and the tasks
    15621588    //          to initialise the schedulers and the task contexts.
    1563 
    1564     for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) {
     1589    // Implementation note:
     1590    // This function initialises the task context for all tasks.
     1591    // For each processor, the scheduler virtual base address
     1592    // is written in the CP0_SCHED register in reset.S
     1593
     1594    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++)
     1595    {
    15651596
    15661597#if BOOT_DEBUG_SCHED
    1567         boot_puts
    1568             ("\n[BOOT DEBUG] Initialise schedulers / task contexts for vspace ");
    1569         boot_puts(vspace[vspace_id].name);
    1570         boot_puts("\n");
     1598boot_puts("\n[BOOT DEBUG] Initialise task contexts for vspace ");
     1599boot_puts(vspace[vspace_id].name);
     1600boot_puts("\n");
    15711601#endif
    15721602        // We must set the PTPR depending on the vspace, because the start_vector
    15731603        // and the stack address are defined in virtual space.
    1574         boot_set_mmu_ptpr((unsigned int) boot_ptabs_paddr[vspace_id] >> 13);
     1604        boot_set_mmu_ptpr( (unsigned int)(boot_ptabs_paddr[vspace_id] >> 13) );
    15751605
    15761606        // loop on the tasks in vspace (task_id is the global index)
    15771607        for (task_id = vspace[vspace_id].task_offset;
    1578                 task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
    1579                 task_id++) {
     1608             task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
     1609             task_id++)
     1610        {
     1611            // compute gpid (global processor index) and scheduler base address
     1612            unsigned int gpid = task[task_id].clusterid * NB_PROCS_MAX +
     1613                                task[task_id].proclocid;
     1614            static_scheduler_t* psched = boot_schedulers[gpid];
     1615
    15801616            // ctx_ra :  the return address is &boot_eret()
    15811617            unsigned int ctx_ra = (unsigned int) &boot_eret;
     
    15851621
    15861622            // ctx_ptpr : page table physical base address (shifted by 13 bit)
    1587             unsigned int ctx_ptpr = (unsigned int) boot_ptabs_paddr[vspace_id] >> 13;
    1588 
    1589             // compute gpid = global processor index
    1590             unsigned int gpid = task[task_id].clusterid * NB_PROCS_MAX + task[task_id].proclocid;
     1623            unsigned int ctx_ptpr = (unsigned int)(boot_ptabs_paddr[vspace_id] >> 13);
    15911624
    15921625            // ctx_ptab : page_table virtual base address
    1593             unsigned int ctx_ptab = (unsigned int) boot_ptabs_vaddr[vspace_id];
    1594 
    1595             // ctx_tty : terminal global index provided by a global allocator
     1626            unsigned int ctx_ptab = boot_ptabs_vaddr[vspace_id];
     1627
     1628            // ctx_tty : terminal global index provided by the global allocator
    15961629            unsigned int ctx_tty = 0xFFFFFFFF;
    1597             if (task[task_id].use_tty) {
    1598                 if (alloc_tty_channel >= NB_TTYS) {
     1630            if (task[task_id].use_tty)
     1631            {
     1632                if (alloc_tty_channel >= NB_TTY_CHANNELS)
     1633                {
    15991634                    boot_puts("\n[BOOT ERROR] TTY index too large for task ");
    16001635                    boot_puts(task[task_id].name);
     
    16071642                alloc_tty_channel++;
    16081643            }
    1609             // ctx_nic : NIC channel global index provided by a global allocator
     1644            // ctx_nic : NIC channel global index provided by the global allocator
    16101645            unsigned int ctx_nic = 0xFFFFFFFF;
    1611             if (task[task_id].use_nic) {
    1612                 if (alloc_nic_channel >= NB_NICS) {
     1646            if (task[task_id].use_nic)
     1647            {
     1648                if (alloc_nic_channel >= NB_NIC_CHANNELS)
     1649                {
    16131650                    boot_puts("\n[BOOT ERROR] NIC channel index too large for task ");
    16141651                    boot_puts(task[task_id].name);
     
    16211658                alloc_nic_channel++;
    16221659            }
    1623             // ctx_timer : user TIMER global index provided by a cluster allocator
    1624             unsigned int ctx_timer = 0xFFFFFFFF;
    1625             if (task[task_id].use_timer) {
     1660            // ctx_cma : CMA channel global index provided by the global allocator
     1661            unsigned int ctx_cma = 0xFFFFFFFF;
     1662            if (task[task_id].use_cma)
     1663            {
     1664                if (alloc_cma_channel >= NB_CMA_CHANNELS)
     1665                {
     1666                    boot_puts("\n[BOOT ERROR] CMA channel index too large for task ");
     1667                    boot_puts(task[task_id].name);
     1668                    boot_puts(" in vspace ");
     1669                    boot_puts(vspace[vspace_id].name);
     1670                    boot_puts("\n");
     1671                    boot_exit();
     1672                }
     1673                ctx_cma = alloc_cma_channel;
     1674                alloc_cma_channel++;
     1675            }
     1676            // ctx_ioc : IOC channel global index provided by the global allocator
     1677            unsigned int ctx_ioc = 0xFFFFFFFF;
     1678            if (task[task_id].use_ioc)
     1679            {
     1680                if (alloc_ioc_channel >= NB_IOC_CHANNELS)
     1681                {
     1682                    boot_puts("\n[BOOT ERROR] IOC channel index too large for task ");
     1683                    boot_puts(task[task_id].name);
     1684                    boot_puts(" in vspace ");
     1685                    boot_puts(vspace[vspace_id].name);
     1686                    boot_puts("\n");
     1687                    boot_exit();
     1688                }
     1689                ctx_ioc = alloc_ioc_channel;
     1690                alloc_ioc_channel++;
     1691            }
     1692            // ctx_tim : TIMER local channel index provided by the cluster allocator
     1693            unsigned int ctx_tim = 0xFFFFFFFF;
     1694            if (task[task_id].use_tim)
     1695            {
    16261696                unsigned int cluster_id = task[task_id].clusterid;
    1627                 unsigned int allocated = alloc_timer_channel[cluster_id];
    1628 
    1629                 if (allocated >= NB_TIMERS_MAX) {
     1697
     1698                if ( alloc_tim_channel[cluster_id] >= NB_TIM_CHANNELS )
     1699                {
    16301700                    boot_puts("\n[BOOT ERROR] local TIMER index too large for task ");
    16311701                    boot_puts(task[task_id].name);
     
    16351705                    boot_exit();
    16361706                }
    1637                 //assert(allocated >= 0);
    1638                 char found = 0;
    1639                 for (irq_id = 0; irq_id < 32; irq_id++) { //look at the isr_timer isr channel
    1640                     unsigned int isr = boot_scheduler_get_itvector(gpid, irq_id) & 0x000000FF;
    1641                     if (isr == ISR_TIMER) {
    1642                         if (allocated == 0) {
    1643                             found = 1;
    1644                             alloc_timer_channel[cluster_id]++;
    1645                             ctx_timer = cluster_id * NB_TIMERS_MAX + alloc_timer_channel[cluster_id];
    1646                             break;
    1647                         }
    1648                         else {
    1649                             allocated--;
    1650                         }
     1707
     1708                // checking that there is a well defined ISR_TIMER installed
     1709                unsigned int found = 0;
     1710                for ( irq_id = 0 ; irq_id < 32 ; irq_id++ ) 
     1711                {
     1712                    unsigned int entry   = psched->interrupt_vector[irq_id];
     1713                    unsigned int isr     = entry & 0x000000FF;
     1714                    unsigned int channel = entry>>16;
     1715                    if ( (isr == ISR_TIMER) && (channel == alloc_tim_channel[cluster_id]) )
     1716                    {
     1717                        found     = 1;
     1718                        ctx_tim =  alloc_tim_channel[cluster_id];
     1719                        alloc_tim_channel[cluster_id]++;
     1720                        break;
    16511721                    }
    16521722                }
    1653 
    1654                 if (!found) {
    1655                     boot_puts("\n[BOOT ERROR] No user timer available for task ");
     1723                if (!found)
     1724                {
     1725                    boot_puts("\n[BOOT ERROR] No ISR_TIMER installed for task ");
    16561726                    boot_puts(task[task_id].name);
    16571727                    boot_puts(" in vspace ");
     
    16601730                    boot_exit();
    16611731                }
    1662 
    16631732            }
    1664             // ctx_dma : DMA global index provided by a cluster allocator 
     1733            // ctx_dma : the local channel index is defined by the cluster allocator 
     1734            //           but the ctx_dma value is a global index
    16651735            unsigned int ctx_dma = 0xFFFFFFFF;
    1666             if (task[task_id].use_fbdma || task[task_id].use_nic) {
     1736            if ( task[task_id].use_dma )
     1737            {
    16671738                unsigned int cluster_id = task[task_id].clusterid;
    1668                 if (alloc_dma_channel[cluster_id] >= NB_DMAS_MAX) {
     1739
     1740                if (alloc_dma_channel[cluster_id] >= NB_DMA_CHANNELS)
     1741                {
    16691742                    boot_puts("\n[BOOT ERROR] local DMA index too large for task ");
    16701743                    boot_puts(task[task_id].name);
     
    16741747                    boot_exit();
    16751748                }
    1676                 ctx_dma = cluster_id * NB_DMAS_MAX + alloc_dma_channel[cluster_id];
     1749                ctx_dma = cluster_id * NB_DMA_CHANNELS + alloc_dma_channel[cluster_id];
    16771750                alloc_dma_channel[cluster_id]++;
    16781751            }
    16791752            // ctx_epc : Get the virtual address of the start function
    1680             mapping_vobj_t * pvobj = &vobj[vspace[vspace_id].vobj_offset + vspace[vspace_id].start_offset];
    1681             unsigned int * start_vector_vbase = (unsigned int *) pvobj->vaddr;
     1753            mapping_vobj_t* pvobj = &vobj[vspace[vspace_id].vobj_offset +
     1754                                     vspace[vspace_id].start_offset];
     1755            unsigned int* start_vector_vbase = (unsigned int *) pvobj->vaddr;
    16821756            unsigned int ctx_epc = start_vector_vbase[task[task_id].startid];
    16831757
     
    16861760            unsigned int ctx_sp = vobj[vobj_id].vaddr + vobj[vobj_id].length;
    16871761
    1688             // In the code below, we access the scheduler with specific access
    1689             // functions, because we only have the physical address of the scheduler,
    1690             // and these functions must temporary desactivate the DTLB...
    1691 
    1692             // get local task index in scheduler[gpid]
    1693             unsigned int ltid = boot_scheduler_get_tasks(gpid);
    1694 
    1695             if (ltid >= IDLE_TASK_INDEX) {
     1762            // get local task index in scheduler
     1763            unsigned int ltid = psched->tasks;
     1764
     1765            if (ltid >= IDLE_TASK_INDEX)
     1766            {
    16961767                boot_puts("\n[BOOT ERROR] : ");
    16971768                boot_putd(ltid);
     
    17011772                boot_exit();
    17021773            }
    1703             // update the "tasks" field in scheduler[gpid]
    1704             boot_scheduler_set_tasks(gpid, ltid + 1);
    1705 
    1706             // update the "current" field in scheduler[gpid]
    1707             boot_scheduler_set_current(gpid, 0);
    1708 
    1709             // initializes the task context in scheduler[gpid]
    1710             boot_scheduler_set_context(gpid, ltid, CTX_SR_ID, ctx_sr);
    1711             boot_scheduler_set_context(gpid, ltid, CTX_SP_ID, ctx_sp);
    1712             boot_scheduler_set_context(gpid, ltid, CTX_RA_ID, ctx_ra);
    1713             boot_scheduler_set_context(gpid, ltid, CTX_EPC_ID, ctx_epc);
    1714             boot_scheduler_set_context(gpid, ltid, CTX_PTPR_ID, ctx_ptpr);
    1715             boot_scheduler_set_context(gpid, ltid, CTX_TTY_ID, ctx_tty);
    1716             boot_scheduler_set_context(gpid, ltid, CTX_DMA_ID, ctx_dma);
    1717             boot_scheduler_set_context(gpid, ltid, CTX_NIC_ID, ctx_nic);
    1718             boot_scheduler_set_context(gpid, ltid, CTX_TIMER_ID, ctx_timer);
    1719             boot_scheduler_set_context(gpid, ltid, CTX_PTAB_ID, ctx_ptab);
    1720             boot_scheduler_set_context(gpid, ltid, CTX_LTID_ID, ltid);
    1721             boot_scheduler_set_context(gpid, ltid, CTX_VSID_ID, vspace_id);
    1722             boot_scheduler_set_context(gpid, ltid, CTX_GTID_ID, task_id);
    1723             boot_scheduler_set_context(gpid, ltid, CTX_RUN_ID, 1);
     1774            // update the "tasks" field in scheduler
     1775            psched->tasks = ltid + 1;
     1776
     1777            // update the "current" field in scheduler
     1778            psched->current = 0;
     1779
     1780            // initializes the task context in scheduler
     1781            psched->context[ltid][CTX_SR_ID]    = ctx_sr;
     1782            psched->context[ltid][CTX_SP_ID]    = ctx_sp;
     1783            psched->context[ltid][CTX_RA_ID]    = ctx_ra;
     1784            psched->context[ltid][CTX_EPC_ID]   = ctx_epc;
     1785            psched->context[ltid][CTX_PTPR_ID]  = ctx_ptpr;
     1786            psched->context[ltid][CTX_TTY_ID]   = ctx_tty;
     1787            psched->context[ltid][CTX_CMA_ID]   = ctx_cma;
     1788            psched->context[ltid][CTX_IOC_ID]   = ctx_ioc;
     1789            psched->context[ltid][CTX_NIC_ID]   = ctx_nic;
     1790            psched->context[ltid][CTX_TIM_ID]   = ctx_tim;
     1791            psched->context[ltid][CTX_DMA_ID]   = ctx_dma;
     1792            psched->context[ltid][CTX_PTAB_ID]  = ctx_ptab;
     1793            psched->context[ltid][CTX_LTID_ID]  = ltid;
     1794            psched->context[ltid][CTX_GTID_ID]  = task_id;
     1795            psched->context[ltid][CTX_VSID_ID]  = vspace_id;
     1796            psched->context[ltid][CTX_RUN_ID]   = 1;
    17241797
    17251798#if BOOT_DEBUG_SCHED
    1726             boot_puts("\nTask ");
    1727             boot_puts(task[task_id].name);
    1728             boot_puts(" (");
    1729             boot_putd(task_id);
    1730             boot_puts(") allocated to processor ");
    1731             boot_putd(gpid);
    1732             boot_puts("\n  - ctx[LTID]   = ");
    1733             boot_putd(ltid);
    1734             boot_puts("\n  - ctx[SR]     = ");
    1735             boot_putx(ctx_sr);
    1736             boot_puts("\n  - ctx[SR]     = ");
    1737             boot_putx(ctx_sp);
    1738             boot_puts("\n  - ctx[RA]     = ");
    1739             boot_putx(ctx_ra);
    1740             boot_puts("\n  - ctx[EPC]    = ");
    1741             boot_putx(ctx_epc);
    1742             boot_puts("\n  - ctx[PTPR]   = ");
    1743             boot_putx(ctx_ptpr);
    1744             boot_puts("\n  - ctx[TTY]    = ");
    1745             boot_putd(ctx_tty);
    1746             boot_puts("\n  - ctx[NIC]    = ");
    1747             boot_putd(ctx_nic);
    1748             boot_puts("\n  - ctx[TIMER]  = ");
    1749             boot_putd(ctx_timer);
    1750             boot_puts("\n  - ctx[DMA]    = ");
    1751             boot_putd(ctx_dma);
    1752             boot_puts("\n  - ctx[PTAB]   = ");
    1753             boot_putx(ctx_ptab);
    1754             boot_puts("\n  - ctx[VSID]   = ");
    1755             boot_putd(vspace_id);
    1756             boot_puts("\n");
     1799boot_puts("\nTask ");
     1800boot_puts(task[task_id].name);
     1801boot_puts(" (");
     1802boot_putd(task_id);
     1803boot_puts(") allocated to processor ");
     1804boot_putd(gpid);
     1805boot_puts("\n  - ctx[LTID]   = ");
     1806boot_putd(ltid);
     1807boot_puts("\n  - ctx[SR]     = ");
     1808boot_putx(ctx_sr);
     1809boot_puts("\n  - ctx[SR]     = ");
     1810boot_putx(ctx_sp);
     1811boot_puts("\n  - ctx[RA]     = ");
     1812boot_putx(ctx_ra);
     1813boot_puts("\n  - ctx[EPC]    = ");
     1814boot_putx(ctx_epc);
     1815boot_puts("\n  - ctx[PTPR]   = ");
     1816boot_putx(ctx_ptpr);
     1817boot_puts("\n  - ctx[TTY]    = ");
     1818boot_putd(ctx_tty);
     1819boot_puts("\n  - ctx[NIC]    = ");
     1820boot_putd(ctx_nic);
     1821boot_puts("\n  - ctx[CMA]    = ");
     1822boot_putd(ctx_cma);
     1823boot_puts("\n  - ctx[IOC]    = ");
     1824boot_putd(ctx_ioc);
     1825boot_puts("\n  - ctx[TIM]    = ");
     1826boot_putd(ctx_tim);
     1827boot_puts("\n  - ctx[DMA]    = ");
     1828boot_putd(ctx_dma);
     1829boot_puts("\n  - ctx[PTAB]   = ");
     1830boot_putx(ctx_ptab);
     1831boot_puts("\n  - ctx[GTID]   = ");
     1832boot_putd(task_id);
     1833boot_puts("\n  - ctx[VSID]   = ");
     1834boot_putd(vspace_id);
     1835boot_puts("\n");
    17571836#endif
    17581837
     
    17651844// This function is executed by P[0] to wakeup all processors.
    17661845//////////////////////////////////////////////////////////////////////////////////
    1767 void boot_start_all_procs() {
     1846void boot_start_all_procs()
     1847{
    17681848    mapping_header_t * header = (mapping_header_t *) &seg_mapping_base;
    17691849    header->signature = OUT_MAPPING_SIGNATURE;
     
    17861866    boot_psegs_init();
    17871867
    1788     boot_puts
    1789         ("\n[BOOT] Pseg allocators initialisation completed at cycle ");
     1868    boot_puts("\n[BOOT] Pseg allocators initialisation completed at cycle ");
    17901869    boot_putd(boot_proctime());
    17911870    boot_puts("\n");
     
    17981877    boot_puts("\n");
    17991878
     1879    // mmu activation ( with page table [Ø] )
     1880    boot_set_mmu_ptpr( (unsigned int)(boot_ptabs_paddr[0] >> 13) );
     1881    boot_set_mmu_mode(0xF);
     1882
     1883    boot_puts("\n[BOOT] Proc 0 MMU activation at cycle ");
     1884    boot_putd(boot_proctime());
     1885    boot_puts("\n");
     1886
    18001887    // vobjs initialisation
    18011888    boot_vobjs_init();
     
    18091896
    18101897    boot_puts("\n[BOOT] Peripherals initialisation completed at cycle ");
    1811     boot_putd(boot_proctime());
    1812     boot_puts("\n");
    1813 
    1814     // mmu activation
    1815     boot_set_mmu_ptpr((unsigned int) boot_ptabs_paddr[0] >> 13);
    1816     boot_set_mmu_mode(0xF);
    1817 
    1818     boot_puts("\n[BOOT] MMU activation completed at cycle ");
    18191898    boot_putd(boot_proctime());
    18201899    boot_puts("\n");
  • soft/giet_vm/boot/reset.S

    r234 r238  
    182182boot_to_kernel_init:
    183183
    184     # all processors initialise SCHED register with boot_schedulers_paddr[pid]
     184    # all processors initialise the CP0 SCHED register
     185    # SCHED contains the schedulers array virtual base address
    185186    mfc0        k0, CP0_PROCID
    186187    andi    k0, k0, 0xFFF
    187188    sll         k0, k0, 2               # k0 <= 4*pid
    188     la          k1, boot_schedulers_paddr
    189     addu    k1, k1, k0          # k1 <= &boot_scheduler_paddr[pid]
    190     lw          k1,     0(k1)           
    191     mtc0        k1, CP0_SCHED
    192 
    193     # all processors initialize PTPR register with boot_ptabs_paddr[0]
     189    la          k1, boot_schedulers
     190    addu    k1, k1, k0          # k1 <= &boot_schedulers[pid]
     191    lw          k0,     0(k1)           
     192    mtc0        k0, CP0_SCHED
     193
     194    # all processors initialize the CP2 PTPR register
     195    # At this stage, all PTPR registers contain the physical base
     196    # address (13 bits right shifted) of the page table for vspace[0]
    194197    la      k1, boot_ptabs_paddr
    195     lw      k1, 0(k1)   
    196     srl     k1, k1, 13
    197     mtc2        k1,     CP2_PTPR       
    198 
    199         # all processors activate MMU
     198    lw      k0, 0(k1)           # k0 <= paddr_lsb
     199    lw      k1, 4(k1)           # k1 <= paddr_msb
     200    srl     k0, k0, 13          # k0 <= paddr_lsb shifted
     201    sll     k1, k1, 19          # k1 <= paddr_msb shifted
     202    or      k0, k0, k1
     203    mtc2        k0,     CP2_PTPR       
     204
     205        # all processors activate MMU (already done for processor 0)
    200206    li      k1, 0xF
    201207    mtc2    k1, CP2_MODE
  • soft/giet_vm/display/main.c

    r218 r238  
    1818        if ( x )
    1919        {
    20             giet_tty_printf("echec giet_ioc_read %d at date : %d\n", x , giet_proctime() );
     20            giet_tty_printf("echec giet_ioc_read = %d at date : %d\n", x , giet_proctime() );
    2121            giet_exit();
    2222        }
     
    2424        if ( x )
    2525        {
    26             giet_tty_printf("echec giet_ioc_completed %d at date : %d\n", x, giet_proctime() );
     26            giet_tty_printf("echec giet_ioc_completed = %d at date : %d\n", x, giet_proctime() );
    2727            giet_exit();
    2828        }
     
    3333        if ( x )
    3434        {
    35             giet_tty_printf("echec giet_fb_write %d at date : %d\n", x, giet_proctime() );
     35            giet_tty_printf("echec giet_fb_write = %d at date : %d\n", x, giet_proctime() );
    3636            giet_exit();
    3737        }
     
    4242        if ( x )
    4343        {
    44             giet_tty_printf("echec giet_fb_completed %d at date : %d\n", x, giet_proctime() );
     44            giet_tty_printf("echec giet_fb_completed = %d at date : %d\n", x, giet_proctime() );
    4545            giet_exit();
    4646        }
  • soft/giet_vm/giet_config.h

    r232 r238  
    22/*      File : giet_config.h                                                        */
    33/*      Author : Alain Greiner                                                      */
    4 /*      Date : 26/03/2012                                                           */
     4/*      Date : 26/03/2013                                                           */
    55/********************************************************************************/
    66/*      Define various configuration parameters for the GIET                                */
    77/********************************************************************************/
    88
    9 #ifndef _CONFIG_H
    10 #define _CONFIG_H
     9#ifndef _GIET_CONFIG_H
     10#define _GIET_CONFIG_H
    1111
    1212/* hardware parameters */
    1313#include "hard_config.h"
    1414
    15 
    1615/* Debug parameters */
    1716
    18 #define BOOT_DEBUG_PERI     0                   /* trace peripherals initialisation */
    19 #define BOOT_DEBUG_PT           0                       /* trace page tables initialisation */
    20 #define BOOT_DEBUG_VOBJS        0                       /* trace vobjs initialisation */
    21 #define BOOT_DEBUG_SCHED        0                       /* trace schedulers initialisation */
     17#define BOOT_DEBUG_PERI          1                      /* trace peripherals initialisation */
     18#define BOOT_DEBUG_PT                1                  /* trace page tables initialisation */
     19#define BOOT_DEBUG_VOBJS             1                  /* trace vobjs initialisation */
     20#define BOOT_DEBUG_SCHED             1                  /* trace schedulers initialisation */
    2221
    23 #define GIET_DEBUG_INIT         0                       /* trace parallel kernel initialisation */
    24 #define GIET_DEBUG_SWITCH       0                       /* trace context switchs  */
     22#define GIET_DEBUG_INIT              0                  /* trace parallel kernel initialisation */
     23#define GIET_DEBUG_SWITCH            0                  /* trace context switchs  */
     24#define GIET_DEBUG_IOC_DRIVER    0          /* trace IOC accesses */
     25#define GIET_DEBUG_DMA_DRIVER    0          /* trace DMA accesses */
    2526
    2627#define CONFIG_SRL_VERBOSITY TRACE
     
    2829/* software parameters */
    2930
    30 #define GIET_NB_VSPACE_MAX      64                      /* max number of virtual spaces */
    31 #define GIET_TICK_VALUE     0x100000            /* context switch period (number of cycles) */
     31#define GIET_CLUSTER_INCREMENT   0x100000       /* address increment for replicated peripherals */
     32#define GIET_NB_VSPACE_MAX           64                 /* max number of virtual spaces */
     33#define GIET_TICK_VALUE          0x100000       /* context switch period (number of cycles) */
    3234
    3335#endif
  • soft/giet_vm/libs/memspace.h

    r228 r238  
    1313///////////////////////////////////////////////////////////////////////////////////
    1414
    15 typedef struct _srl_memspace_s {
     15typedef struct _giet_memspace_s
     16{
    1617    void * buffer;
    1718    unsigned int size;
  • soft/giet_vm/libs/stdio.c

    r237 r238  
    103103// This function returns the local processor time (clock cycles since boot)
    104104////////////////////////////////////////////////////////////////////////////////////
    105 unsigned int giet_proctime() {
     105unsigned int giet_proctime()
     106{
    106107    return sys_call(SYSCALL_PROCTIME, 0, 0, 0, 0);
    107108}
     
    118119// - Returns 1 if the character has been written, 0 otherwise.
    119120////////////////////////////////////////////////////////////////////////////////////
    120 unsigned int giet_tty_putc(char byte) {
     121unsigned int giet_tty_putc(char byte)
     122{
    121123    return sys_call(SYSCALL_TTY_WRITE, (unsigned int) (&byte), 1, 0, 0);
    122124}
     
    132134// - Returns the number of written characters.
    133135////////////////////////////////////////////////////////////////////////////////////
    134 unsigned int giet_tty_puts(char * buf) {
     136unsigned int giet_tty_puts(char * buf)
     137{
    135138    unsigned int length = 0;
    136     while (buf[length] != 0) {
    137         length++;
    138     }
     139    while (buf[length] != 0) { length++; }
    139140    return sys_call(SYSCALL_TTY_WRITE, (unsigned int) buf, length, 0, 0);
    140141}
     
    149150// Returns the number of written characters (should be equal to ten).
    150151////////////////////////////////////////////////////////////////////////////////////
    151 unsigned int giet_tty_putw(unsigned int val) {
     152unsigned int giet_tty_putw(unsigned int val)
     153{
    152154    char buf[10];
    153155    unsigned int i;
    154     for (i = 0; i < 10; i++) {
     156    for (i = 0; i < 10; i++)
     157    {
    155158        buf[9 - i] = (val % 10) + 0x30;
    156159        val = val / 10;
     
    168171// - Returns 0 when completed.
    169172////////////////////////////////////////////////////////////////////////////////////
    170 unsigned int giet_tty_getc(char * byte) {
     173unsigned int giet_tty_getc(char * byte)
     174{
    171175    unsigned int ret = 0;
    172     while (ret == 0) {
     176    while (ret == 0)
     177    {
    173178        ret = sys_call(SYSCALL_TTY_READ, (unsigned int)byte, 1, 0, 0);
    174179    }
     
    187192//   will be copied into buffer, and the string is always completed by a NUL
    188193//   character.
    189 // - The <LF> character is interpreted, as the function close the string with a
     194// - The <LF> character is interpreted, and the function close the string with a
    190195//   NUL character if <LF> is read.
    191196// - The <DEL> character is interpreted, and the corresponding character(s) are
    192197//   removed from the target buffer.
    193198////////////////////////////////////////////////////////////////////////////////////
    194 unsigned int giet_tty_gets(char * buf, unsigned int bufsize) {
     199unsigned int giet_tty_gets( char*        buf,
     200                            unsigned int bufsize)
     201{
    195202    unsigned int ret;
    196203    unsigned char byte;
    197204    unsigned int index = 0;
    198205
    199     while (index < (bufsize - 1)) {
    200         do {
    201             ret = sys_call(SYSCALL_TTY_READ, (unsigned int) (&byte), 1, 0, 0);
    202         } while (ret != 1);
    203 
    204         if (byte == 0x0A) {
    205             break; /* LF */
    206         }
    207         else if ((byte == 0x7F) && (index > 0)) {
    208             index--; /* DEL */
    209         }
    210         else {
     206    while (index < (bufsize - 1))
     207    {
     208        do { ret = sys_call(SYSCALL_TTY_READ, (unsigned int) (&byte), 1, 0, 0); }
     209        while (ret != 1);
     210
     211        if (byte == 0x0A)  /* LF */
     212        {
     213            break;
     214        }
     215        else if ((byte == 0x7F) && (index > 0))  /* DEL */
     216        {
     217            index--;
     218        }
     219        else
     220        {
    211221            buf[index] = byte;
    212222            index++;
     
    236246//   bits range, the zero value is returned.
    237247////////////////////////////////////////////////////////////////////////////////////
    238 unsigned int giet_tty_getw(unsigned int * val) {
     248unsigned int giet_tty_getw(unsigned int * val)
     249{
    239250    unsigned char buf[32];
    240251    unsigned char byte;
     
    247258    unsigned int ret;
    248259
    249     while (done == 0) {
    250         do {
    251             ret = sys_call(SYSCALL_TTY_READ, (unsigned int) (&byte), 1, 0, 0);
    252         } while (ret != 1);
    253 
    254         if ((byte > 0x2F) && (byte < 0x3A)) {
    255             /* decimal character */
     260    while (done == 0)
     261    {
     262        do { ret = sys_call(SYSCALL_TTY_READ, (unsigned int) (&byte), 1, 0, 0); }
     263        while (ret != 1);
     264
     265        if ((byte > 0x2F) && (byte < 0x3A))  /* decimal character */
     266        {
    256267            buf[max] = byte;
    257268            max++;
    258269            giet_tty_putc(byte);
    259270        }
    260         else if ((byte == 0x0A) || (byte == 0x0D)) {
    261             /* LF or CR character */
     271        else if ((byte == 0x0A))   /* LF */
     272        {
    262273            done = 1;
    263274        }
    264         else if (byte == 0x7F) {
    265             /* DEL character */
    266             if (max > 0) {
    267                 max--; /* cancel the character */
     275        else if (byte == 0x7F)   /* DEL */
     276        {
     277            if (max > 0)
     278            {
     279                max--;      /* cancel the character */
    268280                giet_tty_putc(0x08);
    269281                giet_tty_putc(0x20);
     
    271283            }
    272284        }
    273         if (max == 32) {
    274             /* decimal string overflow */
    275             for (i = 0; i < max; i++) {
     285        if (max == 32)  /* decimal string overflow */
     286        {
     287            for (i = 0; i < max; i++)
     288            {
    276289                /* cancel the string */
    277290                giet_tty_putc(0x08);
     
    280293            }
    281294            giet_tty_putc(0x30);
    282             *val = 0; /* return 0 value */
     295            *val = 0;      /* return 0 value */
    283296            return 0;
    284297        }
     
    286299
    287300    /* string conversion */
    288     for (i = 0; i < max; i++) {
     301    for (i = 0; i < max; i++)
     302    {
    289303        dec = dec * 10 + (buf[i] - 0x30);
    290         if (dec < save) {
    291             overflow = 1;
    292         }
     304        if (dec < save)  overflow = 1;
    293305        save = dec;
    294306    }
    295307
    296308    /* check overflow */
    297     if (overflow == 0) {
     309    if (overflow == 0)
     310    {
    298311        *val = dec; /* return decimal value */
    299312    }
    300     else {
    301         for (i = 0; i < max; i++) {
     313    else
     314    {
     315        for (i = 0; i < max; i++)
     316        {
    302317            /* cancel the string */
    303318            giet_tty_putc(0x08);
     
    306321        }
    307322        giet_tty_putc(0x30);
    308         *val = 0; /* return 0 value */
     323        *val = 0;         /* return 0 value */
    309324    }
    310325    return 0;
     
    326341// - Returns 0 if success, > 0 if error.
    327342////////////////////////////////////////////////////////////////////////////////////
    328 unsigned int giet_tty_printf(char * format, ...) {
     343unsigned int giet_tty_printf(char * format, ...)
     344{
    329345    va_list ap;
    330346    va_start(ap, format);
     
    333349printf_text:
    334350
    335     while (*format) {
     351    while (*format)
     352    {
    336353        unsigned int i;
    337354        for (i = 0; format[i] && format[i] != '%'; i++);
    338         if (i) {
     355        if (i)
     356        {
    339357            ret = sys_call(SYSCALL_TTY_WRITE, (unsigned int) format, i, 0, 0);
    340             if (ret != i) {
    341                 return 1; /* return error */
    342             }
     358            if (ret != i)  return 1; /* return error */
    343359            format += i;
    344360        }
    345         if (*format == '%') {
     361        if (*format == '%')
     362        {
    346363            format++;
    347364            goto printf_arguments;
  • soft/giet_vm/memo/TODO

    r163 r238  
    11+ Support for debug info
    22+ Search the sections by name, the name should correspond to vobj->name and the adresse should correspond to vseg->addresse
     3+ Documentation
  • soft/giet_vm/memo/include/libelfpp/elfpp/elfpp_object.hh

    r163 r238  
    5959
    6060    /** Copy all header fields of obj and set the access_ variable*/
    61     void copy_info(object& obj);
     61    void copy_info(object& obj, size_t word_width = 0);
    6262
    6363    ~object();
  • soft/giet_vm/memo/include/memo.h

    r212 r238  
    11/* -*- c++ -*-
    22 *
    3  * SOCLIB_LGPL_HEADER_BEGIN
     3 * GIET_VM_LGPL_HEADER_BEGIN
    44 *
    5  * This file is part of SoCLib, GNU LGPLv2.1.
     5 * This file is part of GIET_VM, GNU LGPLv2.1.
    66 *
    7  * SoCLib is free software; you can redistribute it and/or modify it
     7 * GIET_VM is free software; you can redistribute it and/or modify it
    88 * under the terms of the GNU Lesser General Public License as published
    99 * by the Free Software Foundation; version 2.1 of the License.
    1010 *
    11  * SoCLib is distributed in the hope that it will be useful, but
     11 * GIET_VM is distributed in the hope that it will be useful, but
    1212 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1313 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1515 *
    1616 * You should have received a copy of the GNU Lesser General Public
    17  * License along with SoCLib; if not, write to the Free Software
     17 * License along with GIET_VM; if not, write to the Free Software
    1818 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    1919 * 02110-1301 USA
    2020 *
    21  * SOCLIB_LGPL_HEADER_END
     21 * GIET_VM_LGPL_HEADER_END
    2222 *
    2323 * Copyright (c) UPMC, Lip6, SoC
     
    2525 *
    2626 */
    27 #ifndef _MEMO_H_
    28 #define _MEMO_H_
     27
     28#ifndef GIET_VM_MEMO_H
     29#define GIET_VM_MEMO_H
    2930
    3031#include  <stdlib.h>
     
    5758class MeMo
    5859{
     60// TODO: make the name defined in the map_info relative to this wd.
    5961
    60     std::string m_path;         //map_info path name
    61     std::string m_wd;           //map_info path to directory TODO: make the name defined in the map_info relative to this wd.
    62     std::string m_simpleName;   //map_info filename TODO
    63     void* m_data;               //map_info structure
    64     uintptr_t m_addr;           //map_info address (virtual)
    65     size_t m_size;              //size of the structure
     62    std::string                                   m_path;       // map_info path name
     63    std::string                                   m_wd;         // map_info directory TODO
     64    std::string                                   m_simpleName; // map_info filename TODO
     65    void*                                         m_data;       // map_info structure
     66    uintptr_t                                     m_addr;       // map_info address (virtual)
     67    size_t                                        m_size;       // size of the structure
    6668    mutable std::map<std::string, elfpp::object*> m_loaders;
    67     PSegHandler m_psegh;
    68     PathHandler m_pathHandler;
    69    
    70     bool m_ginit;
    71     elfpp::object* m_generator;
     69    PSegHandler                                   m_psegh;
     70    PathHandler                                   m_pathHandler;
     71    bool                                          m_ginit;
     72    elfpp::object*                                m_generator;
    7273
    7374    size_t load_bin(std::string filename, void* buffer);   
     
    7879public:
    7980
    80     MeMo( const std::string &name, const size_t pageSize = 4096);
     81    MeMo( const std::string   &name,
     82          const size_t        pageSize = 4096);
     83
    8184    ~MeMo();
    8285
     
    9396    }
    9497
     98    // The following functions handle the map.bin structure
     99    // They must keep synchronised with functions defined in boot_init.c.
    95100
    96     //The following functions handle the map.bin structure
    97     //inspired from the boot_init.c of the GIET
    98101    mapping_cluster_t* get_cluster_base( mapping_header_t* header );
    99102    mapping_pseg_t* get_pseg_base( mapping_header_t* header );
     
    108111
    109112
    110 #endif /* _MEMO_H_ */
     113#endif /* GIET_VM_MEMO_H */
    111114
    112115// Local Variables:
  • soft/giet_vm/memo/include/pseg.h

    r210 r238  
    11/* -*- c++ -*-
    22 *
    3  * SOCLIB_LGPL_HEADER_BEGIN
     3 * GIET-VM_LGPL_HEADER_BEGIN
    44 *
    5  * This file is part of SoCLib, GNU LGPLv2.1.
     5 * This file is part of the GIET-VMS, GNU LGPLv2.1.
    66 *
    7  * SoCLib is free software; you can redistribute it and/or modify it
     7 * The GIET-VM is free software; you can redistribute it and/or modify it
    88 * under the terms of the GNU Lesser General Public License as published
    99 * by the Free Software Foundation; version 2.1 of the License.
    1010 *
    11  * SoCLib is distributed in the hope that it will be useful, but
     11 * THe GIET-VM is distributed in the hope that it will be useful, but
    1212 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1313 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1919 * 02110-1301 USA
    2020 *
    21  * SOCLIB_LGPL_HEADER_END
     21 * GIET-VM_LGPL_HEADER_END
    2222 *
    2323 * Copyright (c) UPMC, Lip6, SoC
     
    2525 *         
    2626 */
    27 #ifndef SOCLIB_PSEG_H_
    28 #define SOCLIB_PSEG_H_
     27#ifndef GIET_MEMO_PSEG_H
     28#define GIET_MEMO_PSEG_H
    2929
    3030#include <string>
     
    3939class MeMo;
    4040
     41//////////
    4142class VSeg
    4243{
     
    4546    friend class MeMo;
    4647
    47     std::string m_name;
    48     std::string m_file;
    49     uintptr_t m_vma;   //The address of the section to load in the binary file.
    50     uintptr_t m_lma;   //Physical address to which we load the seg (getted from the associated PSeg), setted by PSeg::add/addIdent.
    51     size_t m_length;
    52     size_t m_type;
    53     bool m_loadable;     // wether this is a loadable vseg ( code, data...)
     48    typedef unsigned long long paddr_t;
     49
     50    std::string m_name;     // vseg name
     51    std::string m_file;     // file name
     52    uintptr_t   m_vma;      // Virtual address of the section to load in the binary file.
     53    paddr_t     m_lma;      // Physical address 
     54    size_t      m_length;
     55    size_t      m_type;
     56    bool        m_loadable; // loadable vseg ( code, data...)
    5457
    5558public:
    56     bool m_ident;//Indicate if the idententy mapping is activited. used by PSegHandler::makeIdent()
     59
     60    bool        m_ident;    // identity mapping required if true
    5761
    5862    const std::string& name() const;
    5963    const std::string& file() const;
    6064    uintptr_t vma() const;
    61     uintptr_t lma() const;
     65    paddr_t lma() const;
    6266    size_t length() const;
    6367    size_t type() const;
     
    7579    VSeg();
    7680    VSeg( const VSeg &ref );
    77     VSeg(std::string& binaryName, std::string& name, uintptr_t vma, size_t length, bool loadable, bool ident);
     81    VSeg(std::string&   binaryName,
     82         std::string&   name,
     83         uintptr_t      vma,
     84         size_t         length,
     85         bool           loadable,
     86         bool           ident);
    7887
    7988    ~VSeg();
    8089};
    8190
    82 
     91//////////
    8392class PSeg
    8493{
    85     std::string m_name;
    86     uintptr_t m_lma;
    87     size_t m_length;
    88     size_t m_type;
     94    std::string   m_name;
     95    paddr_t      m_lma;
     96    paddr_t      m_length;
     97    size_t        m_type;
    8998
    90     uintptr_t m_pageLimit;  //The end (m_lma + m_length)  address of the segment pageSize aligned
    91     uintptr_t m_nextLma;    //next free base
     99    paddr_t       m_pageLimit;  // m_lma + m_length aligned on page size
     100    paddr_t       m_nextLma;    // next free base
    92101   
    93     void confNextLma();     //check that m_nextLma has a correct value: whithin the seg limits
     102    void confNextLma();         // check m_nextLma is whithin the seg limits
    94103
    95104public:
     105
    96106    std::vector<VSeg> m_vsegs;
    97     uintptr_t m_limit;// m_lma + m_length
    98107
     108    paddr_t     m_limit;        // m_lma + m_length
    99109
    100110    const std::string& name() const;
    101     uintptr_t lma() const;
    102     size_t length() const;
     111    paddr_t lma() const;
     112    paddr_t length() const;
    103113    size_t type() const;
    104     uintptr_t limit() const;
    105     uintptr_t nextLma() const;
     114    paddr_t limit() const;
     115    paddr_t nextLma() const;
    106116
    107117    void check() const;
    108118
    109119    void setName(std::string& name);
    110     void setLma( uintptr_t lma);
    111     void setLength(size_t length);
     120    void setLma( paddr_t lma);
     121    void setLength(paddr_t length);
    112122
    113     static size_t align( unsigned toAlign, unsigned alignPow2);
    114     static size_t pageAlign( size_t toAlign );
     123    static paddr_t align( paddr_t toAlign, unsigned alignPow2);
     124    static paddr_t pageAlign( paddr_t toAlign );
     125
    115126    static void setPageSize(size_t pg);
     127
    116128    static size_t& pageSize();
    117129
    118     void add( VSeg& vseg );//add a VSeg
     130    void add( VSeg& vseg );    //add a VSeg
    119131    void addIdent( VSeg& vseg );
    120132
    121     void setNextLma( uintptr_t nextLma);
    122     void incNextLma( size_t inc_next);
     133    void setNextLma( paddr_t nextLma);
     134    void incNextLma( size_t inc);
    123135
    124136    void print( std::ostream &o ) const;
     
    134146    PSeg( const PSeg &ref );
    135147    PSeg( const std::string &name);
    136     PSeg( const uintptr_t lma);
     148    PSeg( const paddr_t lma);
    137149    PSeg( const std::string &name,
    138                      uintptr_t lma,
    139              size_t length,
    140              size_t type);
     150          paddr_t lma,
     151          paddr_t length,
     152          size_t type);
    141153    ~PSeg();
    142154};
    143155
    144156
    145 #endif /* SOCLIB_PSEG_H_ */
     157#endif /* GIET_MEMO_PSEG_H */
  • soft/giet_vm/memo/src/libelfpp/elfpp_object.cc

    r163 r238  
    129129   
    130130
    131   void object::copy_info(object& obj)
    132   {
    133     this->word_width_  = obj.word_width_ ;
     131  void object::copy_info(object& obj, size_t word_width)
     132  {
     133
     134        if(word_width == 32)
     135                this->word_width_  = ELFCLASS32;
     136        else if(word_width == 64)
     137            this->word_width_  =  ELFCLASS64;
     138        else
     139            this->word_width_  = obj.word_width_ ;
     140
    134141    this->byteorder_  = obj.byteorder_ ;
    135142    this->machine_  = obj.machine_ ;
  • soft/giet_vm/memo/src/memo.cpp

    r215 r238  
    11/* -*- c++ -*-
    22 *
    3  * SOCLIB_LGPL_HEADER_BEGIN
     3 * GIET_VM_LGPL_HEADER_BEGIN
    44 *
    5  * This file is part of SoCLib, GNU LGPLv2.1.
     5 * This file is part of GIET_VM, GNU LGPLv2.1.
    66 *
    7  * SoCLib is free software; you can redistribute vSO and/or modify vSO
     7 * GIET_VM is free software; you can redistribute it and/or modify it
    88 * under the terms of the GNU Lesser General Public License as published
    99 * by the Free Software Foundation; version 2.1 of the License.
    1010 *
    11  * SoCLib is distributed in the hope that vSO will be useful, but
     11 * GIET_VM is distributed in the hope that it will be useful, but
    1212 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1313 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1515 *
    1616 * You should have received a copy of the GNU Lesser General Public
    17  * License along with SoCLib; if not, write to the Free Software
     17 * License along with GIET_VM; if not, write to the Free Software
    1818 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    1919 * 02110-1301 USA
    2020 *
    21  * SOCLIB_LGPL_HEADER_END
     21 * GIET_VM_LGPL_HEADER_END
    2222 *
    2323 * Copyright (c) UPMC, Lip6, SoC
     
    4141//#define MOVER_DEBUG
    4242
    43 MeMo::MeMo( const std::string &filename,
    44         const size_t pageSize)
    45         :m_path(filename),
    46         m_pathHandler(filename),
    47         m_ginit(false),
    48         m_generator(new elfpp::object())
    49 {
    50    
     43////////////////////////////////////////////
     44MeMo::MeMo( const std::string     &filename,
     45            const size_t          pageSize)
     46        : m_path(filename),
     47          m_pathHandler(filename),
     48          m_ginit(false),
     49          m_generator(new elfpp::object())
     50{
    5151    PSeg::setPageSize(pageSize);
    5252
    53     /* loading map_info blob */
     53    // loading map_info blob
    5454    m_data = std::malloc(bin_size(m_path));
    5555    if ( !m_data )
     
    5858    m_size = load_bin(m_path, m_data);
    5959
    60     /* checking signature */
     60    // checking signature
    6161    mapping_header_t*   header = (mapping_header_t*)m_data;
    62     //assert((IN_MAPPING_SIGNATURE == header->signature) and "wrong signature");
    6362    if((IN_MAPPING_SIGNATURE != header->signature))
    6463    {
    65         std::cout  << "wrong signature " << std::hex <<header->signature << ", should be:"<< IN_MAPPING_SIGNATURE << std::endl;
     64        std::cout  << "wrong signature "
     65                   << std::hex <<header->signature
     66                   << ", should be:"<< IN_MAPPING_SIGNATURE << std::endl;
    6667        exit(1);
    6768    }
    68    
    69    
    7069
    7170#ifdef MOVER_DEBUG
     
    9291}
    9392
     93/////////////////////////////////////////
    9494void MeMo::print( std::ostream &o ) const
    9595{
     
    102102}
    103103
     104////////////////////////////////
    104105void MeMo::print_mapping() const
    105106{
     
    107108}
    108109
     110////////////////////////////////////////////////////////////////////////////////
    109111elfpp::section* MeMo::get_sect_by_addr(elfpp::object *loader, unsigned int addr)
    110112{
     
    123125}
    124126
    125 
     127/////////////////////////////////////////////////
    126128void MeMo::buildSoft(const std::string &filename)
    127129{
     
    133135}
    134136
    135 /* Load the content of filename in buffer, and send the size */
    136 ////////////////////////////////////////////////////////
     137/////////////////////////////////////////////////////////
    137138size_t MeMo::load_bin(std::string filename, void* buffer)
    138139{
    139140
    140141#ifdef MOVER_DEBUG
    141     std::cout  << "Trying to load the binary blob from file '" << filename << "'" << std::endl;
     142    std::cout  << "Loading binary blob from file '" << filename << "'" << std::endl;
    142143#endif
    143144
     
    339340void MeMo::vseg_map( mapping_vseg_t* vseg)
    340341{
    341     mapping_vobj_t*     vobj   = get_vobj_base( (mapping_header_t*) m_data );
    342     PSeg *ps = &(m_psegh.get(vseg->psegid));// get physical segment pointer(PSegHandler::get)
    343     elfpp::section* sect = NULL;
    344     size_t cur_vaddr;
    345     size_t cur_paddr;
    346     bool first = true;
    347     bool aligned = false;
    348 
    349     VSeg   *vSO = new VSeg;
     342    mapping_vobj_t*  vobj   = get_vobj_base( (mapping_header_t*) m_data );
     343    PSeg             *ps = &(m_psegh.get(vseg->psegid));
     344    elfpp::section*  sect = NULL;
     345    size_t           cur_vaddr;
     346    paddr_t          cur_paddr;
     347    bool             first = true;
     348    bool             aligned = false;
     349    VSeg*            vSO = new VSeg;
     350    mapping_vobj_t*  cur_vobj;
    350351
    351352    vSO->m_name = std::string(vseg->name);
    352     vSO->m_vma = vseg->vbase;
    353     vSO->m_lma = ps->nextLma();
     353    vSO->m_vma  = vseg->vbase;
     354    vSO->m_lma  = ps->nextLma();
    354355
    355356    cur_vaddr = vseg->vbase;
    356357    cur_paddr = ps->nextLma();
    357358
    358     mapping_vobj_t* cur_vobj;
    359359    size_t simple_size = 0; //for debug
    360360
    361361#ifdef MOVER_DEBUG
    362     std::cout << "--------------------vseg_map "<< vseg->name <<"---------------------" << std::endl;
    363 #endif
    364 
    365     for ( size_t vobj_id = vseg->vobj_offset ; vobj_id < (vseg->vobj_offset + vseg->vobjs) ; vobj_id++ )
     362std::cout << "--------------- vseg_map "<< vseg->name <<" ------------------" << std::endl;
     363#endif
     364
     365    for ( size_t vobj_id = vseg->vobj_offset ;
     366          vobj_id < (vseg->vobj_offset + vseg->vobjs) ; vobj_id++ )
    366367    {
    367368        cur_vobj = &vobj[vobj_id];
    368369
    369370#ifdef MOVER_DEBUG
    370         std::cout << std::hex << "current vobj("<< vobj_id <<"): " << cur_vobj->name << " (" <<cur_vobj->vaddr << ")"
    371                         << " size: "<< cur_vobj->length << " type: " <<  cur_vobj->type << std::endl;
     371std::cout << std::hex << "current vobj("<< vobj_id <<"): " << cur_vobj->name
     372          << " (" <<cur_vobj->vaddr << ")"
     373          << " size: "<< cur_vobj->length
     374          << " type: " <<  cur_vobj->type << std::endl;
    372375#endif
    373376        if(cur_vobj->type == VOBJ_TYPE_BLOB)
     
    377380
    378381#ifdef MOVER_DEBUG
    379             std::cout << std::hex << "Handling: " << filePath << " ..." << std::endl;
    380 #endif
    381 
    382             if(!filePath.compare(m_path))    //local blob: map_info
     382std::cout << std::hex << "Handling: " << filePath << " ..." << std::endl;
     383#endif
     384
     385            if(!filePath.compare(m_path))    // local blob: map_info
    383386            {
    384387#ifdef MOVER_DEBUG
    385                 std::cout << "Found the vseg of the mapping info" << std::endl;
     388std::cout << "Found the vseg of the mapping info" << std::endl;
    386389#endif
    387390                blob_size = this->m_size;
     
    391394            {
    392395#ifdef MOVER_DEBUG
    393                 std::cout << "Found an BLOB vseg" << std::endl;
     396std::cout << "Found an BLOB vseg" << std::endl;
    394397#endif
    395398                blob_size = bin_size(filePath);
    396399            }
    397400
    398 
    399             /**creating a new section */
     401            // creating a new section
    400402            sect = new elfpp::section(*m_generator, elfpp::SHT_PROGBITS);
    401403
    402404            sect->set_name(std::string(cur_vobj->name));
    403405            sect->set_flags(elfpp::SHF_ALLOC | elfpp::SHF_WRITE);
    404             sect->set_size(blob_size);//do the malloc for the get_content fonction
     406            sect->set_size(blob_size);  //do the malloc for the get_content fonction
    405407
    406408            assert(sect->get_content());//check allocation
     
    459461                /** Initailising the header of the generator from the first binary,
    460462                ** we suppose that the header is the same for all the binarys **/
    461                 m_generator->copy_info(*loader);
     463                m_generator->copy_info(*loader, 64);
    462464                m_ginit=true;
    463465            }
     
    512514    vSO->m_ident = vseg->ident;
    513515
    514     //should we check that we have the same type for the pseg and vobj?
    515     if(ps->type() != PSEG_TYPE_PERI)//take into acount only vseg who are not of the peri type
    516     {
    517         //set the lma
    518         if ( vseg->ident != 0 )            // identity mapping required
    519             ps->addIdent( *vSO );
    520         else
    521             ps->add( *vSO );
    522     }
    523     if(!sect)
    524         return;
     516    //set the lma for vseg that are not peripherals
     517    if(ps->type() != PSEG_TYPE_PERI)
     518    {
     519        if ( vseg->ident != 0 )    ps->addIdent( *vSO );
     520        else                       ps->add( *vSO );
     521    }
     522
     523    // increment NextLma if required
     524    if(ps->type() == PSEG_TYPE_RAM)
     525    {
     526        ps->incNextLma( vSO->m_length );
     527    }
     528
     529    if(!sect) return;
    525530
    526531#ifdef MOVER_DEBUG
     
    550555#endif
    551556
    552 #ifdef DISTRIBUTED_SCHEDULERS
    553     char found;
    554 #endif
    555 
    556557    for ( size_t cluster_id = 0 ; cluster_id < header->clusters ; cluster_id++ )
    557558    {
    558 
    559 #ifdef DISTRIBUTED_SCHEDULERS
    560         found    = 0;
    561 #endif
    562 
    563559        for ( size_t pseg_id = cluster[cluster_id].pseg_offset ;
    564560              pseg_id < cluster[cluster_id].pseg_offset + cluster[cluster_id].psegs ;
    565561              pseg_id++ )
    566562        {
    567             //build pseg
    568563            std::string name(pseg[pseg_id].name);
    569             PSeg *ps = new PSeg(name, pseg[pseg_id].base, pseg[pseg_id].length, pseg[pseg_id].type);
    570 
    571 #ifdef DISTRIBUTED_SCHEDULERS
    572             if ( (pseg[pseg_id].type == PSEG_TYPE_RAM) && (found == 0) )
    573             {
    574                 ps->incNextLma( (cluster[cluster_id].procs << 12) );
    575                 found  = 1;
    576             }
    577             if(!found){/* we could imagine a cluster without proc, let the giet choose*/ }
    578 #endif
     564            PSeg *ps = new PSeg( name,
     565                                 pseg[pseg_id].base,
     566                                 pseg[pseg_id].length,
     567                                 pseg[pseg_id].type );
    579568            m_psegh.m_pSegs.push_back(*ps);
    580 
    581569        }
    582570    }
  • soft/giet_vm/memo/src/pseg.cpp

    r227 r238  
    11/* -*- c++ -*-
    22 *
    3  * SOCLIB_LGPL_HEADER_BEGIN
     3 * GIET_VM_LGPL_HEADER_BEGIN
    44 *
    55 * This file is part of SoCLib, GNU LGPLv2.1.
     
    1919 * 02110-1301 USA
    2020 *
    21  * SOCLIB_LGPL_HEADER_END
     21 * GIET_VM_LGPL_HEADER_END
    2222 *
    2323 * Copyright (c) UPMC, Lip6, SoC
     
    4343 */
    4444
     45//////////////////////////////////////
    4546const std::string & VSeg::name() const
    4647{
     
    4849}
    4950
     51//////////////////////////////////////
    5052const std::string & VSeg::file() const
    5153{
     
    5355}
    5456
     57///////////////////////////
    5558uintptr_t VSeg::vma() const
    5659{
     
    5861}
    5962
    60 uintptr_t VSeg::lma() const
     63/////////////////////////
     64paddr_t VSeg::lma() const
    6165{
    6266        return m_lma;
    6367}
    6468
     69///////////////////////////
    6570size_t VSeg::length() const
    6671{
     
    6873}
    6974
     75/////////////////////////
    7076size_t VSeg::type() const
    7177{
     
    7379}
    7480
     81/////////////////////////////////////////
    7582void VSeg::print( std::ostream &o ) const
    7683{
     
    7986      << std::setw (8) << std::setfill('0')
    8087      << m_vma << ", to(paddr) 0x"
    81       << std::setw (8) << std::setfill('0')
     88      << std::setw (16) << std::setfill('0')
    8289      << m_lma << ", size: 0x"
    8390      << std::setw (8) << std::setfill('0')
     
    8794}
    8895
     96/////////////
    8997VSeg::~VSeg()
    9098{
    91 //    std::cout << "Deleted VSeg " << *this << std::endl;
    92 }
    93 
     99}
     100
     101/////////////////////////////////////////
    94102VSeg & VSeg::operator=( const VSeg &ref )
    95103{
     
    97105        return *this;
    98106
    99     //std::cout << "Copying " << ref << " to " << *this << std::endl;
    100107    m_name = ref.m_name,
    101108    m_file = ref.m_file;
     
    107114}
    108115
     116////////////
    109117VSeg::VSeg()
    110118    : m_name("No Name"),
     
    115123      m_ident(0)
    116124{
    117     //std::cout << "New empty VSeg " << *this << std::endl;
    118 }
    119 
    120 VSeg::VSeg(std::string& binaryName, std::string& name, uintptr_t vma, size_t length, bool loadable, bool ident)
     125}
     126
     127////////////////////////////////////
     128VSeg::VSeg(std::string&  binaryName,
     129           std::string&  name,
     130           uintptr_t     vma,
     131           size_t        length,
     132           bool          loadable,
     133           bool          ident)
    121134    : m_name(name),
    122135      m_file(binaryName),
     
    126139      m_ident(ident)
    127140{
    128     //std::cout << "New VSeg " << *this << std::endl;
    129 }
    130 
     141}
     142
     143/////////////////////////////
    131144VSeg::VSeg( const VSeg &ref )
    132145    : m_name("To be copied"),
     
    137150      m_ident(0)
    138151{
    139     //std::cout << "New VSeg " << *this << " copied from " << ref << std::endl;
    140152    (*this) = ref;
    141153}
    142 
    143 
    144154
    145155
     
    147157 * PSeg
    148158 */
    149 uintptr_t PSeg::lma() const
     159
     160/////////////////////////
     161paddr_t PSeg::lma() const
    150162{
    151163        return m_lma;
    152164}
    153165
    154 uintptr_t PSeg::limit() const
     166///////////////////////////
     167paddr_t PSeg::limit() const
    155168{
    156169        return m_limit;
    157170}
    158171
    159 size_t PSeg::length() const
     172/////////////////////////////
     173paddr_t PSeg::length() const
    160174{
    161175        return m_length;
    162176}
    163177
     178/////////////////////////
    164179size_t PSeg::type() const
    165180{
     
    167182}
    168183
    169 uintptr_t PSeg::nextLma() const
     184/////////////////////////////
     185paddr_t PSeg::nextLma() const
    170186{
    171187        return m_nextLma;
    172188}
    173189
     190//////////////////////////////////////
    174191const std::string & PSeg::name() const
    175192{
     
    177194}
    178195
     196//////////////////////// initialisation used[][] ??? (AG)
    179197void PSeg::check() const
    180198{
     
    184202
    185203    std::vector<VSeg>::const_iterator it;
    186     size_t size = m_vsegs.size();
    187     size_t used[size][2];//lma, lma+length
    188     size_t i,j,error=0;
     204    size_t    size = m_vsegs.size();
     205    paddr_t   used[size][2];          // lma, lma+length
     206    size_t    i,j,error=0;
    189207   
    190     for(it = m_vsegs.begin(), i= 0; it < m_vsegs.end(); it++, i++)
     208    for(it = m_vsegs.begin(), i= 0 ; it < m_vsegs.end() ; it++, i++)
    191209    {
    192         size_t it_limit = (*it).lma() + (*it).length();
     210        paddr_t it_limit = (*it).lma() + (*it).length();
    193211        for(j=0; j< i; j++)
    194212        {
    195            if(  (used[j][0] == (*it).lma() /*and (*it).length()?*/) ) //not the same lma ,
     213            if( used[j][0] == (*it).lma() ) //not the same lma ,
    196214            {
    197215                error = 1;
    198216                std::cout << "ok \n";
    199217            }
    200            if(  (used[j][1] == it_limit /*and (*it).legth()?*/))  // and not the same limit
     218            if( used[j][1] == it_limit )  // and not the same limit
    201219            {
    202220                error = 2;
    203221            }
    204            if(  ((used[j][0] < (*it).lma()) and ((*it).lma() < used[j][1] )) ) //lma  within the used slice
     222            if( (used[j][0] < (*it).lma()) and ((*it).lma() < used[j][1]) ) // lma  within
    205223            {
    206224                error = 3;
    207225            }
    208            if(  ((used[j][0] < it_limit) and (it_limit < used[j][1] )) )//limit not within the used slice
     226            if(  ((used[j][0] < it_limit) and (it_limit < used[j][1] )) ) // limit no within
    209227            {
    210228                error = 4;
     
    228246}
    229247
     248//////////////////////////////////////
    230249void PSeg::setName(std::string& name )
    231250{
     
    233252}
    234253
    235 size_t PSeg::align( unsigned toAlign, unsigned alignPow2)
    236 {
    237     return ((toAlign + (1 << alignPow2) - 1 ) >> alignPow2) << alignPow2;//page aligned
    238 }
    239 
    240 
    241 size_t PSeg::pageAlign( size_t toAlign )
     254/////////////////////////////////////////////////////////
     255paddr_t PSeg::align( paddr_t toAlign, unsigned alignPow2)
     256{
     257    return ((toAlign + (1 << alignPow2) - 1 ) >> alignPow2) << alignPow2;
     258}
     259
     260//////////////////////////////////////////
     261paddr_t PSeg::pageAlign( paddr_t toAlign )
    242262{
    243263    size_t pgs = pageSize();
    244264    size_t pageSizePow2 = __builtin_ctz(pgs);
    245265   
    246     return align(toAlign, pageSizePow2);//page aligned
    247 
    248 }
    249 
    250 void PSeg::setLma( uintptr_t lma )
     266    return align(toAlign, pageSizePow2);
     267}
     268
     269////////////////////////////////
     270void PSeg::setLma( paddr_t lma )
    251271{
    252272    m_lma = lma;
    253273   
    254     m_nextLma = pageAlign(lma);//page aligned
     274    m_nextLma = pageAlign(lma);
    255275
    256276    m_pageLimit = pageAlign(m_lma+m_length);
    257277
    258278    m_limit = (m_lma + m_length);
    259 
    260 }
    261 
    262 void PSeg::setLength( size_t length )
     279}
     280
     281/////////////////////////////////////
     282void PSeg::setLength( paddr_t length )
    263283{
    264284    m_length = length;
     
    267287
    268288    m_limit = (m_lma + m_length);
    269 
    270     //std::cout << std::hex << " length seted, m_limit: " << m_limit  << std::endl;
    271     //std::cout << *this <<std::endl;
    272 }
    273 
     289}
     290
     291////////////////////////////
    274292void PSeg::add( VSeg& vseg )
    275293{
    276294    vseg.m_lma = m_nextLma;
    277     incNextLma(vseg.length());//for the next vseg
     295//    incNextLma(vseg.length());   //for the next vseg
    278296    m_vsegs.push_back(vseg);
    279297}
    280298
     299/////////////////////////////////
    281300void PSeg::addIdent( VSeg& vseg )
    282301{
    283302    vseg.m_lma = vseg.m_vma;
    284     //incNextLma(vseg.length());//to keep track of space used
    285303    m_vsegs.push_back(vseg);
    286304}
    287305
    288 void PSeg::setNextLma( uintptr_t nextLma)
     306/////////////////////////////////////////
     307void PSeg::setNextLma( paddr_t nextLma)
    289308{
    290309    m_nextLma = nextLma;
    291 
    292310    confNextLma();
    293311}
    294312
    295 void PSeg::incNextLma( size_t inc_next)
    296 {
    297 
    298     m_nextLma += inc_next;
    299 
     313//////////////////////////////////
     314void PSeg::incNextLma( size_t inc)
     315{
     316    m_nextLma += inc;
    300317    confNextLma();
    301318}
    302319
     320////////////////////////
    303321void PSeg::confNextLma()
    304322{
     
    322340}
    323341
     342/////////////////////////////////
    324343void PSeg::setPageSize(size_t pg)
    325344{
     
    332351}
    333352
     353////////////////////////
    334354size_t& PSeg::pageSize()
    335355{
     
    338358}
    339359
     360/////////////////////////////////////////
    340361PSeg & PSeg::operator=( const PSeg &ref )
    341362{
    342363    if ( &ref == this )
    343364        return *this;
    344 
    345     //std::cout << "Copying " << ref << " to " << *this << std::endl;
    346365
    347366    m_name = ref.m_name;
     
    357376}
    358377
     378//////////////////////////////////////////
    359379void PSeg::print( std::ostream &o ) const
    360380{
     
    374394}
    375395
     396////////////////////////////////////
    376397PSeg::PSeg( const std::string &name,
    377                 uintptr_t lma,
    378                 size_t length,
    379                 size_t type)
     398            paddr_t          lma,
     399            paddr_t          length,
     400            size_t            type)
    380401{
    381402    m_name = name;
     
    384405
    385406    setLma(lma);
    386     //std::cout <<"New PSeg :"<< *this ;         
    387 }
    388 
     407}
     408
     409////////////////////////////////////
    389410PSeg::PSeg( const std::string &name):
    390411      m_lma(0),
     
    396417}
    397418
    398 PSeg::PSeg( uintptr_t lma):
     419////////////////////////
     420PSeg::PSeg( paddr_t lma):
    399421      m_name("No name"),
    400422      m_lma(0),
     
    406428}
    407429
    408 
     430////////////
    409431PSeg::PSeg()
    410432    :
     
    415437      m_limit(0)
    416438{
    417     //std::cout << "New empty PSeg " << *this << std::endl;
    418 }
    419 
     439}
     440
     441/////////////////////////////
    420442PSeg::PSeg( const PSeg &ref )
    421443    : m_name("To be copied"),
     
    425447      m_limit(0)
    426448{
    427     //std::cout << "New PSeg " << *this << " copied from " << ref << std::endl;
    428449    (*this) = ref;
    429450}
     
    431452PSeg::~PSeg()
    432453{
    433 //    std::cout << "Deleted PSeg " << *this << std::endl;
    434454}
    435455
  • soft/giet_vm/memo/src/pseg_handler.cpp

    r163 r238  
    11/* -*- c++ -*-
    22 *
    3  * SOCLIB_LGPL_HEADER_BEGIN
     3 * GIET_VM_LGPL_HEADER_BEGIN
    44 *
    5  * This file is part of SoCLib, GNU LGPLv2.1.
     5 * This file is part of GIET_VM, GNU LGPLv2.1.
    66 *
    7  * SoCLib is free software; you can redistribute it and/or modify it
     7 * GIET_VM is free software; you can redistribute it and/or modify it
    88 * under the terms of the GNU Lesser General Public License as published
    99 * by the Free Software Foundation; version 2.1 of the License.
    1010 *
    11  * SoCLib is distributed in the hope that it will be useful, but
     11 * GIET_VM is distributed in the hope that it will be useful, but
    1212 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1313 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1515 *
    1616 * You should have received a copy of the GNU Lesser General Public
    17  * License along with SoCLib; if not, write to the Free Software
     17 * License along with GIET_VM; if not, write to the Free Software
    1818 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    1919 * 02110-1301 USA
    2020 *
    21  * SOCLIB_LGPL_HEADER_END
     21 * GIET_VM_LGPL_HEADER_END
    2222 *
    2323 * Copyright (c) UPMC, Lip6, SoC
     
    3737#include "exception.h"
    3838
    39 
    40 
    4139/*
    4240 * PSegHandler
    4341 */
    4442
     43/////////////////////////////////////
    4544PSeg& PSegHandler::get( size_t pos  )
    4645{
     
    5554}
    5655
     56//////////////////////////////////////////////////////////////
    5757const PSeg& PSegHandler::getByAddr(uintptr_t segAddress) const
    5858{
     
    6060    for(it = m_pSegs.begin(); it < m_pSegs.end(); it++)
    6161    {
    62         uintptr_t lma = (*it).lma();
     62        paddr_t lma = (*it).lma();
    6363        if( lma == segAddress )
    6464            return *it;
     
    7171}
    7272
     73///////////////////////////////
    7374void PSegHandler::check() const
    7475{
  • soft/giet_vm/sys/common.c

    r232 r238  
    2020///////////////////////////////////////////////////////////////////////////////////
    2121
    22 // current context cache TODO
    23 
    2422// SR save (used by _it_mask() / it_restore()
    2523unsigned int _status_register_save[NB_CLUSTERS*NB_PROCS_MAX];
     
    2725///////////////////////////////////////////////////////////////////////////////////
    2826//       _get_sched()
    29 // Access CP0 and returns scheduler physical address.
    30 ///////////////////////////////////////////////////////////////////////////////////
    31 inline unsigned int _get_sched() {
    32     unsigned int ret;
    33     asm volatile(
    34             "mfc0    %0,        $22"
    35             : "=r"(ret));
    36     return ret;
    37 }
    38 
     27// Access CP0 and returns a pointer (virtual address) on the calling
     28// processor scheduler (taking into account the processor local index).
     29///////////////////////////////////////////////////////////////////////////////////
     30static_scheduler_t* _get_sched()
     31{
     32    static_scheduler_t* psched;
     33    unsigned int        vaddr;
     34    unsigned int        lpid = _procid() % NB_PROCS_MAX;
     35
     36    asm volatile(
     37            "mfc0    %0,   $22    \n"
     38            : "=r"(vaddr) );
     39
     40    psched = (static_scheduler_t*)vaddr;
     41    return (psched + lpid);
     42}
    3943
    4044///////////////////////////////////////////////////////////////////////////////////
     
    4246// Access CP2 and returns PTPR register.
    4347///////////////////////////////////////////////////////////////////////////////////
    44 inline unsigned int _get_ptpr() {
     48inline unsigned int _get_ptpr()
     49{
    4550    unsigned int ret;
    4651    asm volatile(
     
    5055}
    5156
    52 
    5357///////////////////////////////////////////////////////////////////////////////////
    5458//       _get_epc()
    5559// Access CP0 and returns EPC register.
    5660///////////////////////////////////////////////////////////////////////////////////
    57 inline unsigned int _get_epc() {
     61inline unsigned int _get_epc()
     62{
    5863    unsigned int ret;
    5964    asm volatile("mfc0    %0,        $14"
     
    6267}
    6368
    64 
    6569///////////////////////////////////////////////////////////////////////////////////
    6670//       _get_bar()
    6771// Access CP0 and returns BAR register.
    6872///////////////////////////////////////////////////////////////////////////////////
    69 inline unsigned int _get_bvar() {
     73inline unsigned int _get_bvar()
     74{
    7075    unsigned int ret;
    7176    asm volatile(
     
    7580}
    7681
    77 
    7882///////////////////////////////////////////////////////////////////////////////////
    7983//       _get_cr()
    8084// Access CP0 and returns CR register.
    8185///////////////////////////////////////////////////////////////////////////////////
    82 inline unsigned int _get_cause() {
     86inline unsigned int _get_cause()
     87{
    8388    unsigned int ret;
    8489    asm volatile("mfc0    %0,        $13"
     
    8792}
    8893
    89 
    9094///////////////////////////////////////////////////////////////////////////////////
    9195//       _get_sr()
    9296// Access CP0 and returns SR register.
    9397///////////////////////////////////////////////////////////////////////////////////
    94 inline unsigned int _get_sr() {
     98inline unsigned int _get_sr()
     99{
    95100    unsigned int ret;
    96101    asm volatile(
     
    106111// This function is NOT USED and NOT TESTED
    107112///////////////////////////////////////////////////////////////////////////////////
    108 inline void _it_mask() {
     113inline void _it_mask()
     114{
    109115    unsigned int sr_value;
    110116    unsigned int proc_id;
     
    121127}
    122128
    123 
    124129///////////////////////////////////////////////////////////////////////////////////
    125130//    _it_restore()
     
    128133// This function is NOT USED and NOT TESTED
    129134///////////////////////////////////////////////////////////////////////////////////
    130 inline void _it_restore() {
     135inline void _it_restore()
     136{
    131137    unsigned int proc_id;
    132138    // get the processor id to index the _status_register_save table
     
    140146// Access CP0 and disables IRQs
    141147///////////////////////////////////////////////////////////////////////////////////
    142 inline void _it_disable() {
     148inline void _it_disable()
     149{
    143150    asm volatile(
    144151            "li      $3,        0xFFFFFFFE    \n"
     
    153160// Access CP0 and enables IRQs
    154161///////////////////////////////////////////////////////////////////////////////////
    155 inline void _it_enable() {
     162inline void _it_enable()
     163{
    156164    asm volatile(
    157165            "li      $3,        0x00000001    \n"
     
    162170}
    163171
    164 
    165172////////////////////////////////////////////////////////////////////////////
    166173//    _get_lock()
     
    169176// (delay average value = 100 cycles)
    170177////////////////////////////////////////////////////////////////////////////
    171 inline void _get_lock(unsigned int * plock) {
     178inline void _get_lock(unsigned int * plock)
     179{
    172180    register unsigned int delay = ( _proctime() ^ _procid() << 4) & 0xFF;
    173181
     
    191199}
    192200
    193 
    194201////////////////////////////////////////////////////////////////////////////
    195202// _release_lock()
    196203////////////////////////////////////////////////////////////////////////////
    197 inline void _release_lock(unsigned int * plock) {
     204inline void _release_lock(unsigned int * plock)
     205{
    198206    asm volatile (
    199207            "sync\n" /* necessary because of the consistency model in tsar */
     
    202210}
    203211
    204 
    205212////////////////////////////////////////////////////////////////////////////
    206213//    _puts()
    207214// display a string on TTY0 / used for system code debug and log
    208215////////////////////////////////////////////////////////////////////////////
    209 void _puts(char * buffer) {
     216void _puts(char * buffer)
     217{
    210218    unsigned int * tty_address = (unsigned int *) &seg_tty_base;
    211219    unsigned int n;
    212220
    213     for (n = 0; n < 100; n++) {
    214         if (buffer[n] == 0) {
    215             break;
    216         }
     221    for (n = 0; n < 100; n++)
     222    {
     223        if (buffer[n] == 0)  break;
    217224        tty_address[TTY_WRITE] = (unsigned int) buffer[n];
    218225    }
    219226}
    220227
    221 
    222228////////////////////////////////////////////////////////////////////////////
    223229//    _putx()
    224 // display an int (hexa) on TTY0 / used for system code debug and log
    225 ////////////////////////////////////////////////////////////////////////////
    226 void _putx(unsigned int val) {
     230// display a 32 bits unsigned int as an hexadecimal string on TTY0
     231////////////////////////////////////////////////////////////////////////////
     232void _putx(unsigned int val)
     233{
    227234    static const char HexaTab[] = "0123456789ABCDEF";
    228235    char buf[11];
     
    233240    buf[10] = 0;
    234241
    235     for (c = 0; c < 8; c++) {
     242    for (c = 0; c < 8; c++)
     243    {
    236244        buf[9 - c] = HexaTab[val & 0xF];
    237245        val = val >> 4;
     
    240248}
    241249
     250////////////////////////////////////////////////////////////////////////////
     251//    _putl()
     252// display a 64 bits unsigned long as an hexadecimal string on TTY0
     253////////////////////////////////////////////////////////////////////////////
     254void _putl(paddr_t val)
     255{
     256    static const char HexaTab[] = "0123456789ABCDEF";
     257    char buf[19];
     258    unsigned int c;
     259
     260    buf[0] = '0';
     261    buf[1] = 'x';
     262    buf[18] = 0;
     263
     264    for (c = 0; c < 16; c++)
     265    {
     266        buf[17 - c] = HexaTab[(unsigned int)val & 0xF];
     267        val = val >> 4;
     268    }
     269    _puts(buf);
     270}
    242271
    243272////////////////////////////////////////////////////////////////////////////
     
    266295}
    267296
    268 
    269297////////////////////////////////////////////////////////////////////////////
    270298//    _strncmp()
     
    284312}
    285313
    286 
    287314////////////////////////////////////////////////////////////////////////////
    288315//        _dcache_buf_invalidate()
     
    310337}
    311338
    312 
    313 ////////////////////////////////////////////////////////////////////////////
    314 //    _physical_read_access()
    315 // This function makes a physical read access to a 32 bits word in memory,
    316 // after a temporary DTLB desactivation.
    317 ////////////////////////////////////////////////////////////////////////////
    318 unsigned int _physical_read_access(unsigned int * paddr) {
    319     unsigned int value;
    320 
    321     asm volatile(
    322             "li     $3,     0xFFFFFFFE         \n"
    323             "mfc0   $2,     $12                \n"        /* $2 <= SR        */
    324             "and    $3,     $3,        $2      \n"
    325             "mtc0   $3,     $12                \n"        /* interrupt masked */
    326             "li     $3,     0xB                \n"
    327             "mtc2   $3,     $1                 \n"        /* DTLB off            */   
    328 
    329             "lw     %0,     0(%1)              \n"        /* entry <= *pslot    */
    330 
    331             "li     $3,     0xF                \n"
    332             "mtc2   $3,     $1                 \n"        /* DTLB on             */   
    333             "mtc0   $2,     $12                \n"        /* restore SR        */
    334             : "=r" (value)
    335             : "r" (paddr)
    336             : "$2", "$3");
    337     return value;
    338 }
    339 
    340 
    341 ////////////////////////////////////////////////////////////////////////////
    342 //    _physical_write_access()
    343 // This function makes a physical write access to a 32 bits word in memory,
    344 // after a temporary DTLB desactivation.
    345 ////////////////////////////////////////////////////////////////////////////
    346 void _physical_write_access(unsigned int * paddr, unsigned int value) {
    347     asm volatile(
    348             "li     $3,     0xFFFFFFFE         \n"
    349             "mfc0   $2,     $12                \n"        /* $26 <= SR        */
    350             "and    $3,     $3,        $2      \n"
    351             "mtc0   $3,     $12                \n"        /* interrupt masked */
    352             "li     $3,     0xB                \n"
    353             "mtc2   $3,     $1                 \n"        /* DTLB off            */
    354 
    355             "sw     %0,     0(%1)              \n"        /* entry <= *pslot    */
    356 
    357             "li     $3,     0xF                \n"
    358             "mtc2   $3,     $1                 \n"        /* DTLB on             */   
    359             "mtc0   $2,     $12                \n"        /* restore SR        */
    360             :
    361             : "r" (value), "r" (paddr)
    362             : "$2", "$3");
    363 }
    364 
    365 
    366 ////////////////////////////////////////////////////////////////////////////
    367 //    _get_tasks_number()
    368 // This function returns the number of tasks allocated to processor.
    369 ////////////////////////////////////////////////////////////////////////////
    370 unsigned int _get_tasks_number() {
    371     static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
    372     return _physical_read_access(&(psched->tasks));
    373 }
    374 
    375 
    376 ////////////////////////////////////////////////////////////////////////////
    377 //    _get_proc_task_id()
    378 // This function returns the index of the currently running task.
    379 ////////////////////////////////////////////////////////////////////////////
    380 unsigned int _get_proc_task_id() {
    381     static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
    382     return _physical_read_access(&(psched->current));
    383 }
    384 
    385 
    386 ////////////////////////////////////////////////////////////////////////////
    387 //    _set_proc_task_id()
    388 // This function returns the index of the currently running task.
    389 ////////////////////////////////////////////////////////////////////////////
    390 void _set_proc_task_id(unsigned int value) {
    391     static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
    392     _physical_write_access(&(psched->current), value);
    393 }
    394 
    395 
    396 ////////////////////////////////////////////////////////////////////////////
    397 //    _get_global_task_id()
    398 // This function returns the global index of the running task.
    399 ////////////////////////////////////////////////////////////////////////////
    400 unsigned int _get_global_task_id() {
    401   return _get_context_slot(_get_proc_task_id(), CTX_GTID_ID);
    402 }
    403 
    404 
    405 ///////////////////////////////////////////////////////////////////////////////
    406 //    _get_context_slot()
    407 // This function returns a slot content for the task defined by task_id.
    408 ///////////////////////////////////////////////////////////////////////////////
    409 unsigned int _get_context_slot(unsigned int task_id, unsigned int slot_id) {
    410     static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
    411     return _physical_read_access(&(psched->context[task_id][slot_id]));
    412 }
    413 
    414 
    415 ///////////////////////////////////////////////////////////////////////////////
    416 //    _set_context_slot()
    417 // This function returns a slot content for the task defined by task_id.
    418 ///////////////////////////////////////////////////////////////////////////////
    419 void _set_context_slot( unsigned int task_id,
    420         unsigned int slot_id,
    421         unsigned int value) {
    422     static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
    423     _physical_write_access(&(psched->context[task_id][slot_id]), value);
    424 }
    425 
    426 
    427 ////////////////////////////////////////////////////////////////////////////////
    428 //    _get_interrupt_vector_entry()
    429 // This function returns the interrupt_vector entry defined by argument index.
    430 ////////////////////////////////////////////////////////////////////////////////
    431 unsigned int _get_interrupt_vector_entry(unsigned int index) {
    432     static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
    433     return _physical_read_access( &(psched->interrupt_vector[index]));
    434 }
    435 
     339/////////////////////////////////////////////////////////////////////////////
     340//      _get_task_slot()
     341// This function returns the content of a context slot
     342// for the task identified by the ltid argument (local index).
     343/////////////////////////////////////////////////////////////////////////////
     344unsigned int _get_task_slot( unsigned int ltid,
     345                             unsigned int slot )
     346{
     347    static_scheduler_t* psched  = _get_sched();
     348    return psched->context[ltid][slot];
     349}
     350
     351/////////////////////////////////////////////////////////////////////////////
     352//      _set_task_slot()
     353// This function updates the content of a context slot
     354// for the task identified by the ltid argument (local index).
     355/////////////////////////////////////////////////////////////////////////////
     356void _set_task_slot( unsigned int ltid,
     357                     unsigned int slot,
     358                     unsigned int value )
     359{
     360    static_scheduler_t* psched  = _get_sched();
     361    psched->context[ltid][slot] = value;
     362}
     363
     364/////////////////////////////////////////////////////////////////////////////
     365//      _get_context_slot()
     366// This function returns the content of a context slot
     367// for the running task (defined by the scheduler current field).
     368/////////////////////////////////////////////////////////////////////////////
     369unsigned int _get_context_slot( unsigned int slot )
     370{
     371    static_scheduler_t* psched  = _get_sched();
     372    unsigned int        task_id = psched->current;
     373    return psched->context[task_id][slot];
     374}
     375
     376/////////////////////////////////////////////////////////////////////////////
     377//      _set_context_slot()
     378// This function updates the content of a context slot for the running task.
     379/////////////////////////////////////////////////////////////////////////////
     380void _set_context_slot( unsigned int slot,
     381                       unsigned int value )
     382{
     383    static_scheduler_t* psched  = _get_sched();
     384    unsigned int        task_id = psched->current;
     385    psched->context[task_id][slot] = value;
     386}
    436387
    437388/////////////////////////////////////////////////////////////////////////////
    438389//      access functions to mapping_info data structure
    439390/////////////////////////////////////////////////////////////////////////////
    440 mapping_cluster_t * _get_cluster_base(mapping_header_t * header) {
     391mapping_cluster_t * _get_cluster_base(mapping_header_t * header)
     392{
    441393    return (mapping_cluster_t *) ((char *) header +
    442394            MAPPING_HEADER_SIZE);
    443395}
    444 
    445 
    446 /////////////////////////////////////////////////////////////////////////////
    447 mapping_pseg_t * _get_pseg_base(mapping_header_t * header) {
     396/////////////////////////////////////////////////////////////////////////////
     397mapping_pseg_t * _get_pseg_base(mapping_header_t * header)
     398{
    448399    return (mapping_pseg_t *) ((char *) header +
    449400            MAPPING_HEADER_SIZE +
     
    451402}
    452403/////////////////////////////////////////////////////////////////////////////
    453 mapping_vspace_t * _get_vspace_base(mapping_header_t * header) {
     404mapping_vspace_t * _get_vspace_base(mapping_header_t * header)
     405{
    454406    return (mapping_vspace_t *)  ((char *) header +
    455407            MAPPING_HEADER_SIZE +
     
    471423
    472424/////////////////////////////////////////////////////////////////////////////
    473 mapping_vobj_t * _get_vobj_base(mapping_header_t * header) {
     425mapping_vobj_t * _get_vobj_base(mapping_header_t * header)
     426{
    474427    return (mapping_vobj_t *) ((char *) header +
    475428            MAPPING_HEADER_SIZE +
     
    482435
    483436/////////////////////////////////////////////////////////////////////////////
    484 mapping_task_t * _get_task_base(mapping_header_t * header) {
     437mapping_task_t * _get_task_base(mapping_header_t * header)
     438{
    485439    return (mapping_task_t *) ((char *) header +
    486440            MAPPING_HEADER_SIZE +
  • soft/giet_vm/sys/common.h

    r232 r238  
    1111#include <mapping_info.h>
    1212#include <giet_config.h>
     13#include <ctx_handler.h>
    1314
    1415///////////////////////////////////////////////////////////////////////////////////
     
    3435///////////////////////////////////////////////////////////////////////////////////
    3536
    36 void _puts(char *string);
    37 void _putx(unsigned int val);
    38 void _putd(unsigned int val);
     37void                 _puts(char *string);
     38void                 _putx(unsigned int val);
     39void                 _putd(unsigned int val);
     40void                 _putl(paddr_t val);
    3941
    40 unsigned int _strncmp(const char * s1, const char * s2, unsigned int n);
    41 void _dcache_buf_invalidate(const void * buffer, unsigned int size);
     42unsigned int         _strncmp(const char * s1,
     43                              const char * s2,
     44                              unsigned int n);
    4245
    43 void _dtlb_off(void);
    44 void _dtlb_on(void);
     46void                 _dcache_buf_invalidate(const void * buffer,
     47                                            unsigned int size);
    4548
    46 void _it_mask(void);
    47 void _it_restore(void);
    48 void _it_disable(void);
    49 void _it_enable(void);
     49void                 _dtlb_off(void);
     50void                 _dtlb_on(void);
    5051
    51 unsigned int _get_epc(void);
    52 unsigned int _get_ptpr(void);
    53 unsigned int _get_bvar(void);
    54 unsigned int _get_cr(void);
    55 unsigned int _get_sched(void);
     52void                 _it_mask(void);
     53void                 _it_restore(void);
     54void                 _it_disable(void);
     55void                 _it_enable(void);
    5656
    57 unsigned int _get_context_slot(unsigned int task_id, unsigned int slot_id);
    58 void _set_context_slot(unsigned int task_id, unsigned int slot_id, unsigned int value);
     57unsigned int         _get_epc(void);
     58unsigned int         _get_ptpr(void);
     59unsigned int         _get_bvar(void);
     60unsigned int         _get_cr(void);
    5961
    60 unsigned int _get_interrupt_vector_entry(unsigned int index);
     62static_scheduler_t*  _get_sched(void);
    6163
    62 unsigned int _get_proc_task_id(void);
    63 void _set_proc_task_id(unsigned int value);
     64unsigned int         _get_context_slot( unsigned int slot );
    6465
    65 unsigned int _get_global_task_id(void);
     66void                 _set_context_slot( unsigned int slot,
     67                                        unsigned int value );
    6668
     69unsigned int         _get_task_slot( unsigned int ltid,
     70                                     unsigned int slot );
    6771
    68 unsigned int _get_tasks_number(void);
     72void                 _set_task_slot( unsigned int ltid,
     73                                     unsigned int slot,
     74                                     unsigned int value );
    6975
    70 void _get_lock(unsigned int * lock);
    71 void _release_lock(unsigned int * lock);
     76void                 _get_lock(unsigned int * lock);
     77void                 _release_lock(unsigned int * lock);
    7278
    73 mapping_cluster_t * _get_cluster_base(mapping_header_t* header);
    74 mapping_pseg_t * _get_pseg_base(mapping_header_t* header);
    75 mapping_vspace_t * _get_vspace_base(mapping_header_t* header);
    76 mapping_vseg_t * _get_vseg_base(mapping_header_t* header);
    77 mapping_vobj_t * _get_vobj_base(mapping_header_t* header);
    78 mapping_task_t * _get_task_base(mapping_header_t* header);
     79mapping_cluster_t *  _get_cluster_base(mapping_header_t* header);
     80mapping_pseg_t *     _get_pseg_base(mapping_header_t* header);
     81mapping_vspace_t *   _get_vspace_base(mapping_header_t* header);
     82mapping_vseg_t *     _get_vseg_base(mapping_header_t* header);
     83mapping_vobj_t *     _get_vobj_base(mapping_header_t* header);
     84mapping_task_t *     _get_task_base(mapping_header_t* header);
    7985
    8086
  • soft/giet_vm/sys/ctx_handler.c

    r232 r238  
    2525// A task context is an array of 64 words = 256 bytes.
    2626// It contains copies of processor registers (when the task is preempted):
    27 // - GPR[i], generally stored in slot (i). $0, *26 & $27 are not saved.
     27// - GPR[i], generally stored in slot (i). $0, $26 & $27 are not saved.
    2828// - HI & LO registers
    2929// - CP0 registers: EPC, SR, CR, BVAR
    3030// - CP2 registers : PTPR
    3131// It contains some general informations associated to the task:
    32 // - TTY    : terminal global index
    33 // - FBDMA    : DMA channel global index
     32// - TTY    : TTY channel global index
    3433// - NIC    : NIC channel global index
    35 // - TIMER  : Timer global index
     34// - CMA    : CMA channel global index
     35// - IOC    : IOC channel global index
     36// - DMA    : DMA channel local index
     37// - TIM    : TIM channel local index
    3638// - PTAB   : page table virtual base address
    37 // - LTID    : Task local index (in scheduler)
     39// - LTID   : Task local index (in scheduler)
    3840// - VSID   : Virtual space index
    3941// - RUN    : Task state (0 => sleeping / 1 => runable )
     
    4244// ctx[1]<- $1 |ctx[9] <- $9 |ctx[17]<- $17|ctx[25]<- $25|ctx[33]<- CR   |ctx[41]<- DMA
    4345// ctx[2]<- $2 |ctx[10]<- $10|ctx[18]<- $18|ctx[26]<- LO |ctx[34]<- SR   |ctx[42]<- NIC
    44 // ctx[3]<- $3 |ctx[11]<- $11|ctx[19]<- $19|ctx[27]<- HI |ctx[35]<- BVAR |ctx[43]<- TIMER
    45 // ctx[4]<- $4 |ctx[12]<- $12|ctx[20]<- $20|ctx[28]<- $28|ctx[36]<- ***  |ctx[44]<- PTAB
    46 // ctx[5]<- $5 |ctx[13]<- $13|ctx[21]<- $21|ctx[29]<- SP |ctx[37]<- ***  |ctx[45]<- LTID
    47 // ctx[6]<- $6 |ctx[14]<- $14|ctx[22]<- $22|ctx[30]<- $30|ctx[38]<- ***  |ctx[46]<- VSID
     46// ctx[3]<- $3 |ctx[11]<- $11|ctx[19]<- $19|ctx[27]<- HI |ctx[35]<- BVAR |ctx[43]<- TIM
     47// ctx[4]<- $4 |ctx[12]<- $12|ctx[20]<- $20|ctx[28]<- $28|ctx[36]<- PTAB |ctx[44]<- IOC
     48// ctx[5]<- $5 |ctx[13]<- $13|ctx[21]<- $21|ctx[29]<- SP |ctx[37]<- LTID |ctx[45]<- CMA
     49// ctx[6]<- $6 |ctx[14]<- $14|ctx[22]<- $22|ctx[30]<- $30|ctx[38]<- VSID |ctx[46]<- GTID
    4850// ctx[7]<- $7 |ctx[15]<- $15|ctx[23]<- $23|ctx[31]<- RA |ctx[39]<- PTPR |ctx[47]<- RUN
    4951//////////////////////////////////////////////////////////////////////////////////////////
     
    6062// If there is no runable task, the scheduler switch to the default "idle" task.
    6163//
    62 // Implementation notes:
    63 // - As we only have the scheduler physical address (in CP0_SCHED register),
    64 //   this function must use specific assess functions to access the scheduler.
    65 // - All the context switch procedure is executed with interrupts masked.
    66 // - The return address contained in $31 is saved in the current task context
    67 //   (in the ctx[31] slot), and the function actually returns to the address
    68 //   contained in the ctx[31] slot of the next task context.
     64// Implementation note
     65// The return address contained in $31 is saved in the current task context
     66// (in the ctx[31] slot), and the function actually returns to the address
     67// contained in the ctx[31] slot of the next task context.
    6968/////////////////////////////////////////////////////////////////////////////////
    70 void _ctx_switch() {
    71     // get scheduler physical address
    72     static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
     69void _ctx_switch()
     70{
     71    // get scheduler address
     72    static_scheduler_t* psched = _get_sched();
    7373
    7474    // get number of tasks allocated to scheduler
    75     unsigned int tasks = _get_tasks_number();
     75    unsigned int tasks = psched->tasks;
    7676
    7777    // get current task index
    78     unsigned int curr_task_id = _get_proc_task_id();
     78    unsigned int curr_task_id = psched->current;
    7979
    8080    // select the next task using a round-robin policy
     
    8383    unsigned int found = 0;
    8484
    85     for (tid = curr_task_id + 1; tid < curr_task_id + 1 + tasks; tid++) {
     85    for (tid = curr_task_id + 1; tid < curr_task_id + 1 + tasks; tid++)
     86    {
    8687        next_task_id = tid % tasks;
    87 
    8888        // test if the task is runable
    89         if (_get_context_slot(next_task_id, CTX_RUN_ID)) {
     89        if ( psched->context[next_task_id][CTX_RUN_ID] )
     90        {
    9091            found = 1;
    9192            break;
     
    9495
    9596    // launch "idle" task if no runable task
    96     if (found == 0) {
     97    if (found == 0)
     98    {
    9799        next_task_id = IDLE_TASK_INDEX;
    98100    }
    99101
    100102    // no switch if no change
    101     if (curr_task_id != next_task_id) {
    102         unsigned int * curr_ctx_paddr = &(psched->context[curr_task_id][0]);
    103         unsigned int * next_ctx_paddr = &(psched->context[next_task_id][0]);
     103    if (curr_task_id != next_task_id)
     104    {
     105        unsigned int* curr_ctx_vaddr = &(psched->context[curr_task_id][0]);
     106        unsigned int* next_ctx_vaddr = &(psched->context[next_task_id][0]);
    104107
    105         _set_proc_task_id(next_task_id);
    106         //_timer_reset_irq_cpt(cluster_id, local_id); // commented until not properly supported in soclib
     108        // set current task index
     109        psched->current = next_task_id;
     110
     111        //_timer_reset_irq_cpt(cluster_id, local_id);
     112        // commented until not properly supported in soclib
    107113        // (the function is not yet present in drivers.c)
    108         _task_switch(curr_ctx_paddr, next_ctx_paddr);
     114
     115        _task_switch(curr_ctx_vaddr, next_ctx_vaddr);
    109116
    110117#if GIET_DEBUG_SWITCH
    111         _get_lock(&_tty_put_lock);
    112         _puts("\n[GIET DEBUG] Context switch for processor ");
    113         _putd(_procid());
    114         _puts(" at cycle ");
    115         _putd(_proctime());
    116         _puts("\n");
    117         _puts(" - tasks        = ");
    118         _putd(tasks);
    119         _puts("\n");
    120         _puts(" - curr_task_id = ");
    121         _putd( curr_task_id );
    122         _puts("\n");
    123         _puts(" - next_task_id = ");
    124         _putd(next_task_id);
    125         _puts("\n");
    126         _release_lock( &_tty_put_lock);
     118_get_lock(&_tty_put_lock);
     119_puts("\n[GIET DEBUG] Context switch for processor ");
     120_putd(_procid());
     121_puts(" at cycle ");
     122_putd(_proctime());
     123_puts("\n");
     124_puts(" - tasks        = ");
     125_putd(tasks);
     126_puts("\n");
     127_puts(" - curr_task_id = ");
     128_putd( curr_task_id );
     129_puts("\n");
     130_puts(" - next_task_id = ");
     131_putd(next_task_id);
     132_puts("\n");
     133_release_lock( &_tty_put_lock);
    127134#endif
    128135
     
    133140// This function is executed as the"idle" task when no other task can be executed
    134141/////////////////////////////////////////////////////////////////////////////////////
    135 void _ctx_idle() {
     142void _ctx_idle()
     143{
    136144    unsigned int delay = 1000000;
    137145
     
    164172// in the "idle" task context.
    165173/////////////////////////////////////////////////////////////////////////////////
    166 void _ctx_eret() {
     174void _ctx_eret()
     175{
    167176    asm volatile("eret");
    168177}
  • soft/giet_vm/sys/ctx_handler.h

    r232 r238  
    88/////////////////////////////////////////////////////////////////////////////////
    99
    10 typedef struct static_scheduler_s {
     10typedef struct static_scheduler_s
     11{
    1112    unsigned int context[15][64];      // at most 15 task contexts
    1213    unsigned int tasks;                // actual number of tasks
     
    2930#define CTX_RA_ID        31
    3031
    31 #define CTX_EPC_ID       32
    32 #define CTX_CR_ID        33
    33 #define CTX_SR_ID        34
    34 #define CTX_BVAR_ID      35
     32#define CTX_EPC_ID       32  // Exception Program Counter (CP0)
     33#define CTX_CR_ID        33  // Cause Register (CP0)
     34#define CTX_SR_ID        34  // Status Register (CP0)
     35#define CTX_BVAR_ID      35      // Bad Virtual Address Register (CP0)
    3536
    36 #define CTX_PTPR_ID      39
     37#define CTX_PTAB_ID      36  // Page Table Virtual address
     38#define CTX_LTID_ID      37  // Local  Task Index (in scheduler)
     39#define CTX_VSID_ID      38  // Vspace Index     
     40#define CTX_PTPR_ID      39  // Page Table Pointer Register (PADDR>>13)
    3741
    38 #define CTX_TTY_ID       40  // Integer : global TTY terminal index
    39 #define CTX_DMA_ID       41  // Integer : global DMA channel index
    40 #define CTX_NIC_ID       42  // Integer : global NIC channel index
    41 #define CTX_TIMER_ID     43  // Integer : user level timer index / UNUSED
    42 #define CTX_PTAB_ID      44  // Pointer : page table virtual base adress
    43 #define CTX_LTID_ID      45  // Integer : local task index (in scheduler) / UNUSED
    44 #define CTX_VSID_ID      46  // Integer : vspace index
    45 #define CTX_RUN_ID       47  // Boolean : task runable
    46 #define CTX_GTID_ID      48  // Integer : Global task id
     42#define CTX_TTY_ID       40  // global TTY terminal 
     43#define CTX_DMA_ID       41  // local DMA channel
     44#define CTX_NIC_ID       42  // global NIC channel
     45#define CTX_TIM_ID       43  // local TIMER channel
     46#define CTX_IOC_ID       44  // global IOC channel
     47#define CTX_CMA_ID       45  // global CMA channel index (in scheduler) / UNUSED
     48#define CTX_GTID_ID      46  // Global Task Index
     49#define CTX_RUN_ID       47  // Boolean: task runable
    4750
    4851//////////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/sys/drivers.c

    r237 r238  
    11///////////////////////////////////////////////////////////////////////////////////
    22// File     : drivers.c
    3 // Date     : 01/04/2012
     3// Date     : 23/05/2013
    44// Author   : alain greiner
    55// Copyright (c) UPMC-LIP6
     
    1616// - vci_block_device
    1717//
    18 // The following global parameters must be defined in the giet_config.h file:
    19 // - CLUSTER_SIZE
     18// For the peripherals replicated in each cluster (ICU, TIMER, DMA),
     19// the corresponding (virtual) base addresses must be completed by an offset
     20// depending on the cluster index.
     21//
     22// The following global parameter must be defined in the giet_config.h file:
     23// - GIET_CLUSTER_INCREMENT
     24//
     25// The following global parameters must be defined in the hard_config.h file:
    2026// - NB_CLUSTERS   
    2127// - NB_PROCS_MAX 
    22 // - NB_TIMERS_MAX   
    23 // - NB_DMAS_MAX     
    24 // - NB_TTYS   
     28// - NB_TIM_CHANNELS   
     29// - NB_DMA_CHANNELS     
     30// - NB_TTY_CHANNELS_MAX   
    2531//
    2632// The following virtual base addresses must be defined in the giet_vsegs.ld file:
    2733// - seg_icu_base
    2834// - seg_tim_base
     35// - seg_dma_base
    2936// - seg_tty_base
    3037// - seg_gcd_base
    31 // - seg_dma_base
    3238// - seg_fbf_base
    3339// - seg_ioc_base
    3440// - seg_nic_base
    35 // As some peripherals can be replicated in the clusters (ICU, TIMER, DMA)
    36 // These addresses must be completed by an offset depending on the cluster index
    37 //    full_base_address = seg_***_base + cluster_id * CLUSTER_SIZE
     41// - seg_cma_base
     42// - seg_iob_base
     43//
    3844///////////////////////////////////////////////////////////////////////////////////
    3945
     
    4854
    4955#if !defined(NB_CLUSTERS)
    50 # error: You must define NB_CLUSTERS in the configs file
     56# error: You must define NB_CLUSTERS in the hard_config.h file
    5157#endif
    5258
    5359#if !defined(NB_PROCS_MAX)
    54 # error: You must define NB_PROCS_MAX in the configs file
     60# error: You must define NB_PROCS_MAX in the hard_config.h file
    5561#endif
    5662
     
    5965#endif
    6066
    61 #if !defined(CLUSTER_SIZE)
    62 # error: You must define CLUSTER_SIZE in the configs file
    63 #endif
    64 
    65 #if !defined(NB_TTYS)
    66 # error: You must define NB_TTYS in the configs file
    67 #endif
    68 
    69 #if (NB_TTYS < 1)
    70 # error: NB_TTYS cannot be smaller than 1!
    71 #endif
    72 
    73 #if !defined(NB_DMAS_MAX)
    74 #define NB_DMAS_MAX 0
    75 #endif
    76 
    77 #if !defined(NB_TIMERS_MAX)
    78 #define NB_TIMERS_MAX 0
    79 #endif
    80 
    81 #if ( (NB_TIMERS_MAX) > 32 )
    82 # error: NB_TIMERS_MAX + NB_PROCS_MAX cannot be larger than 32
    83 #endif
    84 
    85 #if !defined(NB_IOCS)
    86 # error: You must define NB_IOCS in the configs file
    87 #endif
    88 
    89 #if ( NB_IOCS > 1 )
    90 # error: NB_IOCS cannot be larger than 1
     67#if !defined(GIET_CLUSTER_INCREMENT)
     68# error: You must define GIET_CLUSTER_INCREMENT in the giet_config.h file
     69#endif
     70
     71#if !defined(NB_TTY_CHANNELS)
     72# error: You must define NB_TTY_CHANNELS in the hard_config.h file
     73#endif
     74
     75#if (NB_TTY_CHANNELS < 1)
     76# error: NB_TTY_CHANNELS cannot be smaller than 1!
     77#endif
     78
     79#if !defined(NB_DMA_CHANNELS)
     80# error: You must define NB_DMA_CHANNELS in the hard_config.h file
     81#endif
     82
     83#if (NB_DMA_CHANNELS > 8)
     84# error: NB_DMA_CHANNELS cannot be smaller than 8!
     85#endif
     86
     87#if !defined(NB_TIM_CHANNELS)
     88#define NB_TIM_CHANNELS 0
     89#endif
     90
     91#if ( (NB_TIM_CHANNELS + NB_PROC_MAX) > 32 )
     92# error: NB_TIM_CHANNELS + NB_PROCS_MAX cannot be larger than 32
     93#endif
     94
     95#if !defined(NB_IOC_CHANNELS)
     96# error: You must define NB_IOC_CHANNELS in the hard_config.h file
     97#endif
     98
     99#if ( NB_IOC_CHANNELS > 8 )
     100# error: NB_IOC_CHANNELS cannot be larger than 8
     101#endif
     102
     103#if !defined(NB_NIC_CHANNELS)
     104# error: You must define NB_NIC_CHANNELS in the hard_config.h file
     105#endif
     106
     107#if ( NB_NIC_CHANNELS > 8 )
     108# error: NB_NIC_CHANNELS cannot be larger than 8
     109#endif
     110
     111#if !defined(NB_CMA_CHANNELS)
     112# error: You must define NB_CMA_CHANNELS in the hard_config.h file
     113#endif
     114
     115#if ( NB_CMA_CHANNELS > 8 )
     116# error: NB_CMA_CHANNELS cannot be larger than 8
    91117#endif
    92118
    93119#if !defined( USE_XICU )
    94 # error: You must define USE_XICU in the configs file
     120# error: You must define USE_XICU in the hard_config.h file
    95121#endif
    96122
    97123#if !defined( IOMMU_ACTIVE )
    98 # error: You must define IOMMU_ACTIVE in the configs file
     124# error: You must define IOMMU_ACTIVE in the hard_config.h file
    99125#endif
    100126
     
    105131//     Timers driver
    106132//////////////////////////////////////////////////////////////////////////////
     133// This peripheral is replicated in all clusters.
    107134// The timers can be implemented in a vci_timer component or in a vci_xicu
    108135// component (depending on the USE_XICU parameter).
     
    113140// - "user" timers : requested by the task in the mapping_info data structure.
    114141//   For each user timer, the timer_id is stored in the context of the task.
    115 // The global index is cluster_id * (NB_PROCS_MAX+NB_TIMERS_MAX) + local_id
     142// The global index is cluster_id * (NB_PROCS_MAX+NB_TIM_CHANNELS) + local_id
    116143//////////////////////////////////////////////////////////////////////////////
     144// The (virtual) base address of the associated segment is:
     145//
     146//       timer_address = seg_icu_base + cluster_id * GIET_CLUSTER_INCREMENT
     147//
     148// - cluster id is an explicit argument of all access functions
     149// - seg_icu_base must be defined in the giet_vsegs.ld file
     150// - GIET_CLUSTER_INCREMENT must be defined in the giet_config.h file
     151////////////////////////////////////////////////////////////////////////////////
    117152
    118153// User Timer signaling variables
    119154
    120 #if (NB_TIMERS_MAX > 0)
    121 in_unckdata volatile unsigned char _user_timer_event[NB_CLUSTERS * NB_TIMERS_MAX]
    122                             = { [0 ... ((NB_CLUSTERS * NB_TIMERS_MAX) - 1)] = 0 };
     155#if (NB_TIM_CHANNELS > 0)
     156in_unckdata volatile unsigned char _user_timer_event[NB_CLUSTERS * NB_TIM_CHANNELS]
     157                            = { [0 ... ((NB_CLUSTERS * NB_TIM_CHANNELS) - 1)] = 0 };
    123158#endif
    124159
     
    131166// Returns 0 if success, > 0 if error.
    132167//////////////////////////////////////////////////////////////////////////////
    133 unsigned int _timer_start(unsigned int cluster_id, unsigned int local_id, unsigned int period) {
     168unsigned int _timer_start( unsigned int cluster_id,
     169                           unsigned int local_id,
     170                           unsigned int period)
     171{
    134172    // parameters checking
    135     if (cluster_id >= NB_CLUSTERS) {
    136         return 1;
    137     }
    138     if (local_id >= NB_TIMERS_MAX) {
    139         return 2;
    140     }
     173    if (cluster_id >= NB_CLUSTERS)  return 1;
     174    if (local_id >= NB_TIM_CHANNELS)  return 2;
    141175
    142176#if USE_XICU
    143     unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base + (cluster_id * CLUSTER_SIZE));
     177    unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base +
     178                                                     (cluster_id * GIET_CLUSTER_INCREMENT));
    144179
    145180    timer_address[XICU_REG(XICU_PTI_PER, local_id)] = period;
    146181#else
    147     unsigned int* timer_address = (unsigned int *) ((char *) &seg_tim_base + (cluster_id * CLUSTER_SIZE));
     182    unsigned int* timer_address = (unsigned int *) ((char *) &seg_tim_base +
     183                                                    (cluster_id * GIET_CLUSTER_INCREMENT));
    148184
    149185    timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period;
     
    152188    return 0;
    153189}
    154 
    155190
    156191//////////////////////////////////////////////////////////////////////////////
     
    160195// Returns 0 if success, > 0 if error.
    161196//////////////////////////////////////////////////////////////////////////////
    162 unsigned int _timer_stop(unsigned int cluster_id, unsigned int local_id) {
     197unsigned int _timer_stop( unsigned int cluster_id,
     198                          unsigned int local_id)
     199{
    163200    // parameters checking
    164     if (cluster_id >= NB_CLUSTERS) {
    165         return 1;
    166     }
    167     if (local_id >= NB_TIMERS_MAX) {
    168         return 2;
    169     }
     201    if (cluster_id >= NB_CLUSTERS)  return 1;
     202    if (local_id >= NB_TIM_CHANNELS)  return 2;
    170203
    171204#if USE_XICU
    172     unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base + (cluster_id * CLUSTER_SIZE));
     205    unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base +
     206                                                     (cluster_id * GIET_CLUSTER_INCREMENT));
    173207
    174208    timer_address[XICU_REG(XICU_PTI_PER, local_id)] = 0;
    175209#else
    176     unsigned int* timer_address = (unsigned int *) ((char *) &seg_tim_base + (cluster_id * CLUSTER_SIZE));
     210    unsigned int* timer_address = (unsigned int *) ((char *) &seg_tim_base +
     211                                                    (cluster_id * GIET_CLUSTER_INCREMENT));
     212
    177213    timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0;
    178214#endif
     
    189225// Returns 0 if success, > 0 if error.
    190226//////////////////////////////////////////////////////////////////////////////
    191 unsigned int _timer_reset_irq(unsigned int cluster_id, unsigned int local_id) {
     227unsigned int _timer_reset_irq( unsigned int cluster_id,
     228                               unsigned int local_id )
     229{
    192230    // parameters checking
    193     if (cluster_id >= NB_CLUSTERS) {
    194         return 1;
    195     }
    196     if (local_id >= NB_TIMERS_MAX) {
    197         return 2;
    198     }
     231    if (cluster_id >= NB_CLUSTERS)  return 1;
     232    if (local_id >= NB_TIM_CHANNELS)  return 2;
    199233
    200234#if USE_XICU
    201235    unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base +
    202             (cluster_id * (unsigned) CLUSTER_SIZE));
     236                                                     (cluster_id * GIET_CLUSTER_INCREMENT));
    203237
    204238    unsigned int bloup = timer_address[XICU_REG(XICU_PTI_ACK, local_id)];
     
    206240#else
    207241    unsigned int * timer_address = (unsigned int *) ((char *) &seg_tim_base +
    208             (cluster_id * CLUSTER_SIZE));
     242            (cluster_id * GIET_CLUSTER_INCREMENT));
    209243
    210244    timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0;
    211245#endif
    212 
    213246    return 0;
    214247}
     
    223256//        return 1;
    224257//    }
    225 //    if (local_id >= NB_TIMERS_MAX) {
     258//    if (local_id >= NB_TIM_CHANNELS) {
    226259//        return 2;
    227260//    }
     
    230263//#error // not implemented
    231264//#else
    232 //    unsigned int * timer_address = (unsigned int *) ((char *) &seg_tim_base + (cluster_id * CLUSTER_SIZE));
     265//    unsigned int * timer_address = (unsigned int *) ((char *) &seg_tim_base + (cluster_id * GIET_CLUSTER_INCREMENT));
    233266//    unsigned int timer_period = timer_address[local_id * TIMER_SPAN + TIMER_PERIOD];
    234267//
     
    244277/////////////////////////////////////////////////////////////////////////////////
    245278// There is only one multi_tty controler in the architecture.
    246 // The total number of TTYs is defined by the configuration parameter NB_TTYS.
     279// The total number of TTYs is defined by the configuration parameter NB_TTY_CHANNELS.
    247280// The "system" terminal is TTY[0].
    248281// The "user" TTYs are allocated to applications by the GIET in the boot phase,
     
    253286
    254287// TTY variables
    255 in_unckdata volatile unsigned char _tty_get_buf[NB_TTYS];
    256 in_unckdata volatile unsigned char _tty_get_full[NB_TTYS] = { [0 ... NB_TTYS - 1] = 0 };
     288in_unckdata volatile unsigned char _tty_get_buf[NB_TTY_CHANNELS];
     289in_unckdata volatile unsigned char _tty_get_full[NB_TTY_CHANNELS]
     290                                     = { [0 ... NB_TTY_CHANNELS - 1] = 0 };
    257291in_unckdata unsigned int _tty_put_lock = 0;  // protect kernel TTY[0]
    258292
     
    260294//      _tty_error()
    261295////////////////////////////////////////////////////////////////////////////////
    262 void _tty_error(unsigned int tty_id, unsigned int task_id) {
     296void _tty_error(unsigned int tty_id, unsigned int task_id)
     297{
    263298    unsigned int proc_id = _procid();
    264299
     
    287322// The function returns  the number of characters that have been written.
    288323/////////////////////////////////////////////////////////////////////////////////
    289 unsigned int _tty_write(const char * buffer, unsigned int length) {
     324unsigned int _tty_write(const char * buffer,
     325                        unsigned int length)
     326{
    290327    unsigned int nwritten;
    291     unsigned int task_id = _get_proc_task_id();
    292     unsigned int tty_id = _get_context_slot(task_id, CTX_TTY_ID);
    293 
    294     if (tty_id >= NB_TTYS) {
    295         _tty_error(tty_id , task_id);
    296         return 0;
    297     }
    298 
    299     unsigned int * tty_address = (unsigned int *) &seg_tty_base;
    300 
    301     for (nwritten = 0; nwritten < length; nwritten++) {
     328    unsigned int tty_id = _get_context_slot(CTX_TTY_ID);
     329    unsigned int* tty_address = (unsigned int *) &seg_tty_base;
     330
     331    for (nwritten = 0; nwritten < length; nwritten++)
     332    {
    302333        // check tty's status
    303         if ((tty_address[tty_id * TTY_SPAN + TTY_STATUS] & 0x2) == 0x2) {
    304             break;
    305         }
    306         else {
    307             // write character
    308             tty_address[tty_id * TTY_SPAN + TTY_WRITE] = (unsigned int) buffer[nwritten];
    309         }
     334        if ((tty_address[tty_id * TTY_SPAN + TTY_STATUS] & 0x2) == 0x2) break;
     335        tty_address[tty_id * TTY_SPAN + TTY_WRITE] = (unsigned int) buffer[nwritten];
    310336    }
    311337    return nwritten;
    312338}
    313 
    314339
    315340//////////////////////////////////////////////////////////////////////////////
     
    324349// Returns 0 if the kernel buffer is empty, 1 if the buffer is full.
    325350//////////////////////////////////////////////////////////////////////////////
    326 unsigned int _tty_read(char * buffer, unsigned int length) {
    327     unsigned int task_id = _get_proc_task_id();
    328     unsigned int tty_id = _get_context_slot(task_id, CTX_TTY_ID);
    329 
    330     if (tty_id >= NB_TTYS) {
    331         _tty_error(tty_id, task_id);
     351unsigned int _tty_read(char * buffer,
     352                       unsigned int length)
     353{
     354    unsigned int tty_id = _get_context_slot(CTX_TTY_ID);
     355
     356    if (_tty_get_full[tty_id] == 0)
     357    {
    332358        return 0;
    333359    }
    334 
    335     if (_tty_get_full[tty_id] == 0) {
    336         return 0;
    337     }
    338     else {
     360    else
     361    {
    339362        *buffer = _tty_get_buf[tty_id];
    340363        _tty_get_full[tty_id] = 0;
     
    342365    }
    343366}
    344 
    345367
    346368////////////////////////////////////////////////////////////////////////////////
     
    351373// Returns 0 if success, 1 if tty_id too large.
    352374////////////////////////////////////////////////////////////////////////////////
    353 unsigned int _tty_get_char(unsigned int tty_id, unsigned char * buffer) {
     375unsigned int _tty_get_char(unsigned int tty_id,
     376                           unsigned char * buffer)
     377{
    354378    // checking argument
    355     if (tty_id >= NB_TTYS) {
    356         return 1;
    357     }
     379    if (tty_id >= NB_TTY_CHANNELS) { return 1; }
    358380
    359381    // compute terminal base address
     
    366388
    367389////////////////////////////////////////////////////////////////////////////////
    368 //     VciMultiIcu and VciXicu drivers
    369 ////////////////////////////////////////////////////////////////////////////////
     390//     VciMultiIcu or VciXicu driver
     391////////////////////////////////////////////////////////////////////////////////
     392// This hardware component is replicated in all clusters.
    370393// There is one vci_multi_icu (or vci_xicu) component per cluster,
    371394// and the number of independant ICUs is equal to NB_PROCS_MAX,
    372 // because there is one private interrupr controler per processor.
     395// because there is one private interrupt controler per processor.
     396////////////////////////////////////////////////////////////////////////////////
     397// The (virtual) base address of the associated segment is:
     398//
     399//       icu_address = seg_icu_base + cluster_id * GIET_CLUSTER_INCREMENT
     400//
     401// - cluster id is an explicit argument of all access functions
     402// - seg_icu_base must be defined in the giet_vsegs.ld file
     403// - GIET_CLUSTER_INCREMENT must be defined in the giet_config.h file
    373404////////////////////////////////////////////////////////////////////////////////
    374405
     
    380411// Returns 0 if success, > 0 if error.
    381412////////////////////////////////////////////////////////////////////////////////
    382 unsigned int _icu_set_mask(
    383         unsigned int cluster_id,
    384         unsigned int proc_id,
    385         unsigned int value,
    386         unsigned int is_timer) {
     413unsigned int _icu_set_mask( unsigned int cluster_id,
     414                            unsigned int proc_id,
     415                            unsigned int value,
     416                            unsigned int is_timer)
     417{
    387418    // parameters checking
    388     if (cluster_id >= NB_CLUSTERS) {
    389         return 1;
    390     }
    391     if (proc_id >= NB_PROCS_MAX) {
    392         return 1;
    393     }
     419    if (cluster_id >= NB_CLUSTERS) return 1;
     420    if (proc_id >= NB_PROCS_MAX)   return 1;
    394421
    395422    unsigned int * icu_address = (unsigned int *) ((char *) &seg_icu_base +
    396             (cluster_id * (unsigned) CLUSTER_SIZE));
     423                                                   (cluster_id * GIET_CLUSTER_INCREMENT));
    397424#if USE_XICU
    398     if (is_timer) {
     425    if (is_timer)
     426    {
    399427        icu_address[XICU_REG(XICU_MSK_PTI_ENABLE, proc_id)] = value;
    400428    }
    401     else {
     429    else
     430    {
    402431        icu_address[XICU_REG(XICU_MSK_HWI_ENABLE, proc_id)] = value;
    403432    }
     
    405434    icu_address[proc_id * ICU_SPAN + ICU_MASK_SET] = value;
    406435#endif
    407 
    408436    return 0;
    409437}
     
    417445// Returns 0 if success, > 0 if error.
    418446////////////////////////////////////////////////////////////////////////////////
    419 unsigned int _icu_get_index(unsigned int cluster_id, unsigned int proc_id, unsigned int * buffer) {
     447unsigned int _icu_get_index( unsigned int cluster_id,
     448                             unsigned int proc_id,
     449                             unsigned int * buffer)
     450{
    420451    // parameters checking
    421     if (cluster_id >= NB_CLUSTERS) {
    422         return 1;
    423     }
    424     if (proc_id >= NB_PROCS_MAX) {
    425         return 1;
    426     }
     452    if (cluster_id >= NB_CLUSTERS)  return 1;
     453    if (proc_id >= NB_PROCS_MAX)    return 1;
    427454
    428455    unsigned int * icu_address = (unsigned int *) ((char *) &seg_icu_base +
    429             (cluster_id * (unsigned) CLUSTER_SIZE));
     456                                                   (cluster_id * GIET_CLUSTER_INCREMENT));
    430457#if USE_XICU
    431458    unsigned int prio = icu_address[XICU_REG(XICU_PRIO, proc_id)];
     
    436463    unsigned int hwi_id = (prio & 0x001F0000) >> 16;
    437464    unsigned int swi_id = (prio & 0x1F000000) >> 24;
    438     if (pti_ok) {
    439         *buffer = pti_id;
    440     }
    441     else if (hwi_ok) {
    442         *buffer = hwi_id;
    443     }
    444     else if (swi_ok) {
    445         *buffer = swi_id;
    446     }
    447     else {
    448         *buffer = 32;
    449     }
     465    if      (pti_ok) { *buffer = pti_id; }
     466    else if (hwi_ok) { *buffer = hwi_id; }
     467    else if (swi_ok) { *buffer = swi_id; }
     468    else             { *buffer = 32; }
    450469#else
    451470    *buffer = icu_address[proc_id * ICU_SPAN + ICU_IT_VECTOR];
    452471#endif
    453 
    454472    return 0;
    455473}
     
    469487// Returns 0 if success, > 0 if error.
    470488////////////////////////////////////////////////////////////////////////////////
    471 unsigned int _gcd_write(unsigned int register_index, unsigned int value) {
     489unsigned int _gcd_write( unsigned int register_index,
     490                         unsigned int value)
     491{
    472492    // parameters checking
    473     if (register_index >= GCD_END) {
    474         return 1;
    475     }
     493    if (register_index >= GCD_END)  return 1;
    476494
    477495    unsigned int * gcd_address = (unsigned int *) &seg_gcd_base;
     
    487505// Returns 0 if success, > 0 if error.
    488506////////////////////////////////////////////////////////////////////////////////
    489 unsigned int _gcd_read(unsigned int register_index, unsigned int * buffer) {
     507unsigned int _gcd_read( unsigned int register_index,
     508                        unsigned int * buffer )
     509{
    490510    // parameters checking
    491     if (register_index >= GCD_END) {
    492         return 1;
    493     }
     511    if (register_index >= GCD_END)  return 1;
    494512
    495513    unsigned int * gcd_address = (unsigned int *) &seg_gcd_base;
     
    567585// Returns 0 if success, > 0 if error.
    568586///////////////////////////////////////////////////////////////////////////////
    569 unsigned int _ioc_access(
    570         unsigned int to_mem,
    571         unsigned int lba,
    572         unsigned int user_vaddr,
    573         unsigned int count) {
    574     unsigned int user_vpn_min; // first virtuel page index in user space
    575     unsigned int user_vpn_max; // last virtual page index in user space
    576     unsigned int vpn;          // current virtual page index in user space
    577     unsigned int ppn;          // physical page number
    578     unsigned int flags;        // page protection flags
    579     unsigned int ix2;          // page index in IOMMU PT1 page table
    580     unsigned int addr;         // buffer address for IOC peripheral
    581     unsigned int ppn_first;    // first physical page number for user buffer
    582 
     587unsigned int _ioc_access( unsigned int to_mem,
     588                          unsigned int lba,
     589                          unsigned int user_vaddr,
     590                          unsigned int count)
     591{
     592    unsigned int user_vpn_min;     // first virtuel page index in user space
     593    unsigned int user_vpn_max;     // last virtual page index in user space
     594    unsigned int vpn;              // current virtual page index in user space
     595    unsigned int ppn;              // physical page number
     596    unsigned int flags;            // page protection flags
     597    unsigned int ix2;              // page index in IOMMU PT1 page table
     598    unsigned int ppn_first;        // first physical page number for user buffer
     599    unsigned int buf_xaddr = 0;    // user buffer virtual address in IO space (if IOMMU)
     600    paddr_t      buf_paddr = 0;    // user buffer physical address (if no IOMMU),
     601                               
    583602    // check buffer alignment
    584     if ((unsigned int) user_vaddr & 0x3) {
    585         return 1;
     603    if ((unsigned int) user_vaddr & 0x3)
     604    {
     605        _get_lock(&_tty_put_lock);
     606        _puts("[GIET ERROR] in _ioc_access() : user buffer not word aligned\n");
     607        _release_lock(&_tty_put_lock);
     608        return 1;
    586609    }
    587610
     
    592615
    593616    // get user space page table virtual address
    594     unsigned int task_id = _get_proc_task_id();
    595     unsigned int user_pt_vbase = _get_context_slot(task_id, CTX_PTAB_ID);
     617    unsigned int user_pt_vbase = _get_context_slot(CTX_PTAB_ID);
    596618
    597619    user_vpn_min = user_vaddr >> 12;
    598620    user_vpn_max = (user_vaddr + length - 1) >> 12;
    599     ix2 = 0;
    600621
    601622    // loop on all virtual pages covering the user buffer
    602     for (vpn = user_vpn_min; vpn <= user_vpn_max; vpn++) {
     623    for (vpn = user_vpn_min, ix2 = 0 ;
     624         vpn <= user_vpn_max ;
     625         vpn++, ix2++ )
     626    {
    603627        // get ppn and flags for each vpn
    604         unsigned int ko = _v2p_translate((page_table_t *) user_pt_vbase, vpn, &ppn, &flags);
    605 
     628        unsigned int ko = _v2p_translate( (page_table_t*)user_pt_vbase,
     629                                           vpn,
     630                                           &ppn,
     631                                           &flags);
    606632        // check access rights
    607         if (ko) {
    608             return 2; // unmapped
     633        if (ko)                                 
     634        {
     635            _get_lock(&_tty_put_lock);
     636            _puts("[GIET ERROR] in _ioc_access() : user buffer unmapped\n");
     637            _release_lock(&_tty_put_lock);
     638            return 1;
    609639        }
    610         if ((flags & PTE_U) == 0) {
    611             return 3; // not in user space
     640        if ((flags & PTE_U) == 0)
     641        {
     642            _get_lock(&_tty_put_lock);
     643            _puts("[GIET ERROR] in _ioc_access() : user buffer not in user space\n");
     644            _release_lock(&_tty_put_lock);
     645            return 1;
    612646        }
    613         if (((flags & PTE_W) == 0 ) && to_mem) {
    614             return 4; // not writable
     647        if (((flags & PTE_W) == 0 ) && to_mem)
     648        {
     649            _get_lock(&_tty_put_lock);
     650            _puts("[GIET ERROR] in _ioc_access() : user buffer not writable\n");
     651            _release_lock(&_tty_put_lock);
     652            return 1;
    615653        }
    616654
    617655        // save first ppn value
    618         if (ix2 == 0) {
    619             ppn_first = ppn;
     656        if (ix2 == 0) ppn_first = ppn;
     657
     658        if (IOMMU_ACTIVE) // the user buffer must be remapped in the I/0 space
     659        {
     660            // check buffer length < 2 Mbytes
     661            if (ix2 > 511)
     662            {
     663                _get_lock(&_tty_put_lock);
     664                _puts("[GIET ERROR] in _ioc_access() : user buffer > 2 Mbytes\n");
     665                _release_lock(&_tty_put_lock);
     666                return 1;
     667            }
     668
     669            // map the physical page in IOMMU page table
     670            _iommu_add_pte2( _ioc_iommu_ix1,    // PT1 index
     671                             ix2,               // PT2 index
     672                             ppn,               // Physical page number   
     673                             flags);            // Protection flags
     674
     675            // compute user buffer virtual adress in IO space
     676            buf_xaddr = (_ioc_iommu_ix1) << 21 | (user_vaddr & 0xFFF);
    620677        }
    621 
    622         if (IOMMU_ACTIVE) {
    623             // the user buffer must be remapped in the I/0 space
    624             // check buffer length < 2 Mbytes
    625             if (ix2 > 511) {
    626                 return 2;
     678        else            // No IOMMU
     679        {
     680            // check that physical pages are contiguous
     681            if ((ppn - ppn_first) != ix2)
     682            {
     683                _get_lock(&_tty_put_lock);
     684                _puts("[GIET ERROR] in _ioc_access() : split physical user buffer\n");
     685                _release_lock(&_tty_put_lock);
     686                return 1;
    627687            }
    628688
    629             // map the physical page in IOMMU page table
    630             _iommu_add_pte2(
    631                     _ioc_iommu_ix1,    // PT1 index
    632                     ix2,               // PT2 index
    633                     ppn,               // Physical page number   
    634                     flags);            // Protection flags
     689            // compute user buffer physical adress
     690            buf_paddr = (((paddr_t)ppn_first) << 12) | (user_vaddr & 0xFFF);
    635691        }
    636         else {
    637             // no IOMMU : check that physical pages are contiguous
    638             if ((ppn - ppn_first) != ix2) {
    639                 return 5; // split physical buffer
    640             }
    641         }
    642 
    643         // increment page index
    644         ix2++;
    645692    } // end for vpn
    646693
     
    649696
    650697    // invalidate data cache in case of memory write
    651     if (to_mem) {
    652         _dcache_buf_invalidate((void *) user_vaddr, length);
    653     }
    654 
    655     // compute buffer base address for IOC depending on IOMMU activation
    656     if (IOMMU_ACTIVE) {
    657         addr = (_ioc_iommu_ix1) << 21 | (user_vaddr & 0xFFF);
    658     }
    659     else {
    660         addr = (ppn_first << 12) | (user_vaddr & 0xFFF);
    661     }
     698    if (to_mem) _dcache_buf_invalidate((void *) user_vaddr, length);
     699
     700#if GIET_DEBUG_IOC_DRIVER
     701_get_lock(&_tty_put_lock);
     702_puts("\n[GIET DEBUG]  IOC_ACCESS at cycle ");
     703_putd( _proctime() );
     704_puts("\n - proc_id         = ");
     705_putd( _procid() );
     706_puts("\n - ioc_vbase       = ");
     707_putx( (unsigned int)ioc_address );
     708_puts("\n - psched_vbase    = ");
     709_putx( (unsigned int)_get_sched() );
     710_puts("\n - pt_vbase        = ");
     711_putx( user_pt_vbase );
     712_puts("\n - user_buf_vbase  = ");
     713_putx( user_vaddr );
     714_puts("\n - user_buf_length = ");
     715_putx( length );
     716_puts("\n - user_buf_paddr  = ");
     717_putl( buf_paddr );
     718_puts("\n - user_buf_xaddr  = ");
     719_putx( buf_xaddr );
     720_puts("\n");
     721_release_lock(&_tty_put_lock);
     722#endif
    662723
    663724    // get the lock on ioc device
     
    665726
    666727    // peripheral configuration 
    667     ioc_address[BLOCK_DEVICE_BUFFER] = addr;
     728    if ( IOMMU_ACTIVE )
     729    {
     730        ioc_address[BLOCK_DEVICE_BUFFER] = buf_xaddr;
     731    }
     732    else
     733    {
     734        ioc_address[BLOCK_DEVICE_BUFFER]     = (unsigned int)buf_paddr;
     735        ioc_address[BLOCK_DEVICE_BUFFER_EXT] = (unsigned int)(buf_paddr>>32);
     736    }
    668737    ioc_address[BLOCK_DEVICE_COUNT] = count;
    669738    ioc_address[BLOCK_DEVICE_LBA] = lba;
    670     if (to_mem == 0) {
     739    if (to_mem == 0)
     740    {
    671741        ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_WRITE;
    672742    }
    673     else {
     743    else
     744    {
    674745        ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_READ;
    675746    }
    676 
    677     return 0;
    678 }
    679 
     747    return 0;
     748}
    680749
    681750/////////////////////////////////////////////////////////////////////////////////
     
    688757// Returns 0 if success, > 0 if error.
    689758/////////////////////////////////////////////////////////////////////////////////
    690 unsigned int _ioc_completed() {
     759unsigned int _ioc_completed()
     760{
    691761    unsigned int ret;
    692762    unsigned int ix2;
    693763
    694764    // busy waiting
    695     while (_ioc_done == 0) {
    696         asm volatile("nop");
    697     }
     765    while (_ioc_done == 0) { asm volatile("nop"); }
     766
     767#if GIET_DEBUG_IOC_DRIVER
     768_get_lock(&_tty_put_lock);
     769_puts("\n[GIET DEBUG]  IOC_COMPLETED at cycle ");
     770_putd( _proctime() );
     771_puts("\n - proc_id         = ");
     772_putd( _procid() );
     773_puts("\n");
     774_release_lock(&_tty_put_lock);
     775#endif
    698776
    699777    // unmap the buffer from IOMMU page table if IOMMU is activated
    700     if (IOMMU_ACTIVE) {
     778    if (IOMMU_ACTIVE)
     779    {
    701780        unsigned int * iob_address = (unsigned int *) &seg_iob_base;
    702781
    703         for (ix2 = 0; ix2 < _ioc_iommu_npages; ix2++) {
     782        for (ix2 = 0; ix2 < _ioc_iommu_npages; ix2++)
     783        {
    704784            // unmap the page in IOMMU page table
    705785            _iommu_inval_pte2(
     
    714794    // test IOC status
    715795    if ((_ioc_status != BLOCK_DEVICE_READ_SUCCESS)
    716             && (_ioc_status != BLOCK_DEVICE_WRITE_SUCCESS)) {
    717         ret = 1; // error
    718     }
    719     else {
    720         ret = 0; // success
    721     }
     796            && (_ioc_status != BLOCK_DEVICE_WRITE_SUCCESS)) ret = 1; // error
     797    else                                                    ret = 0; // success
    722798
    723799    // reset synchronization variables
     
    738814// Returns 0 if success, > 0 if error.
    739815///////////////////////////////////////////////////////////////////////////////
    740 unsigned int _ioc_read(unsigned int lba, void * buffer, unsigned int count) {
     816unsigned int _ioc_read( unsigned int lba,
     817                        void * buffer,
     818                        unsigned int count)
     819{
    741820    return _ioc_access(
    742821            1,        // read access
     
    755834// Returns 0 if success, > 0 if error.
    756835///////////////////////////////////////////////////////////////////////////////
    757 unsigned int _ioc_write(unsigned int lba, const void * buffer, unsigned int count) {
     836unsigned int _ioc_write( unsigned int lba,
     837                         const void * buffer,
     838                         unsigned int count)
     839{
    758840    return _ioc_access(
    759841            0, // write access
     
    769851// Returns 0 if success, > 0 if error.
    770852///////////////////////////////////////////////////////////////////////////////
    771 unsigned int _ioc_get_status(unsigned int * status) {
     853unsigned int _ioc_get_status(unsigned int * status)
     854{
    772855    // get IOC base address
    773856    unsigned int * ioc_address = (unsigned int *) &seg_ioc_base;
     
    782865// This function returns the block_size with which the IOC has been configured.
    783866///////////////////////////////////////////////////////////////////////////////
    784 unsigned int _ioc_get_block_size() {
     867unsigned int _ioc_get_block_size()
     868{
    785869    // get IOC base address
    786870    unsigned int * ioc_address = (unsigned int *) &seg_ioc_base;
     
    794878//////////////////////////////////////////////////////////////////////////////////
    795879// The DMA controllers are physically distributed in the clusters.
    796 // There is  (NB_CLUSTERS * NB_DMAS_MAX) channels, indexed by a global index:
    797 //        dma_id = cluster_id * NB_DMA_MAX + loc_id
    798 //
    799 // As a DMA channel can be used by several tasks, each DMA channel is protected
    800 // by a specific lock: _dma_lock[dma_id]
     880// There is  (NB_CLUSTERS * NB_DMA_CHANNELS) channels, indexed by a global index:
     881//        dma_id = cluster_id * NB_DMA_CHANNELS + loc_id
     882//
     883// As a DMA channel is a private ressource allocated to a task,
     884// there is no lock protecting exclusive access to the channel.
    801885// The signalisation between the OS and the DMA uses the _dma_done[dma_id]
    802886// synchronisation variables  (set by the ISR, and reset by the OS).
    803887// The transfer status is copied by the ISR in the _dma_status[dma_id] variables.
    804 //
    805 // These DMA channels can be used by the FB driver, or by the NIC driver.
    806 //////////////////////////////////////////////////////////////////////////////////
    807 
    808 #if NB_DMAS_MAX > 0
    809 in_unckdata unsigned int            _dma_lock[NB_DMAS_MAX * NB_CLUSTERS] = {
    810     [0 ... (NB_DMAS_MAX * NB_CLUSTERS) - 1] = 0
    811 };
    812 
    813 in_unckdata volatile unsigned int    _dma_done[NB_DMAS_MAX * NB_CLUSTERS] = {
    814     [0 ... (NB_DMAS_MAX * NB_CLUSTERS) - 1] = 0
    815 };
    816 
    817 in_unckdata volatile unsigned int _dma_status[NB_DMAS_MAX * NB_CLUSTERS];
     888//////////////////////////////////////////////////////////////////////////////////
     889// The (virtual) base address of the associated segment is:
     890//
     891//       dma_address = seg_dma_base + cluster_id * GIET_CLUSTER_INCREMENT
     892//
     893// - seg_dma_base  must be defined in the giet_vsegs.ld file
     894// - GIET_CLUSTER_INCREMENT  must be defined in the giet_config.h file
     895////////////////////////////////////////////////////////////////////////////////
     896
     897#if NB_DMA_CHANNELS > 0
     898
     899// in_unckdata unsigned int            _dma_lock[NB_DMA_CHANNELS * NB_CLUSTERS]
     900// = { [0 ... (NB_DMA_CHANNELS * NB_CLUSTERS) - 1] = 0 };
     901
     902in_unckdata volatile unsigned int    _dma_done[NB_DMA_CHANNELS * NB_CLUSTERS]
     903        = { [0 ... (NB_DMA_CHANNELS * NB_CLUSTERS) - 1] = 0 };
     904in_unckdata volatile unsigned int _dma_status[NB_DMA_CHANNELS * NB_CLUSTERS];
    818905in_unckdata unsigned int _dma_iommu_ix1 = 1;
    819 in_unckdata unsigned int _dma_iommu_npages[NB_DMAS_MAX * NB_CLUSTERS];
     906in_unckdata unsigned int _dma_iommu_npages[NB_DMA_CHANNELS * NB_CLUSTERS];
    820907#endif
    821908
     
    823910// _dma_reset_irq()
    824911//////////////////////////////////////////////////////////////////////////////////
    825 unsigned int _dma_reset_irq(unsigned int cluster_id, unsigned int channel_id) {
    826 #if NB_DMAS_MAX > 0
     912unsigned int _dma_reset_irq( unsigned int cluster_id,
     913                             unsigned int channel_id)
     914{
     915#if NB_DMA_CHANNELS > 0
    827916    // parameters checking
    828     if (cluster_id >= NB_CLUSTERS) {
    829         return 1;
    830     }
    831     if (channel_id >= NB_DMAS_MAX) {
    832         return 1;
    833     }
     917    if (cluster_id >= NB_CLUSTERS)  return 1;
     918    if (channel_id >= NB_DMA_CHANNELS)  return 1;
    834919
    835920    // compute DMA base address
    836921    unsigned int * dma_address = (unsigned int *) ((char *) &seg_dma_base +
    837             (cluster_id * (unsigned) CLUSTER_SIZE));
     922                                                   (cluster_id * GIET_CLUSTER_INCREMENT));
    838923
    839924    dma_address[channel_id * DMA_SPAN + DMA_RESET] = 0;           
     
    848933// _dma_get_status()
    849934//////////////////////////////////////////////////////////////////////////////////
    850 unsigned int _dma_get_status(unsigned int cluster_id, unsigned int channel_id, unsigned int * status) {
    851 #if NB_DMAS_MAX > 0
     935unsigned int _dma_get_status( unsigned int cluster_id,
     936                              unsigned int channel_id,
     937                              unsigned int * status)
     938{
     939#if NB_DMA_CHANNELS > 0
    852940    // parameters checking
    853     if (cluster_id >= NB_CLUSTERS) {
    854         return 1;
    855     }
    856     if (channel_id >= NB_DMAS_MAX) {
    857         return 1;
    858     }
     941    if (cluster_id >= NB_CLUSTERS)  return 1;
     942    if (channel_id >= NB_DMA_CHANNELS)  return 1;
    859943
    860944    // compute DMA base address
    861945    unsigned int * dma_address = (unsigned int *) ((char *) &seg_dma_base +
    862             (cluster_id * (unsigned) CLUSTER_SIZE));
     946                                                   (cluster_id * GIET_CLUSTER_INCREMENT));
    863947
    864948    *status = dma_address[channel_id * DMA_SPAN + DMA_LEN];
     
    873957// _dma_transfer()
    874958// Transfer data between a user buffer and a device buffer using DMA.
    875 // Two devices types are supported: Frame Buffer if dev_type == 0
    876 //                                  Multi-Nic if dev_type != 0
     959// Only one device type is supported: Frame Buffer (dev_type == 0)
    877960// Arguments are:
    878961// - dev_type     : device type.
     
    882965// - length       : number of bytes to be transfered.
    883966//
    884 // The DMA channel is obtained from task context (CTX_FBDMA_ID / CTX_NIDMA_ID.
     967// The cluster_id and channel_id are obtained from task context (CTX_DMA_ID).
    885968// The user buffer must be mapped in user address space and word-aligned.
    886969// The user buffer length must be multiple of 4 bytes.
    887 // Me must compute the physical base addresses for both the device buffer
     970// We compute the physical base addresses for both the device buffer
    888971// and the user buffer before programming the DMA transfer.
    889972// The GIET being fully static, we don't need to split the transfer in 4 Kbytes
     
    891974// Returns 0 if success, > 0 if error.
    892975//////////////////////////////////////////////////////////////////////////////////
    893 unsigned int _dma_transfer(
    894         unsigned int dev_type,
    895         unsigned int to_user,
    896         unsigned int offset,
    897         unsigned int user_vaddr,
    898         unsigned int length) {
    899 #if NB_DMAS_MAX > 0
     976unsigned int _dma_transfer( unsigned int dev_type,
     977                            unsigned int to_user,
     978                            unsigned int offset,
     979                            unsigned int user_vaddr,
     980                            unsigned int length )
     981{
     982#if NB_DMA_CHANNELS > 0
    900983    unsigned int ko;           // unsuccessfull V2P translation
     984    unsigned int device_vbase; // device buffer vbase address
    901985    unsigned int flags;        // protection flags
    902986    unsigned int ppn;          // physical page number
    903     unsigned int user_pbase;   // user buffer pbase address
    904     unsigned int device_pbase; // frame buffer pbase address
    905     unsigned int device_vaddr; // device buffer vbase address
     987    paddr_t      user_pbase;   // user buffer pbase address
     988    paddr_t      device_pbase; // frame buffer pbase address
    906989
    907990    // check user buffer address and length alignment
    908     if ((user_vaddr & 0x3) || (length & 0x3)) {
     991    if ((user_vaddr & 0x3) || (length & 0x3))
     992    {
    909993        _get_lock(&_tty_put_lock);
    910994        _puts("\n[GIET ERROR] in _dma_transfer : user buffer not word aligned\n");
     
    914998
    915999    // get DMA channel and compute DMA vbase address
    916     unsigned int task_id    = _get_proc_task_id();
    917     unsigned int dma_id     = _get_context_slot(task_id, CTX_DMA_ID);
    918     unsigned int cluster_id = dma_id / NB_DMAS_MAX;
    919     unsigned int loc_id     = dma_id % NB_DMAS_MAX;
    920     unsigned int * dma_base = (unsigned int *) ((char *) &seg_dma_base +
    921             (cluster_id * (unsigned) CLUSTER_SIZE));
    922 
     1000    unsigned int dma_id      = _get_context_slot(CTX_DMA_ID);
     1001    if ( dma_id == 0xFFFFFFFF )
     1002    {
     1003        _get_lock(&_tty_put_lock);
     1004        _puts("\n[GIET ERROR] in _dma_transfer : no DMA channel allocated\n");
     1005        _release_lock(&_tty_put_lock);
     1006        return 1;
     1007    }
     1008    unsigned int cluster_id  = dma_id / NB_DMA_CHANNELS;
     1009    unsigned int channel_id  = dma_id % NB_DMA_CHANNELS;
     1010    unsigned int * dma_vbase  = (unsigned int *) ((char *) &seg_dma_base +
     1011                                                (cluster_id * GIET_CLUSTER_INCREMENT));
    9231012    // get page table address
    924     unsigned int user_ptab = _get_context_slot(task_id, CTX_PTAB_ID);
    925 
    926     // get peripheral buffer virtual address
    927     if (dev_type) {
    928         device_vaddr = (unsigned int) &seg_nic_base + offset;
    929     }
    930     else {
    931         device_vaddr = (unsigned int) &seg_fbf_base + offset;
     1013    unsigned int user_ptab = _get_context_slot(CTX_PTAB_ID);
     1014
     1015    // get devic buffer virtual address, depending on peripheral type
     1016    if (dev_type == 0)
     1017    {
     1018        device_vbase = (unsigned int) &seg_fbf_base + offset;
     1019    }
     1020    else
     1021    {
     1022        _get_lock(&_tty_put_lock);
     1023        _puts("\n[GIET ERROR] in _dma_transfer : device type not supported\n");
     1024        _release_lock(&_tty_put_lock);
     1025        return 1;
    9321026    }
    9331027
    9341028    // get device buffer physical address
    935     ko = _v2p_translate((page_table_t *) user_ptab, (device_vaddr >> 12), &ppn, &flags);
    936     if (ko) {
     1029    ko = _v2p_translate( (page_table_t*) user_ptab,
     1030                         (device_vbase >> 12),
     1031                         &ppn,
     1032                         &flags );
     1033    if (ko)
     1034    {
    9371035        _get_lock(&_tty_put_lock);
    9381036        _puts("\n[GIET ERROR] in _dma_transfer : device buffer unmapped\n");
    9391037        _release_lock(&_tty_put_lock);
    940         return 2;
    941     }
    942     device_pbase = (ppn << 12) | (device_vaddr & 0x00000FFF);
     1038        return 1;
     1039    }
     1040    device_pbase = ((paddr_t)ppn << 12) | (device_vbase & 0x00000FFF);
    9431041
    9441042    // Compute user buffer physical address
    945     ko = _v2p_translate((page_table_t*) user_ptab, (user_vaddr >> 12), &ppn, &flags);
    946     if (ko) {
     1043    ko = _v2p_translate( (page_table_t*) user_ptab,
     1044                         (user_vaddr >> 12),
     1045                         &ppn,
     1046                         &flags );
     1047    if (ko)
     1048    {
    9471049        _get_lock(&_tty_put_lock);
    9481050        _puts("\n[GIET ERROR] in _dma_transfer() : user buffer unmapped\n");
    9491051        _release_lock(&_tty_put_lock);
    950         return 3;
     1052        return 1;
    9511053    }
    952     if ((flags & PTE_U) == 0) {
     1054    if ((flags & PTE_U) == 0)
     1055    {
    9531056        _get_lock(&_tty_put_lock);
    9541057        _puts("[GIET ERROR] in _dma_transfer() : user buffer not in user space\n");
    9551058        _release_lock(&_tty_put_lock);
    956         return 4;
    957     }
    958     if (((flags & PTE_W) == 0 ) && to_user) {
     1059        return 1;
     1060    }
     1061    if (((flags & PTE_W) == 0 ) && to_user)
     1062    {
    9591063        _get_lock(&_tty_put_lock);
    9601064        _puts("\n[GIET ERROR] in _dma_transfer() : user buffer not writable\n");
    9611065        _release_lock(&_tty_put_lock);
    962         return 5;
    963     }
    964     user_pbase = (ppn << 12) | (user_vaddr & 0x00000FFF);
    965 
    966     /*  This is a draft for IOMMU support
     1066        return 1;
     1067    }
     1068    user_pbase = (((paddr_t)ppn) << 12) | (user_vaddr & 0x00000FFF);
     1069
     1070/*  This is a draft for IOMMU support
    9671071
    9681072    // loop on all virtual pages covering the user buffer
     
    10141118
    10151119    // invalidate data cache in case of memory write
    1016     if (to_user) {
    1017         _dcache_buf_invalidate((void *) user_vaddr, length);
    1018     }
    1019 
    1020     // get the lock
    1021     _get_lock(&_dma_lock[dma_id]);
     1120    if (to_user) _dcache_buf_invalidate((void *) user_vaddr, length);
     1121
     1122// get the lock
     1123//  _get_lock(&_dma_lock[dma_id]);
     1124
     1125#if GIET_DEBUG_DMA_DRIVER
     1126_get_lock(&_tty_put_lock);
     1127_puts("\n[GIET DEBUG] DMA TRANSFER at cycle ");
     1128_putd( _proctime() );
     1129_puts("\n - cluster_id       = ");
     1130_putx( cluster_id );
     1131_puts("\n - channel_id       = ");
     1132_putx( channel_id );
     1133_puts("\n - dma_vbase        = ");
     1134_putx( (unsigned int)dma_vbase );
     1135_puts("\n - device_buf_vbase = ");
     1136_putx( device_vbase );
     1137_puts("\n - device_buf_pbase = ");
     1138_putl( device_pbase );
     1139_puts("\n - user_buf_vbase   = ");
     1140_putx( user_vaddr );
     1141_puts("\n - user_buf_pbase   = ");
     1142_putl( user_pbase );
     1143_puts("\n");
     1144_release_lock(&_tty_put_lock);
     1145#endif
    10221146
    10231147    // DMA configuration
    1024     if (to_user) {
    1025         dma_base[loc_id * DMA_SPAN + DMA_SRC] = (unsigned int) device_pbase;
    1026         dma_base[loc_id * DMA_SPAN + DMA_DST] = (unsigned int) user_pbase;
    1027     }
    1028     else {
    1029         dma_base[loc_id * DMA_SPAN + DMA_SRC] = (unsigned int) user_pbase;
    1030         dma_base[loc_id * DMA_SPAN + DMA_DST] = (unsigned int) device_pbase;
    1031     }
    1032     dma_base[loc_id * DMA_SPAN + DMA_LEN] = (unsigned int) length;
    1033 
    1034     return 0;
    1035 #else //NB_DMAS_MAX == 0
    1036     return -1;
    1037 #endif
     1148    if (to_user)
     1149    {
     1150        dma_vbase[channel_id * DMA_SPAN + DMA_SRC]     = (unsigned int)(device_pbase);
     1151        dma_vbase[channel_id * DMA_SPAN + DMA_SRC_EXT] = (unsigned int)(device_pbase>>32);
     1152        dma_vbase[channel_id * DMA_SPAN + DMA_DST]     = (unsigned int)(user_pbase);
     1153        dma_vbase[channel_id * DMA_SPAN + DMA_DST_EXT] = (unsigned int)(user_pbase>>32);
     1154    }
     1155    else
     1156    {
     1157        dma_vbase[channel_id * DMA_SPAN + DMA_SRC]     = (unsigned int)(user_pbase);
     1158        dma_vbase[channel_id * DMA_SPAN + DMA_SRC_EXT] = (unsigned int)(user_pbase>>32);
     1159        dma_vbase[channel_id * DMA_SPAN + DMA_DST]     = (unsigned int)(device_pbase);
     1160        dma_vbase[channel_id * DMA_SPAN + DMA_DST_EXT] = (unsigned int)(device_pbase>>32);
     1161    }
     1162    dma_vbase[channel_id * DMA_SPAN + DMA_LEN] = (unsigned int) length;
     1163
     1164    return 0;
     1165
     1166#else // NB_DMA_CHANNELS == 0
     1167    _get_lock(&_tty_put_lock);
     1168    _puts("\n[GIET ERROR] in _dma_transfer() : NB_DMA_CHANNELS == 0");
     1169    _release_lock(&_tty_put_lock);
     1170    return 1;
     1171#endif
     1172
    10381173}  // end _dma_transfer() 
    10391174
     
    10471182// (1 == read error / 2 == DMA idle error / 3 == write error)
    10481183//////////////////////////////////////////////////////////////////////////////////
    1049 unsigned int _dma_completed() {
    1050 #if NB_DMAS_MAX > 0
    1051     unsigned int task_id = _get_proc_task_id();
    1052     unsigned int dma_id  = _get_context_slot(task_id, CTX_DMA_ID);
     1184unsigned int _dma_completed()
     1185{
     1186#if NB_DMA_CHANNELS > 0
     1187    unsigned int dma_id  = _get_context_slot(CTX_DMA_ID);
    10531188    unsigned int dma_ret;
    10541189
    10551190    // busy waiting with a pseudo random delay between bus access
    1056     while (_dma_done[dma_id] == 0) {
     1191    while (_dma_done[dma_id] == 0)
     1192    {
    10571193        unsigned int delay = (( _proctime() ^ _procid() << 4) & 0x3F) + 1;
    10581194        asm volatile(
     
    10671203    }
    10681204
    1069     /* draft support for IOMMU
    1070     // unmap the buffer from IOMMU page table if IOMMU is activated
    1071     if ( GIET_IOMMU_ACTIVE )
    1072     {
    1073     unsigned int* iob_address = (unsigned int*)&seg_iob_base;
    1074 
    1075     unsigned int  ix1         = _dma_iommu_ix1 + dma_id;
    1076     unsigned int  ix2;
    1077 
    1078     for ( ix2 = 0 ; ix2 < _dma_iommu_npages[dma_id] ; ix2++ )
    1079     {
    1080     // unmap the page in IOMMU page table
    1081     _iommu_inval_pte2( ix1,        // PT1 index
    1082     ix2 );   // PT2 index
    1083 
    1084     // clear IOMMU TLB
    1085     iob_address[IOB_INVAL_PTE] = (ix1 << 21) | (ix2 << 12);
    1086     }
    1087     }
    1088     */
     1205#if GIET_DEBUG_DMA_DRIVER
     1206_get_lock(&_tty_put_lock);
     1207_puts("\n[GIET DEBUG] DMA COMPLETED at cycle ");
     1208_putd( _proctime() );
     1209_puts("\n - cluster_id       = ");
     1210_putx( dma_id/NB_DMA_CHANNELS );
     1211_puts("\n - channel_id       = ");
     1212_putx( dma_id%NB_DMA_CHANNELS );
     1213_puts("\n");
     1214_release_lock(&_tty_put_lock);
     1215#endif
    10891216
    10901217    // reset synchronization variables
     
    10921219    dma_ret = _dma_status[dma_id];
    10931220    asm volatile("sync\n");
    1094     _dma_lock[dma_id] = 0;
     1221
     1222//    _dma_lock[dma_id] = 0;
    10951223
    10961224    return dma_ret;
    10971225
    1098 #else //NB_DMAS_MAX == 0
     1226#else // NB_DMA_CHANNELS == 0
    10991227    return -1;
    11001228#endif
     1229
    11011230}  // end _dma_completed
     1231
    11021232
    11031233//////////////////////////////////////////////////////////////////////////////////
     
    11131243// The '_fb_write()', '_fb_read()' and '_fb_completed()' functions use the
    11141244// VciMultiDma components (distributed in the clusters) to transfer data
    1115 // between the user buffer and the frame buffer. A  FBDMA channel is
     1245// between the user buffer and the frame buffer. A DMA channel is
    11161246// allocated to each task requesting it in the mapping_info data structure.
    11171247//////////////////////////////////////////////////////////////////////////////////
     
    11241254// - length : number of bytes to be transfered.
    11251255//////////////////////////////////////////////////////////////////////////////////
    1126 unsigned int _fb_sync_write(unsigned int offset, const void * buffer, unsigned int length) {
    1127     unsigned char * fb_address = (unsigned char *) &seg_fbf_base + offset;
     1256unsigned int _fb_sync_write( unsigned int   offset,
     1257                             const void*    buffer,
     1258                             unsigned int   length)
     1259{
     1260    unsigned char* fb_address = (unsigned char *) &seg_fbf_base + offset;
    11281261    memcpy((void *) fb_address, (void *) buffer, length);
    11291262    return 0;
     
    11381271// - length : number of bytes to be transfered.
    11391272//////////////////////////////////////////////////////////////////////////////////
    1140 unsigned int _fb_sync_read(unsigned int offset, const void * buffer, unsigned int length) {
    1141     unsigned char * fb_address = (unsigned char *) &seg_fbf_base + offset;
     1273unsigned int _fb_sync_read( unsigned int   offset,
     1274                            const void*    buffer,
     1275                            unsigned int   length)
     1276{
     1277    unsigned char* fb_address = (unsigned char *) &seg_fbf_base + offset;
    11421278    memcpy((void *) buffer, (void *) fb_address, length);
    11431279    return 0;
     
    11531289// Returns 0 if success, > 0 if error.
    11541290//////////////////////////////////////////////////////////////////////////////////
    1155 unsigned int _fb_write(unsigned int offset, const void * buffer, unsigned int length) {
    1156     return _dma_transfer(
    1157             0,             // frame buffer
    1158             0,             // write
    1159             offset,
    1160             (unsigned int) buffer,
    1161             length);
     1291unsigned int _fb_write( unsigned int   offset,
     1292                        const void*    buffer,
     1293                        unsigned int   length)
     1294{
     1295    return _dma_transfer( 0,             // frame buffer
     1296                          0,             // write
     1297                          offset,
     1298                          (unsigned int) buffer,
     1299                          length );
    11621300}
    11631301
     
    11711309// Returns 0 if success, > 0 if error.
    11721310//////////////////////////////////////////////////////////////////////////////////
    1173 unsigned int _fb_read(unsigned int offset, const void * buffer, unsigned int length) {
    1174     return _dma_transfer(
    1175             0,    // frame buffer
    1176             1,    // read
    1177             offset,
    1178             (unsigned int) buffer,
    1179             length);
     1311unsigned int _fb_read( unsigned int   offset,
     1312                       const void*    buffer,
     1313                       unsigned int   length )
     1314{
     1315    return _dma_transfer( 0,    // frame buffer
     1316                          1,    // read
     1317                          offset,
     1318                          (unsigned int) buffer,
     1319                          length );
    11801320}
    11811321
     
    11881328// (1 == read error / 2 == DMA idle error / 3 == write error)
    11891329//////////////////////////////////////////////////////////////////////////////////
    1190 unsigned int _fb_completed() {
     1330unsigned int _fb_completed()
     1331{
    11911332    return _dma_completed();
    11921333}
     
    12151356// - length : number of bytes to be transfered.
    12161357//////////////////////////////////////////////////////////////////////////////////
    1217 unsigned int _nic_sync_write(unsigned int offset, const void * buffer, unsigned int length) {
    1218     unsigned char * nic_address = (unsigned char *) &seg_nic_base + offset;
     1358unsigned int _nic_sync_write( unsigned int   offset,
     1359                              const void*    buffer,
     1360                              unsigned int   length )
     1361{
     1362    unsigned char* nic_address = (unsigned char *) &seg_nic_base + offset;
    12191363    memcpy((void *) nic_address, (void *) buffer, length);
    12201364    return 0;
     
    12791423// (1 == read error / 2 == DMA idle error / 3 == write error)
    12801424//////////////////////////////////////////////////////////////////////////////////
    1281 unsigned int _nic_completed() {
     1425unsigned int _nic_completed()
     1426{
    12821427    return _dma_completed();
    12831428}
     
    12861431// _heap_info()
    12871432// This function returns the information associated to a heap (size and vaddr)
    1288 // It uses the global task id (CTX_GTID_ID, unique for each giet task) and the
    1289 // vspace id (CTX_VSID_ID) defined in the context
     1433// It uses the global task index (CTX_GTID_ID, unique for each giet task) and the
     1434// vspace index (CTX_VSID_ID) defined in the task context.
    12901435///////////////////////////////////////////////////////////////////////////////////
    1291 unsigned int _heap_info(unsigned int * vaddr, unsigned int * size) {
     1436unsigned int _heap_info( unsigned int* vaddr,
     1437                         unsigned int* size )
     1438{
    12921439    mapping_header_t * header  = (mapping_header_t *) (&seg_mapping_base);
    12931440    mapping_task_t * tasks     = _get_task_base(header);
    12941441    mapping_vobj_t * vobjs     = _get_vobj_base(header);
    12951442    mapping_vspace_t * vspaces = _get_vspace_base(header);
    1296     unsigned int taskid        = _get_context_slot(_get_proc_task_id(), CTX_GTID_ID);
    1297     unsigned int vspaceid      = _get_context_slot(_get_proc_task_id(), CTX_VSID_ID);
     1443
     1444    unsigned int taskid        = _get_context_slot(CTX_GTID_ID);
     1445    unsigned int vspaceid      = _get_context_slot(CTX_VSID_ID);
     1446
    12981447    int heap_local_vobjid      = tasks[taskid].heap_vobjid;
    1299     if (heap_local_vobjid != -1) {
     1448    if (heap_local_vobjid != -1)
     1449    {
    13001450        unsigned int vobjheapid = heap_local_vobjid + vspaces[vspaceid].vobj_offset;
    13011451        *vaddr                  = vobjs[vobjheapid].vaddr;
     
    13031453        return 0;
    13041454    }
    1305     else {
     1455    else
     1456    {
    13061457        *vaddr = 0;
    13071458        *size = 0;
  • soft/giet_vm/sys/exc_handler.c

    r232 r238  
    6767
    6868
    69 static void _display_cause(unsigned int type) {
     69static void _display_cause(unsigned int type)
     70{
    7071    _get_lock(&_tty_put_lock);
    7172    _puts("\n[GIET] Exception for task ");
    72     _putd(_get_proc_task_id());
     73    _putd(_get_context_slot(CTX_LTID_ID));
    7374    _puts(" on processor ");
    7475    _putd(_procid());
     
    8687
    8788    // goes to sleeping state
    88     unsigned int task_id = _get_proc_task_id();
    89     _set_context_slot( task_id, CTX_RUN_ID, 0);
     89    _set_context_slot(CTX_RUN_ID, 0);
    9090
    9191    // deschedule
  • soft/giet_vm/sys/hwr_mapping.h

    r228 r238  
    77
    88/* IOC (block device) */
    9 enum IOC_registers {
     9enum IOC_registers
     10{
    1011    BLOCK_DEVICE_BUFFER,
    1112    BLOCK_DEVICE_LBA,
     
    1617    BLOCK_DEVICE_SIZE,
    1718    BLOCK_DEVICE_BLOCK_SIZE,
     19    BLOCK_DEVICE_BUFFER_EXT,
    1820};
    19 enum IOC_operations {
     21enum IOC_operations
     22{
    2023    BLOCK_DEVICE_NOOP,
    2124    BLOCK_DEVICE_READ,
    2225    BLOCK_DEVICE_WRITE,
    2326};
    24 enum IOC_status{
     27enum IOC_status
     28{
    2529    BLOCK_DEVICE_IDLE,
    2630    BLOCK_DEVICE_BUSY,
     
    3337
    3438/* DMA */
    35 enum DMA_registers {
     39enum DMA_registers
     40{
    3641    DMA_SRC         = 0,
    3742    DMA_DST         = 1,
     
    3944    DMA_RESET       = 3,
    4045    DMA_IRQ_DISABLE = 4,
     46    DMA_SRC_EXT     = 5,
     47    DMA_DST_EXT     = 6,
    4148    /**/
    42     DMA_END         = 5,
     49    DMA_END         = 7,
    4350    DMA_SPAN        = 8,
    4451};
    4552
    4653/* GCD */
    47 enum GCD_registers {
     54enum GCD_registers
     55{
    4856    GCD_OPA     = 0,
    4957    GCD_OPB     = 1,
     
    5563
    5664/* ICU */
    57 enum ICU_registers {
     65enum ICU_registers
     66{
    5867    ICU_INT         = 0,
    5968    ICU_MASK        = 1,
     
    6574    ICU_SPAN        = 8,
    6675};
    67 enum Xicu_registers {
     76enum Xicu_registers
     77{
    6878    XICU_WTI_REG = 0,
    6979    XICU_PTI_PER = 1,
     
    92102
    93103/* TIMER */
    94 enum TIMER_registers {
     104enum TIMER_registers
     105{
    95106    TIMER_VALUE     = 0,
    96107    TIMER_MODE      = 1,
     
    102113
    103114/* TTY */
    104 enum TTY_registers {
     115enum TTY_registers
     116{
    105117    TTY_WRITE   = 0,
    106118    TTY_STATUS  = 1,
     
    112124
    113125/* IOB */
    114 enum IOB_registers {
     126enum IOB_registers
     127{
    115128    IOB_IOMMU_PTPR       = 0, /* R/W : Page Table Pointer Register */
    116129    IOB_IOMMU_ACTIVE     = 1, /* R/W : IOMMU activated if not 0 */
     
    125138
    126139/* MWMR */
    127 enum SoclibMwmrRegisters {
     140enum SoclibMwmrRegisters
     141{
    128142    MWMR_IOREG_MAX = 16,
    129143    MWMR_RESET = MWMR_IOREG_MAX,
     
    138152};
    139153
    140 enum SoclibMwmrWay {
     154enum SoclibMwmrWay
     155{
    141156    MWMR_TO_COPROC,
    142157    MWMR_FROM_COPROC,
  • soft/giet_vm/sys/irq_handler.c

    r237 r238  
    1919#include <hwr_mapping.h>
    2020
    21 #if NB_TIMERS_MAX
    22 extern volatile unsigned char _user_timer_event[NB_CLUSTERS * NB_TIMERS_MAX] ;
     21#if NB_TIM_CHANNELS
     22extern volatile unsigned char _user_timer_event[NB_CLUSTERS * NB_TIM_CHANNELS] ;
    2323#endif
    2424
     
    3333//
    3434// There is one interrupt vector per processor (stored in the scheduler associated
    35 // to the processor. Each interrupt vector entry contains two 16 bits fields:
    36 // - isr_id : defines the type of ISR to be executed.
     35// to the processor. Each interrupt vector entry contains three bits fields:
     36// - isr_id     : defines the type of ISR to be executed.
     37// - type_id    : HWI if zero / PTI if non zero
    3738// - channel_id : defines the specific channel for multi-channels peripherals.
    3839//
     
    4041// a global index : channel_id = cluster_id * NB_CHANNELS_MAX + loc_id   
    4142///////////////////////////////////////////////////////////////////////////////////
    42 void _irq_demux() {
     43void _irq_demux()
     44{
    4345    unsigned int pid = _procid();
    4446    unsigned int irq_id;
    4547
    46 
    4748    // get the highest priority active IRQ index
    48     if (_icu_get_index( pid / NB_PROCS_MAX, pid % NB_PROCS_MAX, &irq_id)) {
     49    if (_icu_get_index( pid / NB_PROCS_MAX, pid % NB_PROCS_MAX, &irq_id))
     50    {
    4951        _get_lock(&_tty_put_lock);
    5052        _puts("\n[GIET ERROR] Strange... Wrong _icu_read in _irq_demux()\n");
     
    5254    }
    5355
    54 
    55     if (irq_id < 32) {
    56         // do nothing if no interrupt active
    57         unsigned int entry = _get_interrupt_vector_entry(irq_id);
    58         unsigned int isr_id = entry & 0x000000FF;
    59         unsigned int type_id = (entry >> 8) & 0x000000FF;
    60         unsigned int channel_id = (entry >> 16) & 0x0000FFFF;
     56    // do nothing if no interrupt active
     57    if (irq_id < 32)
     58    {
     59        static_scheduler_t* psched     = _get_sched();
     60        unsigned int        entry      = psched->interrupt_vector[irq_id];
     61        unsigned int        isr_id     = entry & 0x000000FF;
     62        unsigned int        type_id    = (entry >> 8) & 0x000000FF;
     63        unsigned int        channel_id = (entry >> 16) & 0x0000FFFF;
     64
    6165        if(type_id == 0) // HARD irq type
    6266        {
     
    7680}
    7781
    78 
    7982///////////////////////////////////////////////////////////////////////////////////
    8083//     _isr_default()
     
    8285// interrupt vector. It simply displays an error message on kernel TTY[0].
    8386///////////////////////////////////////////////////////////////////////////////////
    84 void _isr_default() {
     87void _isr_default()
     88{
    8589    _get_lock(&_tty_put_lock);
    8690    _puts("\n[GIET ERROR] Strange... Default ISR activated for processor ");
     
    96100// The multi_dma components can be distributed in the clusters.
    97101// The channel_id argument is the local DMA channel index.
    98 //     dma_global_id = cluster_id*NB_DMAS_MAX + channel_id
     102//     dma_global_id = cluster_id*NB_DMA_CHANNELS + channel_id
    99103// - The ISR saves the transfert status in _dma_status[dma_global_id].
    100104// - It acknowledges the interrupt to reinitialize the DMA controler.
    101105// - it resets the synchronisation variable _dma_busy[dma_global_id].
    102106///////////////////////////////////////////////////////////////////////////////////
    103 void _isr_dma(unsigned int channel_id) {
    104 #if NB_DMAS_MAX > 0
     107void _isr_dma(unsigned int channel_id)
     108{
     109#if NB_DMA_CHANNELS > 0
    105110    // compute cluster_id
    106111    unsigned int cluster_id = _procid() / NB_PROCS_MAX;
    107112
    108113    // compute dma_global_id
    109     unsigned int dma_global_id = cluster_id * NB_DMAS_MAX + channel_id;
     114    unsigned int dma_global_id = cluster_id * NB_DMA_CHANNELS + channel_id;
    110115
    111116    // save DMA channel status 
    112117    if (_dma_get_status(cluster_id, channel_id,
    113             (unsigned int *) &_dma_status[dma_global_id])) {
     118            (unsigned int *) &_dma_status[dma_global_id]))
     119    {
    114120        _get_lock(&_tty_put_lock);
    115121        _puts("[GIET ERROR] illegal DMA channel detected by _isr_dma\n");
     
    119125
    120126    // reset DMA channel irq
    121     if (_dma_reset_irq(cluster_id, channel_id)) {
     127    if (_dma_reset_irq(cluster_id, channel_id))
     128    {
    122129        _get_lock(&_tty_put_lock);
    123130        _puts("[GIET ERROR] illegal DMA channel detected by _isr_dma\n");
     
    128135    // release DMA channel
    129136    _dma_done[dma_global_id] = 1;
     137
    130138#else
    131     _puts("[GIET ERROR] NB_DMAS_MAX is set to zero\n");
    132 
     139    _get_lock(&_tty_put_lock);
     140    _puts("[GIET ERROR] NB_DMA_CHANNELS is set to zero\n");
     141    _release_lock(&_tty_put_lock);
    133142#endif
    134143}
     
    140149// - It sets the _ioc_done variable to signal completion.
    141150///////////////////////////////////////////////////////////////////////////////////
    142 void _isr_ioc() {
     151void _isr_ioc()
     152{
    143153    // save status & reset IRQ
    144     if (_ioc_get_status((unsigned int *) &_ioc_status )) {
     154    if (_ioc_get_status((unsigned int *) &_ioc_status ))
     155    {
    145156        _get_lock(&_tty_put_lock);
    146157        _puts("[GIET ERROR] bad access to IOC status detected by _isr_ioc\n");
     
    161172// in a vci_multi_timer component, or in a vci_xicu component.
    162173// The timer_id argument is the user timer local index.
    163 //     timer_globa_id = cluster_id*(NB_TIMERS_MAX) + timer_id
     174//     timer_globa_id = cluster_id*(NB_TIM_CHANNELS) + timer_id
    164175// The ISR acknowledges the IRQ and registers the event in the proper entry
    165176// of the _timer_event[] array, and a log message is displayed on kernel terminal.
    166177///////////////////////////////////////////////////////////////////////////////////
    167 void _isr_timer(unsigned int timer_id) {
     178void _isr_timer(unsigned int timer_id)
     179{
    168180    // compute cluster_id
    169181    unsigned int cluster_id = _procid() / NB_PROCS_MAX;
    170182
    171183    // aknowledge IRQ
    172     if (_timer_reset_irq( cluster_id, timer_id)) {
     184    if (_timer_reset_irq( cluster_id, timer_id))
     185    {
    173186        _get_lock(&_tty_put_lock);
    174187        _puts("[GIET ERROR] illegal timer index detected by _isr_timer\n");
     
    177190    }
    178191
    179 #if NB_TIMERS_MAX
     192#if NB_TIM_CHANNELS
    180193    // register the event
    181     unsigned int timer_global_id = cluster_id * NB_TIMERS_MAX + timer_id;
     194    unsigned int timer_global_id = cluster_id * NB_TIM_CHANNELS + timer_id;
    182195    _user_timer_event[timer_global_id] = 1;
    183196#endif
     
    207220// A character is lost if the buffer is full when the ISR is executed.
    208221///////////////////////////////////////////////////////////////////////////////////
    209 void _isr_tty(unsigned int tty_id) {
     222void _isr_tty(unsigned int tty_id)
     223{
    210224    // save character and reset IRQ
    211     if (_tty_get_char( tty_id, (unsigned char *) &_tty_get_buf[tty_id])) {
     225    if (_tty_get_char( tty_id, (unsigned char *) &_tty_get_buf[tty_id]))
     226    {
    212227        _get_lock(&_tty_put_lock);
    213228        _puts("[GIET ERROR] illegal tty index detected by _isr_tty\n");
     
    229244// The ISR acknowledges the IRQ and calls the _ctx_switch() function.
    230245/////////////////////////////////////////////////////////////////////////////////////
    231 void _isr_switch( unsigned int timer_id) {
     246void _isr_switch( unsigned int timer_id)
     247{
    232248    // get cluster index and proc local index
    233249    unsigned int cluster_id = _procid() / NB_PROCS_MAX;
    234250
    235251    // acknowledge IRQ
    236     if (_timer_reset_irq(cluster_id, timer_id)) {
     252    if (_timer_reset_irq(cluster_id, timer_id))
     253    {
    237254        _get_lock(&_tty_put_lock);
    238255        _puts("[GIET ERROR] illegal proc index detected by _isr_switch\n");
  • soft/giet_vm/sys/irq_handler.h

    r228 r238  
    22#define _IRQ_HANDLER_H
    33
    4 enum
     4enum isr_type_t
    55{
    66    ISR_DEFAULT = 0,
  • soft/giet_vm/sys/kernel_init.c

    r228 r238  
    3333
    3434///////////////////////////////////////////////////////////////////////////////////
    35 // array of pointers on the page tables (both virtual and physical addresses)
     35// array of pointers on the page tables (virtual addresses)
    3636///////////////////////////////////////////////////////////////////////////////////
    3737
    3838__attribute__((section (".kdata")))
    39 unsigned int _ptabs_paddr[GIET_NB_VSPACE_MAX];
     39unsigned int _ptabs[GIET_NB_VSPACE_MAX];    // virtual addresses
     40
     41__attribute__((section (".kdata")))       
     42unsigned int _ptprs[GIET_NB_VSPACE_MAX];    // physical addresses >> 13
     43
     44///////////////////////////////////////////////////////////////////////////////////
     45// array of pointers on the schedulers (physical addresses)
     46///////////////////////////////////////////////////////////////////////////////////
    4047
    4148__attribute__((section (".kdata")))
    42 unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX];
    43 
    44 ///////////////////////////////////////////////////////////////////////////////////
    45 // array of pointers on the schedulers (physical addresses)
     49static_scheduler_t* _schedulers[NB_CLUSTERS * NB_PROCS_MAX];
     50
     51///////////////////////////////////////////////////////////////////////////////////
     52// staks for the "idle" tasks (256 bytes for each processor)
    4653///////////////////////////////////////////////////////////////////////////////////
    4754
    4855__attribute__((section (".kdata")))
    49 static_scheduler_t * _schedulers_paddr[NB_CLUSTERS * NB_PROCS_MAX];
    50 
    51 ///////////////////////////////////////////////////////////////////////////////////
    52 // staks for the "idle" tasks (256 bytes for each processor)
    53 ///////////////////////////////////////////////////////////////////////////////////
    54 
    55 __attribute__((section (".kdata")))
    56 unsigned int _idle_stack[NB_CLUSTERS*NB_PROCS_MAX * 64];
    57 
    58 void _sys_exit() {
     56unsigned int _idle_stack[NB_CLUSTERS * NB_PROCS_MAX * 64];
     57
     58////////////////
     59void _sys_exit()
     60{
    5961    while (1);
    6062}
     
    6365//////////////////////////////////////////////////////////////////////////////////
    6466// This function is the entry point for the last step of the boot sequence.
     67// that is done in parallel by all processors, with MMU activated.
    6568//////////////////////////////////////////////////////////////////////////////////
    66 __attribute__((section (".kinit"))) void _kernel_init() {
    67     // compute cluster and local processor index
    68     unsigned int global_pid = _procid();
    69     unsigned int cluster_id = global_pid / NB_PROCS_MAX;
    70     unsigned int proc_id = global_pid % NB_PROCS_MAX;
    71 
    72     // Step 0 : Compute number of tasks allocated to proc
    73 
    74     unsigned int tasks = _get_tasks_number();
    75 
    76 #if GIET_DEBUG_INIT
    77     _get_lock(&_tty_put_lock);
    78     _puts("\n[GIET DEBUG] step 0 for processor ");
    79     _putd(global_pid);
    80     _puts(" : tasks = ");
    81     _putd(tasks);
    82     _puts("\n");
    83     _release_lock(&_tty_put_lock);
    84 #endif
    85 
    86     // step 1 : Initialise scheduler physical addresses array
    87     //          get scheduler physical address (from CP0 register)
    88 
    89     static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
    90     _schedulers_paddr[global_pid] = psched;
    91 
    92 #if GIET_DEBUG_INIT
    93     _get_lock(&_tty_put_lock);
    94     _puts("\n[GIET DEBUG] step 1 for processor ");
    95     _putd(global_pid);
    96     _puts(" / scheduler pbase = ");
    97     _putx((unsigned int) psched);
    98     _puts("\n");
    99     _release_lock(&_tty_put_lock);
    100 #endif
    101 
    102     // step 2 : initialise page table addresse arrays
     69__attribute__((section (".kinit"))) void _kernel_init()
     70{
     71    // Step 1 : get processor index,
     72    //          get scheduler address
     73    //          initialise _schedulers[] array
     74
     75    unsigned int        global_pid = _procid();
     76    unsigned int        cluster_id = global_pid / NB_PROCS_MAX;
     77    unsigned int        proc_id    = global_pid % NB_PROCS_MAX;
     78    static_scheduler_t* psched     = _get_sched();
     79    unsigned int        tasks      = psched->tasks;
     80
     81    _schedulers[global_pid] = psched;
     82
     83#if GIET_DEBUG_INIT
     84_get_lock(&_tty_put_lock);
     85_puts("\n[GIET DEBUG] step 1 for processor ");
     86_putd(global_pid);
     87_puts(" : tasks = ");
     88_putd(tasks);
     89_puts(" / scheduler vbase = ");
     90_putx((unsigned int) psched);
     91_puts("\n");
     92_release_lock(&_tty_put_lock);
     93#endif
     94
     95    // step 2 : initialise ptabs[] & ptprs[] arrays
    10396    //          each processor scans all tasks contexts in its
    10497    //          private scheduler and get VSID, PTAB and PTPR values
     
    10699    unsigned int ltid;
    107100
    108     for (ltid = 0; ltid < tasks; ltid++) {
    109         unsigned int vspace_id = _get_context_slot(ltid , CTX_VSID_ID);
    110         unsigned int ptab_vaddr = _get_context_slot(ltid , CTX_PTAB_ID);
    111         unsigned int ptab_paddr = _get_context_slot(ltid , CTX_PTPR_ID) << 13;
    112 
    113         _ptabs_vaddr[vspace_id] = ptab_vaddr;
    114         _ptabs_paddr[vspace_id] = ptab_paddr;
    115 
    116 #if GIET_DEBUG_INIT
    117         _get_lock(&_tty_put_lock);
    118         _puts("\n[GIET DEBUG] step 2 for processor ");
    119         _putd(global_pid);
    120         _puts(" / vspace ");
    121         _putd(vspace_id);
    122         _puts("\n- ptab vbase = ");
    123         _putx(ptab_vaddr);
    124         _puts("\n- ptab pbase = ");
    125         _putx(ptab_paddr);
    126         _puts("\n");
    127         _release_lock(&_tty_put_lock);
     101    for (ltid = 0; ltid < tasks; ltid++)
     102    {
     103        unsigned int vsid  = _get_task_slot(ltid , CTX_VSID_ID);
     104        unsigned int ptab  = _get_task_slot(ltid , CTX_PTAB_ID);
     105        unsigned int ptpr  = _get_task_slot(ltid , CTX_PTPR_ID);
     106
     107        _ptabs[vsid] = ptab;
     108        _ptprs[vsid] = ptpr;
     109
     110#if GIET_DEBUG_INIT
     111_get_lock(&_tty_put_lock);
     112_puts("\n[GIET DEBUG] step 2 for processor ");
     113_putd(global_pid);
     114_puts(" / vspace ");
     115_putd(vsid);
     116_puts("\n- ptab = ");
     117_putx(ptab);
     118_puts("\n- ptpr = ");
     119_putx(ptpr);
     120_puts("\n");
     121_release_lock(&_tty_put_lock);
    128122#endif
    129123
    130124    }
    131 
    132     unsigned int isr_switch_channel = 0xFFFFFFFF;
    133125
    134126    // step 3 : compute and set ICU masks
     
    136128    //          software interrupts are not supported yet
    137129
    138     unsigned int irq_id;
     130    unsigned int isr_switch_channel = 0xFFFFFFFF;
     131    unsigned int irq_id;            // IN_IRQ index
    139132    unsigned int hwi_mask = 0;
    140133    unsigned int pti_mask = 0;
    141134
    142     for (irq_id = 0; irq_id < 32; irq_id++) {
    143         unsigned int entry = _get_interrupt_vector_entry(irq_id);
    144         unsigned int isr = entry & 0x000000FF;
    145 
    146         if ((isr == ISR_DMA) || (isr == ISR_IOC) || (isr == ISR_TTY)) {
     135    for (irq_id = 0; irq_id < 32; irq_id++)
     136    {
     137        unsigned int entry = psched->interrupt_vector[irq_id];
     138        unsigned int isr   = entry & 0x000000FF;
     139
     140        if ((isr == ISR_DMA) || (isr == ISR_IOC) || (isr == ISR_TTY))
     141        {
    147142            hwi_mask = hwi_mask | 0x1 << irq_id;
    148143        }
    149         else if ((isr == ISR_SWITCH)) {
     144        else if ((isr == ISR_SWITCH))
     145        {
    150146            pti_mask = pti_mask | 0x1 << irq_id;
    151147            isr_switch_channel = irq_id;
    152148        }
    153         else if ((isr == ISR_TIMER)) {
     149        else if ((isr == ISR_TIMER))
     150        {
    154151            pti_mask = pti_mask | 0x1 << irq_id;
    155152        }
    156153    }
     154
     155#if GIET_DEBUG_INIT
     156_get_lock(&_tty_put_lock);
     157_puts("\n[GIET DEBUG] step 3 for processor ");
     158_putd(global_pid);
     159_puts("\n - ICU HWI_MASK = ");
     160_putx(hwi_mask);
     161_puts("\n - ICU PTI_MASK = ");
     162_putx(pti_mask);
     163_puts("\n");
     164_release_lock(&_tty_put_lock);
     165#endif
     166
    157167    _icu_set_mask(cluster_id, proc_id, hwi_mask, 0); // set HWI_MASK
    158168    _icu_set_mask(cluster_id, proc_id, pti_mask, 1); // set PTI_MASK
    159169
    160 #if GIET_DEBUG_INIT
    161     _get_lock(&_tty_put_lock);
    162     _puts("\n[GIET DEBUG] step 3 for processor ");
    163     _putd(global_pid);
    164     _puts("\n - ICU HWI_MASK = ");
    165     _putx(hwi_mask);
    166     _puts("\n - ICU PTI_MASK = ");
    167     _putx(pti_mask);
    168     _puts("\n");
    169     _release_lock(&_tty_put_lock);
    170 #endif
    171 
    172170    // step 4 : start TICK timer if more than one task
    173     if (tasks > 1) {
    174         if (isr_switch_channel == 0xFFFFFFFF) {
     171    if (tasks > 1)
     172    {
     173        if (isr_switch_channel == 0xFFFFFFFF)
     174        {
    175175            _get_lock(&_tty_put_lock);
    176176            _puts("\n[GIET ERROR] ISR_SWITCH not found on proc ");
     
    181181        }
    182182
    183         if (_timer_start( cluster_id, isr_switch_channel, GIET_TICK_VALUE)) {
     183        if (_timer_start( cluster_id, isr_switch_channel, GIET_TICK_VALUE))
     184        {
    184185            _get_lock(&_tty_put_lock);
    185186            _puts("\n[GIET ERROR] ISR_SWITCH init error for proc ");
     
    191192
    192193#if GIET_DEBUG_INIT
    193         _get_lock(&_tty_put_lock);
    194         _puts("\n[GIET DEBUG] Step 4 for processor ");
    195         _putd(global_pid);
    196         _puts(" / context switch activated\n");
    197         _release_lock(&_tty_put_lock);
     194_get_lock(&_tty_put_lock);
     195_puts("\n[GIET DEBUG] Step 4 for processor ");
     196_putd(global_pid);
     197_puts(" / context switch activated\n");
     198_release_lock(&_tty_put_lock);
    198199#endif
    199200
     
    206207    //          the stack size is 256 bytes
    207208
    208     _set_context_slot( IDLE_TASK_INDEX, CTX_RUN_ID, 1);
    209     _set_context_slot( IDLE_TASK_INDEX, CTX_SR_ID,  0xFF03);
    210     _set_context_slot( IDLE_TASK_INDEX, CTX_SP_ID,  (unsigned int) _idle_stack + ((global_pid + 1) << 8));
    211     _set_context_slot( IDLE_TASK_INDEX, CTX_RA_ID,  (unsigned int) &_ctx_eret);
    212     _set_context_slot( IDLE_TASK_INDEX, CTX_EPC_ID, (unsigned int) &_ctx_idle);
    213     _set_context_slot( IDLE_TASK_INDEX, CTX_LTID_ID, IDLE_TASK_INDEX);
    214     _set_context_slot( IDLE_TASK_INDEX, CTX_PTPR_ID, _ptabs_paddr[0] >> 13);
    215 
    216 #if GIET_DEBUG_INIT
    217     _get_lock(&_tty_put_lock);
    218     _puts("\n[GIET DEBUG] Step 5 for processor ");
    219     _putd(global_pid);
    220     _puts(" / idle task context set\n");
    221     _release_lock(&_tty_put_lock);
     209    unsigned int stack = (unsigned int)_idle_stack + ((global_pid + 1)<<8);
     210
     211    _set_task_slot( IDLE_TASK_INDEX, CTX_RUN_ID, 1);
     212    _set_task_slot( IDLE_TASK_INDEX, CTX_SR_ID,  0xFF03);
     213    _set_task_slot( IDLE_TASK_INDEX, CTX_SP_ID,  stack);
     214    _set_task_slot( IDLE_TASK_INDEX, CTX_RA_ID,  (unsigned int) &_ctx_eret);
     215    _set_task_slot( IDLE_TASK_INDEX, CTX_EPC_ID, (unsigned int) &_ctx_idle);
     216    _set_task_slot( IDLE_TASK_INDEX, CTX_LTID_ID, IDLE_TASK_INDEX);
     217    _set_task_slot( IDLE_TASK_INDEX, CTX_PTPR_ID, _ptprs[0]);
     218
     219#if GIET_DEBUG_INIT
     220_get_lock(&_tty_put_lock);
     221_puts("\n[GIET DEBUG] Step 5 for processor ");
     222_putd(global_pid);
     223_puts(" / idle task context set\n");
     224_release_lock(&_tty_put_lock);
    222225#endif
    223226
     
    226229    //          and starts the "idle" task if there is no task allocated.
    227230
    228     unsigned int task_id;
    229 
    230     if (tasks == 0) {
    231         task_id = IDLE_TASK_INDEX;
     231    ltid = 0;
     232
     233    if (tasks == 0)
     234    {
     235        ltid = IDLE_TASK_INDEX;
    232236
    233237        _get_lock(&_tty_put_lock);
     
    237241        _release_lock (&_tty_put_lock);
    238242    }
    239     else {
    240         task_id = 0;
    241     }
    242 
    243     unsigned int sp_value = _get_context_slot(task_id, CTX_SP_ID);
    244     unsigned int sr_value = _get_context_slot(task_id, CTX_SR_ID);
    245     unsigned int ptpr_value = _get_context_slot(task_id, CTX_PTPR_ID);
    246     unsigned int epc_value = _get_context_slot(task_id, CTX_EPC_ID);
    247 
    248 #if GIET_DEBUG_INIT
    249     _get_lock(&_tty_put_lock);
    250     _puts("\n[GIET DEBUG] step 6 for processor ");
    251     _putd(global_pid);
    252     _puts(" / registers initialised \n");
    253     _puts("- sp   = ");
    254     _putx(sp_value);
    255     _puts("\n");
    256     _puts("- sr   = ");
    257     _putx(sr_value);
    258     _puts("\n");
    259     _puts("- ptpr = ");
    260     _putx(ptpr_value << 13);
    261     _puts("\n");
    262     _puts("- epc  = ");
    263     _putx(epc_value);
    264     _puts("\n");
    265     _release_lock(&_tty_put_lock);
    266 #endif
     243
     244    unsigned int sp_value   = _get_task_slot(ltid, CTX_SP_ID);
     245    unsigned int sr_value   = _get_task_slot(ltid, CTX_SR_ID);
     246    unsigned int ptpr_value = _get_task_slot(ltid, CTX_PTPR_ID);
     247    unsigned int epc_value  = _get_task_slot(ltid, CTX_EPC_ID);
     248
     249    _set_task_slot( ltid, CTX_LTID_ID, ltid);
     250
     251#if GIET_DEBUG_INIT
     252_get_lock(&_tty_put_lock);
     253_puts("\n[GIET DEBUG] step 6 for processor ");
     254_putd(global_pid);
     255_puts(" / registers initialised \n");
     256_puts("- sp   = ");
     257_putx(sp_value);
     258_puts("\n");
     259_puts("- sr   = ");
     260_putx(sr_value);
     261_puts("\n");
     262_puts("- ptpr = ");
     263_putx(ptpr_value);
     264_puts("\n");
     265_puts("- epc  = ");
     266_putx(epc_value);
     267_puts("\n");
     268_release_lock(&_tty_put_lock);
     269#endif
     270
     271_get_lock(&_tty_put_lock);
     272_puts("\n[GIET] Processor ");
     273_putd( global_pid );
     274_puts(" starting user code at cycle ");
     275_putd( _proctime() );
     276_puts("\n");
     277_release_lock(&_tty_put_lock);
    267278
    268279    // set  registers and jump to user code
  • soft/giet_vm/sys/mips32_registers.h

    r228 r238  
    4747/* CP0 registers */
    4848
    49 #define CP0_BVAR     $8
    50 #define CP0_TIME     $9
    51 #define CP0_SR       $12
    52 #define CP0_CR       $13
    53 #define CP0_EPC      $14
    54 #define CP0_PROCID   $15,1
    55 #define CP0_SCHED    $22
     49#define CP0_BVAR       $8
     50#define CP0_TIME       $9
     51#define CP0_SR         $12
     52#define CP0_CR         $13
     53#define CP0_EPC        $14
     54#define CP0_PROCID     $15,1
     55#define CP0_SCHED      $22,0
     56#define CP0_SCHED_EXT  $22,1
    5657
    5758/* CP2 registers */
  • soft/giet_vm/sys/switch.s

    r199 r238  
    11/******************************************************************************
    22* This function receives two arguments that are the current task context
    3 * physical addresses and the next task context physical address.
    4 * The DTLB is temporary desactivated...
     3* (virtual) addresses and the next task context (virtual) address.
    54******************************************************************************/
    65
     
    109
    1110_task_switch:
    12 
    13     /* desactivate DTLB */
    14     ori         $27,    $0,             0xB
    15     mtc2        $27,    $1                      /* DTLB desactivated */
    1611
    1712    /* save _current task context */
     
    113108    mtc2    $26,    $0          /* restore PTPR */
    114109
    115     /* activate DTLB */
    116     ori         $27,    $0,             0xF
    117     mtc2        $27,    $1     
    118 
    119110    /* returns to caller */
    120111    jr      $31
  • soft/giet_vm/sys/sys_handler.c

    r237 r238  
    3131    &_gcd_read,            /* 0x07 */
    3232    &_heap_info,           /* 0x08 */
    33     &_get_proc_task_id,    /* 0x09 */
    34     &_get_global_task_id,  /* 0x0A */
     33    &_local_task_id,       /* 0x09 */
     34    &_global_task_id,      /* 0x0A */
    3535    &_sys_ukn,             /* 0x0B */
    3636    &_sys_ukn,             /* 0x0C */
     
    6969}
    7070
    71 
    7271////////////////////////////////////////////////////////////////////////////
    7372// _exit()
     
    7776    unsigned int date = _proctime();
    7877    unsigned int proc_id = _procid();
    79     unsigned int task_id = _get_proc_task_id();
     78    unsigned int task_id = _get_context_slot(CTX_LTID_ID);
    8079
    8180    // print death message
     
    9190
    9291    // goes to sleeping state
    93     _set_context_slot( task_id, CTX_RUN_ID, 0);
     92    _set_context_slot(CTX_RUN_ID, 0);
    9493
    9594    // deschedule
     
    9796}
    9897
    99 
    10098//////////////////////////////////////////////////////////////////////////////
    10199// _procid()
     
    103101// Max number or processors is 1024.
    104102//////////////////////////////////////////////////////////////////////////////
    105 unsigned int _procid() {
     103unsigned int _procid()
     104{
    106105    unsigned int ret;
    107106    asm volatile("mfc0 %0, $15, 1" : "=r" (ret));
     
    109108}
    110109
    111 
    112110//////////////////////////////////////////////////////////////////////////////
    113111// _proctime()
    114112// Access CP0 and returns current processor's elapsed clock cycles since boot.
    115113//////////////////////////////////////////////////////////////////////////////
    116 unsigned int _proctime() {
     114unsigned int _proctime()
     115{
    117116    unsigned int ret;
    118117    asm volatile("mfc0 %0, $9" : "=r" (ret));
     
    120119}
    121120
    122 
    123121//////////////////////////////////////////////////////////////////////////////
    124122// _procnumber()
     
    126124// specified by the cluster_id argument.
    127125//////////////////////////////////////////////////////////////////////////////
    128 unsigned int _procs_number(unsigned int cluster_id, unsigned int * buffer) {
     126unsigned int _procs_number(unsigned int  cluster_id,
     127                           unsigned int* buffer)
     128{
    129129    mapping_header_t * header  = (mapping_header_t *) &seg_mapping_base;
    130130    mapping_cluster_t * cluster = _get_cluster_base(header);
     
    139139}
    140140
    141 
    142 int _get_vobj(char * vspace_name, char * vobj_name, unsigned int vobj_type, mapping_vobj_t ** res_vobj) {
     141/////////////////////////////////////////////////////////////////////////////
     142// _local_task_id()
     143// Returns current task local index.
     144/////////////////////////////////////////////////////////////////////////////
     145unsigned int _local_task_id()
     146{
     147    return _get_context_slot(CTX_LTID_ID);
     148}
     149
     150/////////////////////////////////////////////////////////////////////////////
     151// _global_task_id()
     152// Returns current task global index.
     153/////////////////////////////////////////////////////////////////////////////
     154unsigned int _global_task_id()
     155{
     156    return _get_context_slot(CTX_GTID_ID);
     157}
     158
     159/////////////////////////////////////////////////////////////////////////////
     160// _get_vobj()
     161// This function writes in res_vobj a pointer on a vobj
     162// identified by the (vspace_name / vobj_name ) couple.
     163// The vobj_type argument is here only for the purpose of checking .
     164// returns 0: success, else: failed.
     165/////////////////////////////////////////////////////////////////////////////
     166int _get_vobj( char*             vspace_name,
     167               char*             vobj_name,
     168               unsigned int      vobj_type,
     169               mapping_vobj_t**  res_vobj )
     170{
    143171    mapping_header_t * header = (mapping_header_t *) &seg_mapping_base;
    144172    mapping_vspace_t * vspace = _get_vspace_base(header);
    145     mapping_vobj_t * vobj  = _get_vobj_base(header);
     173    mapping_vobj_t * vobj     = _get_vobj_base(header);
    146174
    147175    unsigned int vspace_id;
     
    149177
    150178    // scan vspaces
    151     for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) {
    152         if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) {
     179    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++)
     180    {
     181        if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0)
     182        {
    153183            // scan vobjs
    154184            for (vobj_id = vspace[vspace_id].vobj_offset;
    155185                 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs);
    156                  vobj_id++) {
    157 
    158                 if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) {
    159                     if (vobj[vobj_id].type != vobj_type) {
     186                 vobj_id++)
     187            {
     188                if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0)
     189                {
     190                    if (vobj[vobj_id].type != vobj_type)
     191                    {
    160192                        _get_lock(&_tty_put_lock);
    161193                        _puts("*** Error in _get_obj: wrong type\n");
     
    176208}
    177209
    178 
    179210/////////////////////////////////////////////////////////////////////////////
    180211// _vobj_get_vbase()
     
    184215// returns 0: success, else: failed.
    185216/////////////////////////////////////////////////////////////////////////////
    186 unsigned int _vobj_get_vbase(
    187         char * vspace_name,
    188         char * vobj_name,
    189         unsigned int vobj_type,
    190         unsigned int * vobj_vaddr) {
    191     mapping_vobj_t * res_vobj;
    192     unsigned int ret;
    193     if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) {
     217unsigned int _vobj_get_vbase( char*         vspace_name,
     218                              char*         vobj_name,
     219                              unsigned int  vobj_type,
     220                              unsigned int* vobj_vaddr )
     221{
     222    mapping_vobj_t* res_vobj;
     223    unsigned int    ret;
     224    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj)))
     225    {
    194226        return ret;
    195227    }
    196 
    197228    *vobj_vaddr = res_vobj->vaddr;
    198229    return 0;
    199230}
    200 
    201231
    202232/////////////////////////////////////////////////////////////////////////////
     
    207237// returns 0: success, else: failed.
    208238/////////////////////////////////////////////////////////////////////////////
    209 unsigned int _vobj_get_length(
    210         char * vspace_name,
    211         char * vobj_name,
    212         unsigned int vobj_type,
    213         unsigned int * vobj_length) {
    214 
     239unsigned int _vobj_get_length( char*         vspace_name,
     240                               char*         vobj_name,
     241                               unsigned int  vobj_type,
     242                               unsigned int* vobj_length )
     243{
    215244    mapping_vobj_t * res_vobj;
    216245    unsigned int ret;
    217     if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) {
     246    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj)))
     247    {
    218248        return ret;
    219249    }
    220 
    221250    *vobj_length = res_vobj->length;
    222 
    223251    return 0;
    224252}
     
    229257// This functions masks interruptions before calling _ctx_switch
    230258// (They are usually masked when we receive a isr_switch interrupt
    231 // because we execute isrs with interrupt masked)
     259// because we execute ISRs with interrupt masked)
    232260////////////////////////////////////////////////////////////////
    233 void _context_switch() {
     261void _context_switch()
     262{
    234263    _it_disable();
    235264    _ctx_switch();
  • soft/giet_vm/sys/sys_handler.h

    r228 r238  
    1919//////////////////////////////////////////////////////////////////////////////////
    2020
    21 void _sys_ukn();
    22 void _exit();
    23 void _context_switch();
     21void         _sys_ukn();
     22void         _exit();
     23void         _context_switch();
    2424unsigned int _procid();
    2525unsigned int _proctime();
    26 unsigned int _procs_number(unsigned int cluster_id, unsigned int * buffer );
    27 unsigned int _vobj_get_vbase(char * vspace_name, char * vobj_name, unsigned vobj_type, unsigned int * vobj_buffer);
     26unsigned int _local_task_id();
     27unsigned int _global_task_id();
     28
     29unsigned int _procs_number( unsigned int  cluster_id,
     30                            unsigned int* buffer );
     31
     32unsigned int _vobj_get_vbase( char*         vspace_name,
     33                              char*         vobj_name,
     34                              unsigned      vobj_type,
     35                              unsigned int* vobj_buffer);
    2836
    2937#endif
  • soft/giet_vm/sys/vm_handler.c

    r228 r238  
    88// They contains the kernel data structures and functions used to dynamically
    99// handle the iommu page table.
    10 //
    11 // TODO : We must transfer here the functions used to statically build
    12 // the page tables associated to the various vspaces (now in boot_handler.c)
    13 //
    1410///////////////////////////////////////////////////////////////////////////////////
    1511
     
    1814#include <common.h>
    1915#include <giet_config.h>
     16#include <drivers.h>
    2017
    2118/////////////////////////////////////////////////////////////////////////////
     
    8885// Returns 0 if success, 1 if PTE1 or PTE2 unmapped
    8986//////////////////////////////////////////////////////////////////////////////
    90 unsigned int _v2p_translate(
    91         page_table_t * pt,
    92         unsigned int vpn,
    93         unsigned int * ppn,       
    94         unsigned int * flags) {
    95     unsigned int ptba;
    96     register unsigned int * pte2;
    97     register unsigned int flags_value;
    98     register unsigned int ppn_value;
     87unsigned int _v2p_translate( page_table_t*   pt,
     88                             unsigned int    vpn,
     89                             unsigned int*   ppn,       
     90                             unsigned int*   flags )
     91{
     92    paddr_t                 ptba;
     93    paddr_t                 pte2;
     94
     95    register unsigned int   pte2_msb;
     96    register unsigned int   pte2_lsb;
     97    register unsigned int   flags_value;
     98    register unsigned int   ppn_value;
    9999
    100100    unsigned int ix1 = vpn >> 9;
    101101    unsigned int ix2 = vpn & 0x1FF;
    102     /*
    103        _puts("\n\n********************** entering v2p_translate");
    104        _puts("\n - pt    = ");
    105        _putx( (unsigned int)pt );
    106        _puts("\n - vpn   = ");
    107        _putx( vpn << 12 );
    108        _puts("\n - ptba  = ");
    109        _putx( pt->pt1[ix1] << 12 ) ;
    110        _puts("\n - &pte2 = ");
    111        _putx( (pt->pt1[ix1] << 12) + 8*ix2 );
    112        _puts("\n - flags = ");
    113        _putx( *(unsigned int*)((pt->pt1[ix1] << 12) + 8*ix2) );
    114        _puts("\n");
    115        */
     102
    116103    // check PTE1 mapping
    117     if ((pt->pt1[ix1] & PTE_V) == 0) {
    118         return 1;
    119     }
    120     else {
     104    if ((pt->pt1[ix1] & PTE_V) == 0) return 1;
     105    else
     106    {
    121107        // get physical addresses of pte2
    122         ptba = pt->pt1[ix1] << 12;
    123         pte2 = (unsigned int *) (ptba + 8 * ix2);
     108        ptba     = (paddr_t)(pt->pt1[ix1] & 0x0FFFFFFF) << 12;
     109        pte2     = ptba + 8*ix2;
     110        pte2_lsb = (unsigned int)pte2;
     111        pte2_msb = (unsigned int)(pte2 >> 32);
    124112
    125113        // gets ppn_value and flags_value, after temporary DTLB desactivation
    126114        asm volatile (
    127                 "li      $27,    0xFFFFFFFE  \n"     /* Mask for IE bits     */
    128                 "mfc0    $26,    $12         \n"     /* save SR              */
    129                 "and     $27,    $26,    $27 \n"
    130                 "mtc0    $27,    $12         \n"     /* disable Interrupts   */
     115                "li      $2,     0xFFFFFFFE  \n"     /* Mask for IE bits     */
     116                "mfc0    $4,     $12         \n"     /* $4 <= SR             */
     117                "and     $2,     $2,    $4  \n"
     118                "mtc0    $2,     $12         \n"     /* disable Interrupts   */
    131119
    132                 "li      $27,    0xB         \n"     
    133                 "mtc2    $27,    $1          \n"     /* DTLB unactivated     */
     120                "li      $3,     0xB         \n"     
     121                "mtc2    $3,     $1          \n"     /* DTLB unactivated     */
    134122
    135                 "move    $27,    %2          \n"     /* $27 <= pte2          */
    136                 "lw      %0,     0($27)      \n"     /* read flags           */
    137                 "lw      %1,     4($27)      \n"     /* read ppn             */
     123                "mtc2    %2,     $24         \n"     /* PADDR_EXT <= msb     */
     124                "lw      %0,     0(%3)       \n"     /* read flags           */
     125                "lw      %1,     4(%3)       \n"     /* read ppn             */
     126                "mtc2    $0,     $24         \n"     /* PADDR_EXT <= 0       */
    138127
    139                 "li      $27,    0xF         \n"
    140                 "mtc2    $27,    $1          \n"     /* DTLB activated       */
     128                "li      $3,     0xF         \n"
     129                "mtc2    $3,     $1          \n"     /* DTLB activated       */
    141130
    142                 "mtc0    $26,    $12         \n"     /* restore SR           */
     131                "mtc0    $4,     $12         \n"     /* restore SR           */
    143132                : "=r" (flags_value), "=r" (ppn_value)
    144                 : "r" (pte2)
    145                 : "$26","$27","$8");
     133                : "r" (pte2_msb), "r" (pte2_lsb)
     134                : "$2","$3","$4");
    146135
    147136        // check PTE2 mapping
    148         if ((flags_value & PTE_V) == 0) {
    149             return 1;
    150         }
     137        if ((flags_value & PTE_V) == 0)  return 1;
    151138
    152139        // set return values
  • soft/giet_vm/xml/mapping_info.h

    r232 r238  
    5050#define OUT_MAPPING_SIGNATURE   0xBABEF00D
    5151
    52 enum vobjType {
    53     VOBJ_TYPE_ELF      = 0, // loadable code/data object of elf files
    54     VOBJ_TYPE_BLOB     = 1, // loadable blob object
    55     VOBJ_TYPE_PTAB     = 2, // page table
    56     VOBJ_TYPE_PERI     = 3, // hardware component
    57     VOBJ_TYPE_MWMR     = 4, // MWMR channel
    58     VOBJ_TYPE_LOCK     = 5, // Lock
    59     VOBJ_TYPE_BUFFER   = 6, // Any "no initialization needed" objects (stacks...)
    60     VOBJ_TYPE_BARRIER  = 7, // Barrier
    61     VOBJ_TYPE_CONST    = 8, // Constant
    62     VOBJ_TYPE_MEMSPACE = 9, // Memspace; different from buffer because we add infos at the beginning
    63 };
    64 
    65 
    66 enum psegType {
     52typedef unsigned long long  paddr_t;
     53
     54enum vobjType
     55{
     56    VOBJ_TYPE_ELF      = 0,  // loadable code/data object of elf files
     57    VOBJ_TYPE_BLOB     = 1,  // loadable blob object
     58    VOBJ_TYPE_PTAB     = 2,  // page table
     59    VOBJ_TYPE_PERI     = 3,  // hardware component
     60    VOBJ_TYPE_MWMR     = 4,  // MWMR channel
     61    VOBJ_TYPE_LOCK     = 5,  // Lock
     62    VOBJ_TYPE_BUFFER   = 6,  // Any "no initialization" objects (stacks...)
     63    VOBJ_TYPE_BARRIER  = 7,  // Barrier
     64    VOBJ_TYPE_CONST    = 8,  // Constant
     65    VOBJ_TYPE_MEMSPACE = 9,  // Memspace (descriptor must be initialised)
     66    VOBJ_TYPE_SCHED    = 10, // Array of schedulers (one per cluster)
     67};
     68
     69
     70enum psegType
     71{
    6772    PSEG_TYPE_RAM  = 0,
    6873    PSEG_TYPE_ROM  = 1,
     
    7176
    7277
    73 enum periphType {
    74     PERIPH_TYPE_ICU  = 0,
    75     PERIPH_TYPE_TIM  = 1,
    76     PERIPH_TYPE_XICU = 2,
    77     PERIPH_TYPE_DMA  = 3,
    78     PERIPH_TYPE_IOC  = 4,
    79     PERIPH_TYPE_TTY  = 5,
    80     PERIPH_TYPE_FBF  = 6,
    81     PERIPH_TYPE_NIC  = 7,
    82     PERIPH_TYPE_IOB  = 8,
    83 };
    84 
    85 
    86 enum mwmrPortDirection {
     78enum periphType
     79{
     80    PERIPH_TYPE_ICU       = 0,
     81    PERIPH_TYPE_TIM       = 1,
     82    PERIPH_TYPE_DMA       = 2,
     83    PERIPH_TYPE_CMA       = 3,
     84    PERIPH_TYPE_IOC       = 4,
     85    PERIPH_TYPE_TTY       = 5,
     86    PERIPH_TYPE_FBF       = 6,
     87    PERIPH_TYPE_NIC       = 7,
     88    PERIPH_TYPE_IOB       = 8,
     89    PERIPH_TYPE_GCD       = 9,
     90    PERIPH_TYPE_MAX_VALUE = 10,
     91};
     92
     93
     94enum mwmrPortDirection
     95{
    8796    PORT_TO_COPROC   = 0, // status register
    8897    PORT_FROM_COPROC = 1, // config register
     
    92101///////////////////////////////
    93102
    94 typedef struct mapping_header_s {
    95     unsigned int signature;      // must contain MAPPING_SIGNATURE
    96     unsigned int clusters;       // number of clusters
    97     unsigned int cluster_x;      // number of cluster on the abcsisse axe
    98     unsigned int cluster_y;      // number of cluster on the ordinate axe
    99     unsigned int globals;        // number of vsegs mapped in all vspaces
    100     unsigned int vspaces;        // number of virtual spaces
    101 
    102     unsigned int tty_clusterid;  // index of cluster containing TTY controler
    103     unsigned int ioc_clusterid;  // index of cluster containing IOC controler
    104     unsigned int nic_clusterid;  // index of cluster containing NIC controler
    105     unsigned int fbf_clusterid;  // index of cluster containing FBF controler
    106 
    107     unsigned int psegs;          // total number of physical segments (for all clusters)
    108     unsigned int vsegs;          // total number of virtual segments (for all vspaces)
    109     unsigned int vobjs;          // total number of virtual objects (for all vspaces)
    110     unsigned int tasks;          // total number of tasks (for all vspaces)
    111     unsigned int procs;          // total number of procs (for all clusters)
    112     unsigned int irqs;           // total number of irqs (for all processors)
    113     unsigned int coprocs;        // total number of coprocs (for all clusters)
    114     unsigned int cp_ports;       // total number of cp_ports (for all coprocs)
    115     unsigned int periphs;        // total number of peripherals (for all clusters)
    116 
    117     char name[32];    // mapping name
     103typedef struct mapping_header_s
     104{
     105    unsigned int signature;          // must contain MAPPING_SIGNATURE
     106    unsigned int clusters;           // number of clusters
     107    unsigned int cluster_x;          // number of cluster in a row
     108    unsigned int cluster_y;          // number of cluster in a column
     109    unsigned int globals;            // number of vsegs mapped in all vspaces
     110    unsigned int vspaces;            // number of virtual spaces
     111
     112    unsigned int tty_cluster;        // index of cluster containing TTY controler
     113    unsigned int tty_cluster_bis;    // index of cluster containing second TTY controler
     114    unsigned int ioc_cluster;        // index of cluster containing IOC controler
     115    unsigned int ioc_cluster_bis;    // index of cluster containing second IOC controler
     116    unsigned int nic_cluster;        // index of cluster containing NIC controler
     117    unsigned int nic_cluster_bis;    // index of cluster containing second NIC controler
     118    unsigned int fbf_cluster;        // index of cluster containing FBF controler
     119    unsigned int fbf_cluster_bis;    // index of cluster containing second FBF controler
     120    unsigned int cma_cluster;        // index of cluster containing CMA controler
     121    unsigned int cma_cluster_bis;    // index of cluster containing second CMA controler
     122    unsigned int iob_cluster;        // index of cluster containing IOB controler
     123    unsigned int iob_cluster_bis;    // index of cluster containing second IOB controler
     124
     125    unsigned int psegs;              // total number of physical segments (for all clusters)
     126    unsigned int vsegs;              // total number of virtual segments (for all vspaces)
     127    unsigned int vobjs;              // total number of virtual objects (for all vspaces)
     128    unsigned int tasks;              // total number of tasks (for all vspaces)
     129    unsigned int procs;              // total number of procs (for all clusters)
     130    unsigned int irqs;               // total number of irqs (for all processors)
     131    unsigned int coprocs;            // total number of coprocs (for all clusters)
     132    unsigned int cp_ports;           // total number of cp_ports (for all coprocs)
     133    unsigned int periphs;            // total number of peripherals (for all clusters)
     134
     135    char name[32];                   // mapping name
    118136} mapping_header_t;
    119137
    120138
    121139////////////////////////////////
    122 typedef struct mapping_cluster_s {
     140typedef struct mapping_cluster_s
     141{
    123142    unsigned int psegs;          // number of psegs in cluster
    124143    unsigned int pseg_offset;    // index of first pseg in pseg set
     
    136155
    137156/////////////////////////////
    138 typedef struct mapping_pseg_s  {
    139     char name[32];               // pseg name (unique in a cluster)
    140     unsigned int base;           // base address in physical space
    141     unsigned int length;         // size (bytes)
     157typedef struct mapping_pseg_s 
     158{
     159    char         name[32];       // pseg name (unique in a cluster)
     160    paddr_t      base;           // base address in physical space
     161    paddr_t      length;         // size (bytes)
    142162    unsigned int type;           // RAM / ROM / PERI
    143163    unsigned int cluster;        // index of cluster containing pseg
    144     unsigned int next_base;      // first free page base address
     164    paddr_t      next_base;      // first free page base address
    145165} mapping_pseg_t;
    146166
    147167
    148168///////////////////////////////
    149 typedef struct mapping_vspace_s {
    150     char name[32];               // virtual space name
     169typedef struct mapping_vspace_s
     170{
     171    char         name[32];       // virtual space name
    151172    unsigned int start_offset;   // offset of the vobj containing the start vector
    152173    unsigned int vsegs;          // number of vsegs in vspace
     
    160181
    161182/////////////////////////////
    162 typedef struct mapping_vseg_s {
    163     char name[32];               // vseg name (unique in vspace)
    164     unsigned int vbase;          // base address in virtual space (hexa)
    165     unsigned int pbase;          // base address in physical space (hexa)
     183typedef struct mapping_vseg_s
     184{
     185    char         name[32];       // vseg name (unique in vspace)
     186    unsigned int vbase;          // base address in virtual space
     187    paddr_t      pbase;          // base address in physical space
    166188    unsigned int length;         // size (bytes)
    167189    unsigned int psegid;         // physical segment global index
     
    169191    unsigned int ident;          // identity mapping if non zero
    170192    unsigned int vobjs;          // number of vobjs in vseg
    171     unsigned int vobj_offset;    // index of first vobjs in vseg
     193    unsigned int vobj_offset;    // index of first vobj in vseg
    172194} mapping_vseg_t;
    173195
    174196
    175197/////////////////////////////
    176 typedef struct mapping_task_s {
    177     char name[32];               // task name (unique in vspace)
     198typedef struct mapping_task_s
     199{
     200    char         name[32];       // task name (unique in vspace)
    178201    unsigned int clusterid;      // physical cluster index
    179202    unsigned int proclocid;      // processor local index (inside cluster)
     
    181204    unsigned int heap_vobjid;    // heap vobj index in vspace
    182205    unsigned int startid;        // index in start_vector
    183     unsigned int use_tty;        // TTY terminal required (global)
     206    unsigned int use_tty;        // TTY channel required (global)
    184207    unsigned int use_nic;        // NIC channel required (global)
    185     unsigned int use_timer;      // user timer required (local)
    186     unsigned int use_fbdma;      // DMA channel to frame buffer required (local)
     208    unsigned int use_cma;        // CMA channel required (global)
     209    unsigned int use_ioc;        // IOC channel required (global)
     210    unsigned int use_tim;        // user timer required (local)
     211    unsigned int use_dma;        // DMA channel required (local)
    187212} mapping_task_t;
    188213
    189214
    190215/////////////////////////////
    191 typedef struct mapping_vobj_s {
    192     char name[32];               // vobj name (unique in a vspace)
    193     char binpath[64];            // path for the binary code ("*.elf")
     216typedef struct mapping_vobj_s
     217{
     218    char         name[32];       // vobj name (unique in a vspace)
     219    char         binpath[64];    // path for the binary code ("*.elf")
    194220    unsigned int type;           // type of vobj
    195221    unsigned int length;         // size (bytes)
    196222    unsigned int align;          // required alignement (logarithm of 2)
    197223    unsigned int vaddr;          // virtual base addresse of the vobj
    198     unsigned int paddr;          // physical base addresse of the vobj
     224    paddr_t      paddr;          // physical base addresse of the vobj
    199225    unsigned int init;           // init value (used by barrier or mwmr channel)
    200226} mapping_vobj_t;
     
    202228
    203229/////////////////////////////
    204 typedef struct mapping_proc_s {
     230typedef struct mapping_proc_s
     231{
    205232    unsigned int irqs;           // number of IRQs allocated to processor
    206233    unsigned int irq_offset;     // index of first IRQ allocated to processor
     
    209236
    210237/////////////////////////////
    211 typedef struct mapping_irq_s {
     238typedef struct mapping_irq_s
     239{
    212240    unsigned int type;           // 0 => HW_IRQ  / 1 => SW_IRQ
    213241    unsigned int icuid;          // IRQ Index for the ICU component
    214     unsigned int isr;            // Interrupt Service Routine Index
    215     unsigned int channel;        // Channel Index (for multi-cannels peripherals)
     242    unsigned int isr;            // ISR Index (defined in irq_handler.h)
     243    unsigned int channel;        // Channel Index (for multi-channels peripherals)
    216244} mapping_irq_t;
    217245
    218246
    219247///////////////////////////////
    220 typedef struct mapping_coproc_s {
    221     char name[32];               // coprocessor name
     248typedef struct mapping_coproc_s
     249{
     250    char         name[32];       // coprocessor name
    222251    unsigned int psegid;         // global pseg index
    223252    unsigned int ports;          // number of MWMR ports used by coprocessor
     
    227256
    228257////////////////////////////////
    229 typedef struct mapping_cp_port_s {
     258typedef struct mapping_cp_port_s
     259{
    230260    unsigned int direction;      // TO_COPROC == 0 / FROM_COPROC == 1
    231261    unsigned int vspaceid;       // index of the vspace containing the MWMR channel
    232     unsigned int mwmr_vobjid;      // local index of the vobj containing the MWMR channel
     262    unsigned int mwmr_vobjid;    // local index of the vobj containing the MWMR channel
    233263} mapping_cp_port_t;
    234264
    235265
    236266///////////////////////////////
    237 typedef struct mapping_periph_s {
     267typedef struct mapping_periph_s
     268{
    238269    unsigned int type;           // IOC / TTY / TIM / DMA / FBF / NIC / IOB
    239270    unsigned int psegid;         // pseg index in cluster
  • soft/giet_vm/xml/xml_driver.c

    r232 r238  
    3131        "CONST",      // Constant
    3232        "MEMSPACE",   // Memspace
     33        "SCHED",      // Scheduler
    3334    };
    3435
     
    238239            fprintf(fpout, "            <pseg name = \"%s\" ", pseg[pseg_id].name);
    239240            fprintf(fpout, " type = \"%s\" ", pseg_type[pseg[pseg_id].type]);
    240             fprintf(fpout, " base = \"0x%x\" ", pseg[pseg_id].base);
    241             fprintf(fpout, " length = \"0x%x\" />\n",   pseg[pseg_id].length);
     241            fprintf(fpout, " base = \"0x%llx\" ", pseg[pseg_id].base);
     242            fprintf(fpout, " length = \"0x%llx\" />\n",   pseg[pseg_id].length);
    242243        }
    243244
     
    366367            fprintf(fpout, "usetty = \"%d\" ", task[task_id].use_tty);
    367368            fprintf(fpout, "usenic = \"%d\" ", task[task_id].use_nic);
    368             fprintf(fpout, "usetimer = \"%d\" ", task[task_id].use_timer);
    369             fprintf(fpout, "usefbma = \"%d\" />\n", task[task_id].use_fbdma);
     369            fprintf(fpout, "usedma = \"%d\" ", task[task_id].use_dma);
     370            fprintf(fpout, "usecma = \"%d\" ", task[task_id].use_cma);
     371            fprintf(fpout, "usetim = \"%d\" ", task[task_id].use_tim);
     372            fprintf(fpout, "useioc = \"%d\" />\n", task[task_id].use_ioc);
    370373        }
    371374        fprintf(fpout, "        </vspace>\n\n");
  • soft/giet_vm/xml/xml_parser.c

    r232 r238  
    4949///////////////////////////////////////////////////////////////////////////////////
    5050
    51 mapping_header_t * header;
    52 mapping_cluster_t * cluster[MAX_CLUSTERS];  // cluster array
    53 mapping_pseg_t * pseg[MAX_PSEGS];           // pseg array
    54 mapping_vspace_t * vspace[MAX_VSPACES];     // vspace array
    55 mapping_vseg_t * vseg[MAX_VSEGS];           // vseg array
    56 mapping_vobj_t * vobj[MAX_VOBJS];           // vobj array
    57 mapping_task_t * task[MAX_TASKS];           // task array
    58 mapping_proc_t * proc[MAX_PROCS];           // proc array
    59 mapping_irq_t * irq[MAX_IRQS];              // irq array
    60 mapping_coproc_t * coproc[MAX_COPROCS];     // coproc array
    61 mapping_cp_port_t * cp_port[MAX_CP_PORTS];  // coproc port array
    62 mapping_periph_t * periph[MAX_PERIPHS];     // peripheral array
     51mapping_header_t *   header;
     52mapping_cluster_t *  cluster[MAX_CLUSTERS];  // cluster array
     53mapping_pseg_t *     pseg[MAX_PSEGS];        // pseg array
     54mapping_vspace_t *   vspace[MAX_VSPACES];    // vspace array
     55mapping_vseg_t *     vseg[MAX_VSEGS];        // vseg array
     56mapping_vobj_t *     vobj[MAX_VOBJS];        // vobj array
     57mapping_task_t *     task[MAX_TASKS];        // task array
     58mapping_proc_t *     proc[MAX_PROCS];        // proc array
     59mapping_irq_t *      irq[MAX_IRQS];          // irq array
     60mapping_coproc_t *   coproc[MAX_COPROCS];    // coproc array
     61mapping_cp_port_t *  cp_port[MAX_CP_PORTS];  // coproc port array
     62mapping_periph_t *   periph[MAX_PERIPHS];    // peripheral array
    6363
    6464// Index for the various arrays
     
    9595
    9696
    97 /////////////////////////
    98 // found peripheral
    99 /////////////////////////
     97//////////////////////////////
     98// for replicated peripheral
     99//////////////////////////////
    100100char found_timer = 0;
    101101char found_icu = 0;
    102 char found_xicu = 0;
    103102char found_dma = 0;
    104103
    105104
    106 //////////////////////////////////
    107 //needed to generate map_config.ld
    108 //////////////////////////////////
    109 unsigned int cluster_y            = 0;
    110 unsigned int cluster_x            = 0;
    111 unsigned int nb_proc_max          = 0; // max number of processors per cluste
    112 
    113 unsigned int nb_tasks_max         = 0; // max number of tasks (for all vspaces)
    114 unsigned int nb_timer_channel_max = 0; // max number of user timer
    115 unsigned int nb_dma_channel_max   = 0;
    116 unsigned int nb_tty_channel       = 0;
    117 unsigned int nb_ioc_channel       = 0;
    118 unsigned int nb_nic_channel       = 0;
    119 unsigned int io_mmu_active        = 0;
    120 unsigned int use_xicu             = 0xFFFFFFFF;
    121 
    122 
    123 //////////////////////////////////
    124 //needed to generate giet_vseg.ld
    125 //////////////////////////////////
    126 
    127 //kernel and boot code
    128 unsigned int kernel_code_base    = 0x80000000; /* kernel code */
    129 unsigned int kernel_data_base    = 0x80010000; /* system cacheable data */
    130 unsigned int kernel_uncdata_base = 0x80080000; /* system uncacheable data */
    131 unsigned int kernel_init_base    = 0x80090000; /* system init entry */
    132 
    133 unsigned int boot_code_base      = 0xBFC00000; /* boot code */
    134 unsigned int boot_stack_base     = 0xBFC08000; /* boot temporary stack */
    135 unsigned int boot_mapping_base   = 0xBFC0C000; /* mapping_info blob */
    136 
    137 //periphs
    138 unsigned int tim_base_offset = 0xFFFFFFFF;
    139 unsigned int tty_base_offset = 0xFFFFFFFF;
    140 unsigned int dma_base_offset = 0xFFFFFFFF;
    141 unsigned int ioc_base_offset = 0xFFFFFFFF;
    142 unsigned int nic_base_offset = 0xFFFFFFFF;
    143 unsigned int fbf_base_offset = 0xFFFFFFFF;
    144 unsigned int icu_base_offset = 0xFFFFFFFF;
    145 unsigned int gcd_base_offset = 0xFFFFFFFF;
    146 unsigned int iob_base_offset = 0xFFFFFFFF;
    147 
     105////////////////////////////////////////////////////////////////////
     106// These variables are used to generate the hard_config.h file
     107////////////////////////////////////////////////////////////////////
     108
     109unsigned int cluster_y        = 0; // number of clusters in a column
     110unsigned int cluster_x        = 0; // number of clusters in a row
     111unsigned int nb_proc_max      = 0; // max number of processors per cluster
     112unsigned int nb_tasks_max     = 0; // max number of tasks (for all vspaces)
     113
     114unsigned int tim_channels     = 0; // max number of user timers per cluster
     115unsigned int dma_channels     = 0; // max number of DMA channels per cluster
     116
     117unsigned int tty_channels     = 0; // total number of terminals in first TTY
     118unsigned int ioc_channels     = 0; // total number of channels in first IOC
     119unsigned int nic_channels     = 0; // total number of channels in first NIC
     120unsigned int cma_channels     = 0; // total number of channels in first CMA
     121
     122unsigned int io_mmu_active    = 0; // using IOB component
     123unsigned int use_xicu         = 0; // using XICU (not ICU)
     124
     125
     126////////////////////////////////////////////////////////////////
     127// These variables are used to generate the giet_vseg.ld file
     128////////////////////////////////////////////////////////////////
     129
     130unsigned int periph_vbase_array[PERIPH_TYPE_MAX_VALUE]
     131         = { [0 ... (PERIPH_TYPE_MAX_VALUE - 1)] = 0xFFFFFFFF };
    148132
    149133//////////////////////////////////////////////////////////////////////
     
    153137// once all the vspace have been parsed.
    154138/////////////////////////////////////////////////////////////////////
    155 typedef struct vobj_ref_s {
     139typedef struct vobj_ref_s
     140{
    156141    char vspace_name[32];
    157142    char vobj_name[32];
     
    162147
    163148//////////////////////////////////////////////////
    164 unsigned int getIntValue(xmlTextReaderPtr reader, const char * attributeName, unsigned int * ok) {
     149unsigned int getIntValue( xmlTextReaderPtr reader,
     150                          const char * attributeName,
     151                          unsigned int * ok)
     152{
    165153    unsigned int value = 0;
    166154    unsigned int i;
    167155    char c;
    168156
    169     char * string = (char *) xmlTextReaderGetAttribute(reader, (const xmlChar *) attributeName);
    170 
    171     if (string == NULL) {
     157    char * string = (char *) xmlTextReaderGetAttribute(reader,
     158                                (const xmlChar *) attributeName);
     159
     160    if (string == NULL)
     161    {
    172162        // missing argument
    173163        *ok = 0;
    174164        return 0;
    175165    }
    176     else {
    177         if ((string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X'))) {
     166    else
     167    {
     168        if ((string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X')))
     169        {
    178170            // Hexa
    179             for (i = 2 ; (string[i] != 0) && (i < 10) ; i++) {
     171            for (i = 2 ; (string[i] != 0) && (i < 10) ; i++)
     172            {
    180173                c = string[i];
    181174                if      ((c >= '0') && (c <= '9')) { value = (value << 4) + string[i] - 48; }
    182175                else if ((c >= 'a') && (c <= 'f')) { value = (value << 4) + string[i] - 87; }
    183176                else if ((c >= 'A') && (c <= 'F')) { value = (value << 4) + string[i] - 55; }
    184                 else {
     177                else
     178                {
    185179                    *ok = 0;
    186180                    return 0;
     
    188182            }
    189183        }
    190         else {
     184        else
     185        {
    191186            // Decimal
    192             for (i = 0; (string[i] != 0) && (i < 9); i++) {
     187            for (i = 0; (string[i] != 0) && (i < 9); i++)
     188            {
    193189                c = string[i];
    194190                if ((c >= '0') && (c <= '9')) value = (value * 10) + string[i] - 48;
    195                 else {
     191                else
     192                {
    196193                    *ok = 0;
    197194                    return 0;
     
    204201} // end getIntValue()
    205202
    206 
    207 ///////////////////////////////////////////////
    208 char * getStringValue(xmlTextReaderPtr reader, const char * attributeName, unsigned int * ok) {
    209     char * string = (char *) xmlTextReaderGetAttribute(reader, (const xmlChar *) attributeName);
    210 
    211 
    212     if (string == NULL) {
     203////////////////////////////////////////////////
     204paddr_t getPaddrValue( xmlTextReaderPtr reader,
     205                       const char * attributeName,
     206                       unsigned int * ok)
     207{
     208    paddr_t value = 0;
     209    unsigned int i;
     210    char c;
     211
     212    char * string = (char *) xmlTextReaderGetAttribute(reader,
     213                                (const xmlChar *) attributeName);
     214
     215    if (string == NULL)
     216    {
     217        // missing argument
     218        *ok = 0;
     219        return 0;
     220    }
     221    else
     222    {
     223        if ((string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X')))
     224        {
     225            // Hexa
     226            for (i = 2 ; (string[i] != 0) && (i < 18) ; i++)
     227            {
     228                c = string[i];
     229                if      ((c >= '0') && (c <= '9')) { value = (value << 4) + string[i] - 48; }
     230                else if ((c >= 'a') && (c <= 'f')) { value = (value << 4) + string[i] - 87; }
     231                else if ((c >= 'A') && (c <= 'F')) { value = (value << 4) + string[i] - 55; }
     232                else
     233                {
     234                    *ok = 0;
     235                    return 0;
     236                }
     237            }
     238        }
     239        else
     240        {
     241            // Decimal not supported for paddr_t
     242            *ok = 0;
     243            return 0;
     244        }
     245        *ok = 1;
     246        return value;
     247    }
     248} // end getPaddrValue()
     249
     250////////////////////////////////////////////////
     251char * getStringValue( xmlTextReaderPtr reader,
     252                       const char * attributeName,
     253                       unsigned int * ok )
     254{
     255    char * string = (char *) xmlTextReaderGetAttribute(reader,
     256                               (const xmlChar *) attributeName);
     257
     258
     259    if (string == NULL)
     260    {
    213261        // missing argument
    214262        *ok = 0;
    215263        return NULL;
    216264    }
    217     else {
     265    else
     266    {
    218267        //we read only string smaller than 32 byte
    219         if (strlen(string) > 32) {
     268        if (strlen(string) > 32)
     269        {
    220270            printf("[XML ERROR] all strings must be less than 32 bytes\n");
    221271            exit(1);
     
    227277} // end getStringValue()
    228278
    229 
    230 ///////////////////////////////////////
    231 int getPsegId(unsigned int cluster_id, char * pseg_name) {
     279///////////////////////////////////////////////////////
     280void set_periph_vbase_array( unsigned int vseg_index )
     281{
     282    unsigned int vbase  = vseg[vseg_index]->vbase;  // peripheral vbase address
     283    unsigned int psegid = vseg[vseg_index]->psegid; // pseg global index
     284    unsigned int type;                              // peripheral type
     285    unsigned int periph_id;
     286
     287    for ( periph_id = 0 ; periph_id < header->periphs ; periph_id++)
     288    {
     289        if( periph[periph_id]->psegid == psegid )
     290        {
     291            type = periph[periph_id]->type;
     292            if ( periph_vbase_array[type] == 0xFFFFFFFF )
     293                 periph_vbase_array[type] = vbase;   
     294        }
     295    }
     296}  // end set_periph_vbase_array()
     297
     298////////////////////////////////////////////////////////
     299int getPsegId(unsigned int cluster_id, char * pseg_name)
     300{
    232301    unsigned int pseg_id;
    233302    unsigned int pseg_min = cluster[cluster_id]->pseg_offset;
    234303    unsigned int pseg_max = pseg_min + cluster[cluster_id]->psegs;
    235304
    236     for (pseg_id = pseg_min; pseg_id < pseg_max; pseg_id++) {
    237         if (strcmp(pseg[pseg_id]->name, pseg_name) == 0) {
     305    for (pseg_id = pseg_min; pseg_id < pseg_max; pseg_id++)
     306    {
     307        if (strcmp(pseg[pseg_id]->name, pseg_name) == 0)
     308        {
    238309            return pseg_id;
    239310        }
     
    242313}
    243314
    244 
    245 ////////////////////////////////////////////
    246 int getVspaceId(char * vspace_name) {
     315///////////////////////////////////
     316int getVspaceId(char * vspace_name)
     317{
    247318    unsigned int vspace_id;
    248319
    249     for (vspace_id = 0; vspace_id < vspace_index; vspace_id++) {
    250         if (!strcmp(vspace[vspace_id]->name, vspace_name)) {
     320    for (vspace_id = 0; vspace_id < vspace_index; vspace_id++)
     321    {
     322        if (strcmp(vspace[vspace_id]->name, vspace_name) == 0)
     323        {
    251324            return vspace_id;
    252325        }
     
    255328}
    256329
    257 
    258 ////////////////////////////////////////////
    259 int getVobjLocId(unsigned int vspace_id, char * vobj_name, unsigned int vspace_max) {
     330///////////////////////////////////////////////////////////////////////////////////
     331int getVobjLocId(unsigned int vspace_id, char * vobj_name, unsigned int vspace_max)
     332{
    260333    unsigned int vobj_id;
    261334    unsigned int vobj_min = vspace[vspace_id]->vobj_offset;
     
    272345
    273346/////////////////////////////////////////
    274 void taskNode(xmlTextReaderPtr reader) {
     347void taskNode(xmlTextReaderPtr reader)
     348{
    275349    unsigned int ok;
    276350    unsigned int value;
    277351    char * str;
    278352
    279     if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) {
    280         return;
    281     }
    282 
    283     if (task_index >= MAX_TASKS) {
     353    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { return; }
     354
     355    if (task_index >= MAX_TASKS)
     356    {
    284357        printf("[XML ERROR] The number of tasks is larger than %d\n", MAX_TASKS);
    285358    }
    286359
    287360#if XML_PARSER_DEBUG
    288     printf("   task %d\n", task_loc_index);
     361printf("   task %d\n", task_loc_index);
    289362#endif
    290363
     
    293366    ////////// get name attribute
    294367    str = getStringValue(reader, "name", &ok);
    295     if (ok) {
    296 #if XML_PARSER_DEBUG
    297         printf("      name = %s\n", str);
     368    if (ok)
     369    {
     370#if XML_PARSER_DEBUG
     371printf("      name = %s\n", str);
    298372#endif
    299373        strncpy( task[task_index]->name, str, 31 );
    300374    }
    301     else {
     375    else
     376    {
    302377        printf("[XML ERROR] illegal or missing <name> attribute for task (%d,%d)\n",
    303378                vspace_index, task_loc_index);
     
    307382    ///////// get clusterid attribute
    308383    value = getIntValue(reader, "clusterid", &ok);
    309     if (ok) {
    310 #if XML_PARSER_DEBUG
    311         printf("      clusterid = %x\n", value);
    312 #endif
    313         if (value >= header->clusters) {
     384    if (ok)
     385    {
     386#if XML_PARSER_DEBUG
     387printf("      clusterid = %x\n", value);
     388#endif
     389        if (value >= header->clusters)
     390        {
    314391            printf("[XML ERROR] <clusterid> too large for task (%d,%d)\n",
    315392                    vspace_index, task_loc_index);
     
    318395        task[task_index]->clusterid = value;
    319396    } 
    320     else {
     397    else
     398    {
    321399        printf("[XML ERROR] illegal or missing <clusterid> attribute for task (%d,%d)\n",
    322400                vspace_index, task_loc_index);
     
    326404    ////////// get proclocid attribute
    327405    value = getIntValue(reader, "proclocid", &ok);
    328     if (ok) {
    329 #if XML_PARSER_DEBUG
    330         printf("      proclocid = %x\n", value);
    331 #endif
    332         if (value >= cluster[task[task_index]->clusterid]->procs) {
     406    if (ok)
     407    {
     408#if XML_PARSER_DEBUG
     409printf("      proclocid = %x\n", value);
     410#endif
     411        if (value >= cluster[task[task_index]->clusterid]->procs)
     412        {
    333413            printf("[XML ERROR] <proclocid> too large for task (%d,%d)\n",
    334414                    vspace_index, task_loc_index);
     
    337417        task[task_index]->proclocid = value;
    338418    } 
    339     else {
     419    else
     420    {
    340421        printf("[XML ERROR] illegal or missing <locprocid> attribute for task (%d,%d)\n",
    341422                vspace_index, task_loc_index);
     
    345426    ////////// get stackname attribute
    346427    str = getStringValue(reader, "stackname" , &ok);
    347     if (ok) {
     428    if (ok)
     429    {
    348430        int index = getVobjLocId(vspace_index, str , vobj_loc_index);
    349         if (index >= 0) {
    350 #if XML_PARSER_DEBUG
    351             printf("      stackname = %s\n", str);
    352             printf("      stackid   = %d\n", index);
     431        if (index >= 0)
     432        {
     433#if XML_PARSER_DEBUG
     434printf("      stackname = %s\n", str);
     435printf("      stackid   = %d\n", index);
    353436#endif
    354437            task[task_index]->stack_vobjid = index;
    355438        }
    356         else {
     439        else
     440        {
    357441            printf("[XML ERROR] illegal or missing <stackname> for task (%d,%d)\n",
    358442                    vspace_index, task_loc_index);
     
    360444        }
    361445    } 
    362     else {
     446    else
     447    {
    363448        printf("[XML ERROR] illegal or missing <stackname> for task (%d,%d)\n",
    364449                vspace_index, task_loc_index);
     
    368453    ////////// get heap attribute
    369454    str = getStringValue(reader, "heapname", &ok);
    370     if (ok) {
     455    if (ok)
     456    {
    371457        int index = getVobjLocId(vspace_index, str, vobj_loc_index);
    372         if (index >= 0) {
    373 #if XML_PARSER_DEBUG
    374             printf("      heapname = %s\n", str);
    375             printf("      heapid   = %d\n", index);
     458        if (index >= 0)
     459        {
     460#if XML_PARSER_DEBUG
     461printf("      heapname = %s\n", str);
     462printf("      heapid   = %d\n", index);
    376463#endif
    377464            task[task_index]->heap_vobjid = index;
    378465        }
    379         else {
    380             printf("[XML ERROR] illegal or missing <heapname> for task (%d,%d)\n", vspace_index, task_loc_index);
     466        else
     467        {
     468            printf("[XML ERROR] illegal or missing <heapname> for task (%d,%d)\n",
     469                   vspace_index, task_loc_index);
    381470            exit(1);
    382471        }
    383472    } 
    384     else {
     473    else
     474    {
    385475        task[task_index]->heap_vobjid = -1;
    386476    }
     
    389479    ////////// get startid  attribute
    390480    value = getIntValue(reader, "startid", &ok);
    391     if (ok) {
    392 #if XML_PARSER_DEBUG
    393         printf("      startid = %x\n", value);
     481    if (ok)
     482    {
     483#if XML_PARSER_DEBUG
     484printf("      startid = %x\n", value);
    394485#endif
    395486        task[task_index]->startid = value;
    396487    } 
    397     else {
     488    else
     489    {
    398490        printf("[XML ERROR] illegal or missing <startid> attribute for task (%d,%d)\n",
    399491                vspace_index, task_loc_index);
     
    403495    /////////// get usetty  attribute (optionnal : 0 if missing)
    404496    value = getIntValue(reader, "usetty", &ok);
    405     if (ok) {
    406 #if XML_PARSER_DEBUG
    407         printf("      usetty = %x\n", value);
    408 #endif
    409         task[task_index]->use_tty = value;
    410     } 
    411     else {
    412         task[task_index]->use_tty = 0;
    413     }
     497#if XML_PARSER_DEBUG
     498printf("      usetty = %x\n", value);
     499#endif
     500    task[task_index]->use_tty = (ok)? value : 0;
    414501
    415502    /////////// get usenic  attribute (optionnal : 0 if missing)
    416503    value = getIntValue(reader, "usenic", &ok);
    417     if (ok) {
    418 #if XML_PARSER_DEBUG
    419         printf("      usenic = %x\n", value);
    420 #endif
    421         task[task_index]->use_nic = value;
    422     } 
    423     else {
    424         task[task_index]->use_nic = 0;
    425     }
    426 
    427     /////////// get usetimer attribute (optionnal : 0 if missing)
    428     value = getIntValue(reader, "usetimer", &ok);
    429     if (ok) {
    430 #if XML_PARSER_DEBUG
    431         printf("      usetimer = %x\n", value);
    432 #endif
    433         task[task_index]->use_timer = value;
    434     } 
    435     else {
    436         task[task_index]->use_timer = 0;
    437     }
    438 
    439     /////////// get usefbdma  attribute (optionnal : 0 if missing)
    440     value = getIntValue(reader, "usefbdma", &ok);
    441     if (ok) {
    442 #if XML_PARSER_DEBUG
    443         printf("      usefbdma = %x\n", value);
    444 #endif
    445         task[task_index]->use_fbdma = value;
    446     }
    447     else {
    448         task[task_index]->use_fbdma = 0;
    449     }
     504#if XML_PARSER_DEBUG
     505printf("      usenic = %x\n", value);
     506#endif
     507    task[task_index]->use_nic = (ok)? value : 0;
     508
     509    /////////// get usetim attribute (optionnal : 0 if missing)
     510    value = getIntValue(reader, "usetim", &ok);
     511#if XML_PARSER_DEBUG
     512printf("      usetim = %x\n", value);
     513#endif
     514    task[task_index]->use_tim = (ok)? value : 0;
     515
     516    /////////// get usedma  attribute (optionnal : 0 if missing)
     517    value = getIntValue(reader, "usedma", &ok);
     518#if XML_PARSER_DEBUG
     519printf("      usedma = %x\n", value);
     520#endif
     521    task[task_index]->use_dma = (ok)? value : 0;
     522
     523    /////////// get useioc  attribute (optionnal : 0 if missing)
     524    value = getIntValue(reader, "useioc", &ok);
     525#if XML_PARSER_DEBUG
     526printf("      useioc = %x\n", value);
     527#endif
     528    task[task_index]->use_ioc = (ok)? value : 0;
     529
     530    /////////// get usecma  attribute (optionnal : 0 if missing)
     531    value = getIntValue(reader, "usecma", &ok);
     532#if XML_PARSER_DEBUG
     533printf("      usecma = %x\n", value);
     534#endif
     535    task[task_index]->use_cma = (ok)? value : 0;
    450536
    451537    task_index++;
     
    454540
    455541
    456 //////////////////////////////////////////
    457 void vobjNode(xmlTextReaderPtr reader) {
     542//////////////////////////////////////
     543void vobjNode(xmlTextReaderPtr reader)
     544{
    458545    unsigned int ok;
    459546    unsigned int value;
    460547    char * str;
    461548
    462     if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) {
    463         return;
    464     }
    465 
    466     if (vobj_index >= MAX_VOBJS) {
    467         printf("[XML ERROR] The number of vobjs is larger than %d\n", MAX_VSEGS);
    468         exit(1);
    469     }
    470 
    471 #if XML_PARSER_DEBUG
    472     printf("      vobj %d\n", vobj_loc_index);
     549    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { return; }
     550
     551    if (vobj_index >= MAX_VOBJS)
     552    {
     553        printf("[XML ERROR] The number of vobjs is larger than %d\n", MAX_VOBJS);
     554        exit(1);
     555    }
     556
     557#if XML_PARSER_DEBUG
     558printf("      vobj %d\n", vobj_loc_index);
    473559#endif
    474560
     
    477563    ///////// get name attribute
    478564    str = getStringValue(reader, "name", &ok);
    479     if (ok) {
    480 #if XML_PARSER_DEBUG
    481         printf("        name = %s\n", str);
     565    if (ok)
     566    {
     567#if XML_PARSER_DEBUG
     568printf("        name = %s\n", str);
    482569#endif
    483570        strncpy(vobj[vobj_index]->name, str, 31);
    484571    }
    485     else {
     572    else
     573    {
    486574        printf("[XML ERROR] illegal or missing <name> attribute for vobj (%d,%d)\n",
    487575                vseg_index, vobj_loc_index);
     
    492580    str = getStringValue(reader, "type", &ok);
    493581#if XML_PARSER_DEBUG
    494     printf("        type = %s\n", str);
    495 #endif
    496     if (ok && (strcmp(str, "ELF") == 0)) {
     582printf("        type = %s\n", str);
     583#endif
     584    if (ok && (strcmp(str, "ELF") == 0))
     585    {
    497586        vobj[vobj_index]->type = VOBJ_TYPE_ELF;
    498587
    499         //check that this vobj is the first in vseg
    500         if (vobj_count != 0) {
    501             printf("[XML ERROR] an ELF vobj must be alone in a vseg (%d,%d)\n",
    502                     vspace_index, vobj_loc_index);
    503             exit(1);
    504         }
    505     }
    506     else if (ok && (strcmp(str, "BLOB")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BLOB; }
    507     else if (ok && (strcmp(str, "PTAB")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_PTAB; }
    508     else if (ok && (strcmp(str, "PERI")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_PERI; }
    509     else if (ok && (strcmp(str, "MWMR")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_MWMR; }
    510     else if (ok && (strcmp(str, "LOCK")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_LOCK; }
    511     else if (ok && (strcmp(str, "BUFFER")   == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BUFFER; }
    512     else if (ok && (strcmp(str, "BARRIER")  == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BARRIER; }
    513     else if (ok && (strcmp(str, "CONST")    == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_CONST; }
     588        assert( (vobj_count == 0) && "[XML ERROR] an ELF vobj must be alone in a vseg");
     589    }
     590    else if (ok && (strcmp(str, "PERI")     == 0))
     591    {
     592        vobj[vobj_index]->type = VOBJ_TYPE_PERI;     
     593
     594        assert( (vobj_count == 0) && "[XML ERROR] a PERI vobj must be alone in a vseg");
     595
     596        // fill the peripheral base address array
     597        set_periph_vbase_array( vseg_index );
     598    }
     599    else if (ok && (strcmp(str, "BLOB")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BLOB;     }
     600    else if (ok && (strcmp(str, "PTAB")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_PTAB;     }
     601    else if (ok && (strcmp(str, "MWMR")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_MWMR;     }
     602    else if (ok && (strcmp(str, "LOCK")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_LOCK;     }
     603    else if (ok && (strcmp(str, "BUFFER")   == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BUFFER;   }
     604    else if (ok && (strcmp(str, "BARRIER")  == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BARRIER;  }
     605    else if (ok && (strcmp(str, "CONST")    == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_CONST;    }
    514606    else if (ok && (strcmp(str, "MEMSPACE") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_MEMSPACE; }
    515     else {
     607    else if (ok && (strcmp(str, "SCHED")    == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_SCHED;    }
     608    else
     609    {
    516610        printf("[XML ERROR] illegal or missing <type> attribute for vobj (%d,%d)\n",
    517611                vspace_index, vobj_loc_index);
     
    523617    if (ok) {
    524618#if XML_PARSER_DEBUG
    525         printf("        length = %d\n", value);
     619printf("        length = %d\n", value);
    526620#endif
    527621        vobj[vobj_index]->length = value;
     
    537631    if (ok) {
    538632#if XML_PARSER_DEBUG
    539         printf("        align = %d\n", value);
     633printf("        align = %d\n", value);
    540634#endif
    541635        vobj[vobj_index]->align = value;
     
    549643    if (ok) {
    550644#if XML_PARSER_DEBUG
    551         printf("        binpath = %s\n", str);
     645printf("        binpath = %s\n", str);
    552646#endif
    553647        strncpy(vobj[vobj_index]->binpath, str, 63);
     
    559653    ////////// get init attribute (mandatory for mwmr and barrier)
    560654    value = getIntValue(reader, "init", &ok);
    561     if (ok) {
    562 #if XML_PARSER_DEBUG
    563         printf("        init  = %d\n", value);
     655    if (ok)
     656    {
     657#if XML_PARSER_DEBUG
     658printf("        init  = %d\n", value);
    564659#endif
    565660        vobj[vobj_index]->init = value;
    566661    } 
    567     else {
     662    else
     663    {
    568664        if ((vobj[vobj_index]->type == VOBJ_TYPE_MWMR) ||
    569                 (vobj[vobj_index]->type == VOBJ_TYPE_BARRIER) ||
    570                 (vobj[vobj_index]->type == VOBJ_TYPE_CONST)) {
     665            (vobj[vobj_index]->type == VOBJ_TYPE_BARRIER) ||
     666            (vobj[vobj_index]->type == VOBJ_TYPE_CONST))
     667        {
    571668            printf("[XML ERROR] illegal or missing <value> attribute for vobj (%d,%d). \
    572                     All MWMR or BARRIER vobj must have a init value \n",
     669                    All MWMR or BARRIER or CONST vobj must have a init value \n",
    573670                    vspace_index, vobj_loc_index);
    574671            exit(1);
     
    583680
    584681
    585 //////////////////////////////////////////
    586 void vsegNode(xmlTextReaderPtr reader) {
     682//////////////////////////////////////
     683void vsegNode(xmlTextReaderPtr reader)
     684{
    587685    unsigned int ok;
    588686    unsigned int value;
     
    591689    vobj_count = 0;
    592690
    593     if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) {
    594         return;
    595     }
    596 
    597     if (vseg_index >= MAX_VSEGS) {
     691    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { return; }
     692
     693    if (vseg_index >= MAX_VSEGS)
     694    {
    598695        printf("[XML ERROR] The number of vsegs is larger than %d\n", MAX_VSEGS);
    599696        exit(1);
     
    601698
    602699#if XML_PARSER_DEBUG
    603     printf("    vseg %d\n", vseg_loc_index);
     700printf("    vseg %d\n", vseg_loc_index);
    604701#endif
    605702
     
    608705    ////////// set vobj_offset attributes
    609706    vseg[vseg_index]->vobj_offset = vobj_index;
    610 #if XML_PARSER_DEBUG
    611     printf("      vobj_offset = %d\n", vobj_index);
     707
     708#if XML_PARSER_DEBUG
     709printf("      vobj_offset = %d\n", vobj_index);
    612710#endif
    613711
    614712    ///////// get name attribute
    615713    str = getStringValue(reader, "name", &ok);
    616     if (ok) {
    617 #if XML_PARSER_DEBUG
    618         printf("      name = %s\n", str);
     714    if (ok)
     715    {
     716#if XML_PARSER_DEBUG
     717printf("      name = %s\n", str);
    619718#endif
    620719        strncpy( vseg[vseg_index]->name, str, 31);
    621720    }
    622     else {
     721    else
     722    {
    623723        printf("[XML ERROR] illegal or missing <name> attribute for vseg (%d,%d)\n",
    624724                vspace_index, vseg_loc_index);
     
    628728    ////////// get ident attribute (optional : 0 if missing)
    629729    value = getIntValue(reader, "ident", &ok);
    630     if (ok) {
    631 #if XML_PARSER_DEBUG
    632         printf("      ident = %d\n", value);
     730    if (ok)
     731    {
     732#if XML_PARSER_DEBUG
     733printf("      ident = %d\n", value);
    633734#endif
    634735        vseg[vseg_index]->ident = value;
    635736    } 
    636     else {
     737    else
     738    {
    637739        vseg[vseg_index]->ident = 0;
    638740    }
     
    640742    /////////// get vbase attribute
    641743    value = getIntValue(reader, "vbase", &ok);
    642     if (ok) {
    643 #if XML_PARSER_DEBUG
    644         printf("      vbase = 0x%x\n", value);
     744    if (ok)
     745    {
     746#if XML_PARSER_DEBUG
     747printf("      vbase = 0x%x\n", value);
    645748#endif
    646749        vseg[vseg_index]->vbase = value;
    647750    }
    648     else {
     751    else
     752    {
    649753        printf("[XML ERROR] illegal or missing <vbase> attribute for vseg (%d,%d)\n",
    650754                vspace_index, vseg_loc_index);
     
    654758    ////////// get clusterid and psegname attributes
    655759    value = getIntValue(reader, "clusterid", &ok);
    656     if (ok == 0) {
     760    if (ok == 0)
     761    {
    657762        printf("[XML ERROR] illegal or missing <clusterid> for vseg %d\n",
    658763                vseg_loc_index);
     
    660765    }
    661766    str = getStringValue(reader, "psegname", &ok);
    662     if (ok == 0) {
     767    if (ok == 0)
     768    {
    663769        printf("[XML ERROR] illegal or missing <psegname> for vseg %d\n",
    664770                vseg_loc_index);
     
    668774    /////////// set psegid field
    669775    int index = getPsegId(value, str);
    670     if (index >= 0) {
    671 #if XML_PARSER_DEBUG
    672         printf("      clusterid = %d\n", value);
    673         printf("      psegname  = %s\n", str);
    674         printf("      psegid    = %d\n", index);
     776    if (index >= 0)
     777    {
     778#if XML_PARSER_DEBUG
     779printf("      clusterid = %d\n", value);
     780printf("      psegname  = %s\n", str);
     781printf("      psegid    = %d\n", index);
    675782#endif
    676783        vseg[vseg_index]->psegid = index;
    677784    }
    678     else {
     785    else
     786    {
    679787        printf("[XML ERROR] pseg not found for vseg %d / clusterid = %d / psegname = %s\n",
    680788                vseg_loc_index, value, str );
     
    685793    str = getStringValue(reader, "mode", &ok);
    686794#if XML_PARSER_DEBUG
    687     printf("      mode = %s\n", str);
     795printf("      mode = %s\n", str);
    688796#endif
    689797    if      (ok && (strcmp(str, "CXWU") == 0)) { vseg[vseg_index]->mode = 0xF; }
     
    714822        const char * tag = (const char *) xmlTextReaderConstName(reader);
    715823
    716         if (strcmp(tag, "vobj")     == 0 ) {
    717             vobjNode(reader);
    718         }
     824        if      (strcmp(tag, "vobj")     == 0 ) { vobjNode(reader); }
    719825        else if (strcmp(tag, "#text"  )  == 0 ) { }
    720826        else if (strcmp(tag, "#comment") == 0 ) { }
    721         else if (strcmp(tag, "vseg")     == 0 ) {
     827        else if (strcmp(tag, "vseg")     == 0 )
     828        {
    722829            vseg[vseg_index]->vobjs = vobj_count;
    723830            vseg_index++;
     
    756863
    757864#if XML_PARSER_DEBUG
    758     printf("\n  vspace %d\n", vspace_index);
     865printf("\n  vspace %d\n", vspace_index);
    759866#endif
    760867
     
    765872    if (ok) {
    766873#if XML_PARSER_DEBUG
    767         printf("  name = %s\n", str);
     874printf("  name = %s\n", str);
    768875#endif
    769876        strncpy(vspace[vspace_index]->name, str, 31);
     
    9361043
    9371044
    938 ///////////////////////////////////////////
    939 void periphNode(xmlTextReaderPtr reader) {
     1045////////////////////////////////////////
     1046void periphNode(xmlTextReaderPtr reader)
     1047{
    9401048    char * str;
    9411049    unsigned int value;
    9421050    unsigned int ok;
    9431051
    944     if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) {
    945         return;
    946     }
    947 
    948     if (periph_index >= MAX_PERIPHS) {
     1052    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { return; }
     1053
     1054    if (periph_index >= MAX_PERIPHS)
     1055    {
    9491056        printf("[XML ERROR] The number of periphs is larger than %d\n", MAX_PERIPHS);
    9501057    }
     
    9551062
    9561063    periph[periph_index] = (mapping_periph_t *) malloc(sizeof(mapping_periph_t));
    957 
    9581064
    9591065    ///////// get channels attribute (optionnal : 1 if missing)
    9601066    value = getIntValue(reader, "channels", &ok);
    961     if (ok) {
     1067    if (ok)
     1068    {
    9621069#if XML_PARSER_DEBUG
    9631070        printf("      channels = %d\n", value);
     
    9651072        periph[periph_index]->channels = value;
    9661073    }
    967     else {
     1074    else
     1075    {
    9681076        periph[periph_index]->channels = 1;
    9691077    }
     
    9711079    /////////// get psegname attribute
    9721080    str = getStringValue(reader, "psegname", &ok);
    973     if (ok == 0) {
     1081    if (ok == 0)
     1082    {
    9741083        printf("[XML ERROR] illegal or missing <psegname> for coproc %d in cluster %d\n",
    9751084                coproc_index, cluster_index);
     
    9791088    /////////// set psegid attribute
    9801089    int index = getPsegId(cluster_index, str);
    981     if (index >= 0) {
     1090    if (index >= 0)
     1091    {
    9821092#if XML_PARSER_DEBUG
    9831093        printf("      clusterid = %d\n", cluster_index);
     
    9891099                "peripheral psegname attribute must refer to a pseg of type PERI" );
    9901100    }
    991     else {
     1101    else
     1102    {
    9921103        printf("[XML ERROR] pseg not found for periph %d / clusterid = %d / psegname = %s\n",
    9931104                periph_loc_index, cluster_index, str );
     
    9951106    } 
    9961107
    997 
    9981108    /////////// get type attribute
    9991109    str = getStringValue(reader, "type", &ok);
    1000     if (ok) {
     1110    if (ok)
     1111    {
    10011112#if XML_PARSER_DEBUG
    10021113        printf("      type     = %s\n", str);
     
    10041115        unsigned int error = 0;
    10051116
    1006         // The TTY, IOC, NIC, FBF and IOB peripherals cannot be replicated
    1007         // one per architecture
    1008         if (strcmp(str, "IOC") == 0) {
     1117        // The TTY, IOC, NIC, FBF, CMA and IOB peripherals are not replicated in all clusters
     1118        // but can be replicated in two different clusters for fault tolerance
     1119        // In case of replication, the number of channels must be the same
     1120        if (strcmp(str, "IOC") == 0)
     1121        {
    10091122            periph[periph_index]->type = PERIPH_TYPE_IOC;
    1010             if (header->ioc_clusterid == 0xFFFFFFFF) {
    1011                 header->ioc_clusterid = cluster_index;
    1012             }
    1013             else {
     1123            if (header->ioc_cluster == 0xFFFFFFFF)
     1124            {
     1125                header->ioc_cluster  = cluster_index;
     1126                ioc_channels = periph[periph_index]->channels;
     1127            }
     1128            else if (header->ioc_cluster_bis == 0xFFFFFFFF)
     1129            {
     1130                header->ioc_cluster_bis = cluster_index;
     1131            }
     1132            else
     1133            {
    10141134                error = 1;
    10151135            }
    1016 
    1017             ioc_base_offset = pseg[periph[periph_index]->psegid]->base;
    1018             nb_ioc_channel = periph[periph_index]->channels;
    10191136        }
    1020         else if (strcmp(str, "TTY") == 0) {
     1137        else if (strcmp(str, "TTY") == 0)
     1138        {
    10211139            periph[periph_index]->type = PERIPH_TYPE_TTY;
    1022             if (header->tty_clusterid == 0xFFFFFFFF) {
    1023                 header->tty_clusterid = cluster_index;
    1024             }
    1025             else  {
     1140            if (header->tty_cluster == 0xFFFFFFFF)
     1141            {
     1142                header->tty_cluster = cluster_index;
     1143                tty_channels = periph[periph_index]->channels;
     1144            }
     1145            else if (header->tty_cluster_bis == 0xFFFFFFFF)
     1146            {
     1147                header->tty_cluster_bis = cluster_index;
     1148            }
     1149            else 
     1150            {
    10261151                error = 1;
    10271152            }
    1028 
    1029             tty_base_offset = pseg[periph[periph_index]->psegid]->base;
    1030             nb_tty_channel = periph[periph_index]->channels;
    1031         }
    1032         else if (strcmp(str, "FBF") == 0) {
     1153        }
     1154        else if (strcmp(str, "FBF") == 0)
     1155        {
    10331156            periph[periph_index]->type = PERIPH_TYPE_FBF;
    1034             if (header->fbf_clusterid == 0xFFFFFFFF) {
    1035                 header->fbf_clusterid = cluster_index;
    1036             }
    1037             else {
     1157            if (header->fbf_cluster == 0xFFFFFFFF) 
     1158            {
     1159                header->fbf_cluster = cluster_index;
     1160            }
     1161            else if (header->fbf_cluster_bis == 0xFFFFFFFF)
     1162            {
     1163                header->fbf_cluster_bis = cluster_index;
     1164            }
     1165            else 
     1166            {
    10381167                error = 1;
    10391168            }
    1040             fbf_base_offset = pseg[periph[periph_index]->psegid]->base;
    1041         }
    1042         else if (strcmp(str, "NIC") == 0) {
     1169        }
     1170        else if (strcmp(str, "NIC") == 0)
     1171        {
    10431172            periph[periph_index]->type = PERIPH_TYPE_NIC;
    1044             if (header->nic_clusterid == 0xFFFFFFFF) {
    1045                 header->nic_clusterid = cluster_index;
    1046             }
    1047             else {
     1173            if (header->nic_cluster == 0xFFFFFFFF) 
     1174            {
     1175                header->nic_cluster = cluster_index;
     1176                nic_channels = periph[periph_index]->channels;
     1177            }
     1178            else if (header->nic_cluster_bis == 0xFFFFFFFF)
     1179            {
     1180                header->nic_cluster_bis = cluster_index;
     1181            }
     1182            else 
     1183            {
    10481184                error = 1;
    10491185            }
    1050             nic_base_offset = pseg[periph[periph_index]->psegid]->base;
    1051             nb_nic_channel = periph[periph_index]->channels;
    1052         }
    1053         else if (strcmp(str, "IOB") == 0) {
     1186        }
     1187        else if (strcmp(str, "CMA") == 0)
     1188        {
     1189            periph[periph_index]->type = PERIPH_TYPE_CMA;
     1190            if (header->cma_cluster == 0xFFFFFFFF) 
     1191            {
     1192                header->cma_cluster = cluster_index;
     1193                cma_channels = periph[periph_index]->channels;
     1194            }
     1195            else if (header->nic_cluster_bis == 0xFFFFFFFF)
     1196            {
     1197                header->cma_cluster_bis = cluster_index;
     1198            }
     1199            else 
     1200            {
     1201                error = 1;
     1202            }
     1203        }
     1204        else if (strcmp(str, "IOB") == 0)
     1205        {
    10541206            periph[periph_index]->type = PERIPH_TYPE_IOB;
    1055             iob_base_offset = pseg[periph[periph_index]->psegid]->base;
    1056 
    1057             if (io_mmu_active) {
     1207            io_mmu_active = 1;
     1208            if (header->iob_cluster == 0xFFFFFFFF) 
     1209            {
     1210                header->iob_cluster = cluster_index;
     1211            }
     1212            else if (header->iob_cluster_bis == 0xFFFFFFFF)
     1213            {
     1214                header->iob_cluster_bis = cluster_index;
     1215            }
     1216            else 
     1217            {
    10581218                error = 1;
    10591219            }
    1060             io_mmu_active = 1;
    1061         }
    1062         // The TIM, ICU, XICU, DMA and IOB peripherals can be replicated in several clusters
    1063         // one per cluster
    1064         else if (strcmp(str, "TIM") == 0 ) {
     1220        }
     1221        // The TIM, ICU, XICU, DMA peripherals are replicated in all clusters
     1222        // but only one component per cluster
     1223        else if (strcmp(str, "TIM") == 0 )
     1224        {
    10651225            periph[periph_index]->type = PERIPH_TYPE_TIM;
    1066             if (found_timer) {
    1067                 error = 1;
    1068             }
     1226            if (found_timer || use_xicu)  error = 1;
    10691227            found_timer = 1;
    1070 
    1071             if (tim_base_offset == 0xFFFFFFFF) {
    1072                 tim_base_offset = pseg[ periph[periph_index]->psegid ]->base;
    1073             }
    1074 
    1075             if (nb_timer_channel_max < periph[periph_index]->channels) {
    1076                 nb_timer_channel_max = periph[periph_index]->channels;
    1077             }
    1078         }
    1079         else if (strcmp(str, "ICU") == 0) {
     1228            if (tim_channels < periph[periph_index]->channels)
     1229            {
     1230                tim_channels = periph[periph_index]->channels;
     1231            }
     1232        }
     1233        else if (strcmp(str, "ICU") == 0)
     1234        {
    10801235            periph[periph_index]->type = PERIPH_TYPE_ICU;
    1081             if (found_icu) {
    1082                 error = 1;
    1083             }
     1236            if (found_icu)  error = 1;
    10841237            found_icu = 1;
    1085 
    1086             if (icu_base_offset == 0xFFFFFFFF) {
    1087                 icu_base_offset = pseg[periph[periph_index]->psegid]->base;
    1088             }
    1089         }
    1090         else if (strcmp(str, "XICU") == 0) {
    1091             periph[periph_index]->type = PERIPH_TYPE_XICU;
    1092             if (found_xicu) {
    1093                 error = 1;
    1094             }
    1095             found_xicu = 1;
    1096 
    1097             //'icu' since we can't have both xicu and icu in an arch
    1098             if (icu_base_offset == 0xFFFFFFFF) {
    1099                 icu_base_offset = pseg[ periph[periph_index]->psegid ]->base;
    1100             }
    1101 
    1102             if (nb_timer_channel_max == 0) {
    1103                 nb_timer_channel_max = 32;
    1104             }
    1105         }
    1106         else if (strcmp(str, "DMA") == 0) {
     1238        }
     1239        else if (strcmp(str, "XICU") == 0)
     1240        {
     1241            periph[periph_index]->type = PERIPH_TYPE_ICU;
     1242            if (found_icu || found_timer)  error = 1;
     1243            found_icu = 1;
     1244            if (tim_channels == 0)
     1245            {
     1246                tim_channels = 32;
     1247            }
     1248            use_xicu = 1;
     1249        }
     1250        else if (strcmp(str, "DMA") == 0)
     1251        {
    11071252            periph[periph_index]->type = PERIPH_TYPE_DMA;
    1108             if (found_dma) {
    1109                 error = 1;
    1110             }
     1253            if (found_dma)  error = 1;
    11111254            found_dma = 1;
    1112 
    1113             if (dma_base_offset == 0xFFFFFFFF) {
    1114                 dma_base_offset = pseg[periph[periph_index]->psegid]->base;
    1115             }
    1116             if (nb_dma_channel_max < periph[periph_index]->channels) {
    1117                 nb_dma_channel_max = periph[periph_index]->channels;
    1118             }
    1119         }
    1120         else {
     1255            if (dma_channels < periph[periph_index]->channels)
     1256                dma_channels = periph[periph_index]->channels;
     1257        }
     1258        else
     1259        {
    11211260            printf("[XML ERROR] illegal <type> for peripheral %d in cluster %d\n",
    11221261                    periph_loc_index, cluster_index);
     
    11241263        }
    11251264
    1126         if (error) {
     1265        if (error)
     1266        {
    11271267            printf("[XML ERROR] illegal <type> for peripheral %d in cluster %d\n",
    11281268                    periph_loc_index, cluster_index);
     
    11301270        }
    11311271    }
    1132     else {
     1272    else
     1273    {
    11331274        printf("[XML ERROR] missing <type> for peripheral  %d in cluster %d\n",
    11341275                periph_loc_index, cluster_index);
    11351276        exit(1);
    11361277    }
    1137 
    11381278
    11391279    periph_index++;
     
    14031543void psegNode(xmlTextReaderPtr reader) {
    14041544    unsigned int ok;
    1405     unsigned int value;
     1545    paddr_t      ll_value;
    14061546    char * str;
    14071547
     
    14501590
    14511591    //////// get base attribute
    1452     value = getIntValue(reader, "base", &ok);
    1453 #if XML_PARSER_DEBUG
    1454     printf("      base = 0x%x\n", value);
     1592    ll_value = getPaddrValue(reader, "base", &ok);
     1593#if XML_PARSER_DEBUG
     1594    printf("      base = 0x%llx\n", ll_value);
    14551595#endif
    14561596    if (ok) {
    1457         pseg[pseg_index]->base = value;
     1597        pseg[pseg_index]->base = ll_value;
    14581598    }
    14591599    else {
     
    14641604
    14651605    //////// get length attribute
    1466     value = getIntValue(reader, "length", &ok);
    1467 #if XML_PARSER_DEBUG
    1468     printf("      length = 0x%x\n", value);
     1606    ll_value = getPaddrValue(reader, "length", &ok);
     1607#if XML_PARSER_DEBUG
     1608    printf("      length = 0x%llx\n", ll_value);
    14691609#endif
    14701610    if (ok) {
    1471         pseg[pseg_index]->length = value;
     1611        pseg[pseg_index]->length = ll_value;
    14721612    } 
    14731613    else {
     
    14851625
    14861626
    1487 /////////////////////////////////////////////
    1488 void clusterNode(xmlTextReaderPtr reader) {
     1627/////////////////////////////////////////
     1628void clusterNode(xmlTextReaderPtr reader)
     1629{
    14891630    unsigned int ok;
    14901631    unsigned int value;
     
    15101651    found_timer = 0;
    15111652    found_icu = 0;
    1512     found_xicu = 0;
    15131653    found_dma = 0;
    15141654
     
    15521692    int status = xmlTextReaderRead(reader);
    15531693
    1554     while (status == 1) {
     1694    while (status == 1)
     1695    {
    15551696        const char * tag = (const char *) xmlTextReaderConstName(reader);
    15561697
     
    15611702        else if (strcmp(tag, "#text")    == 0) { }
    15621703        else if (strcmp(tag, "#comment") == 0) { }
    1563         else if (strcmp(tag, "cluster")  == 0) {
    1564 
    1565             if (use_xicu == 0xFFFFFFFF) {
    1566                 use_xicu = found_xicu;
    1567             }
    1568 
    1569             ////////////////// peripherals checks ////////////////////
    1570             if ((found_timer  && use_xicu) || (!found_timer  && !use_xicu)) {
     1704        else if (strcmp(tag, "cluster")  == 0)
     1705        {
     1706
     1707            ////////////////// peripherals checks /////////////////////////
     1708            if ((found_timer  && use_xicu) || (!found_timer  && !use_xicu))
     1709            {
    15711710                printf("[XML ERROR] illegal or missing timer peripheral in cluster %d\n", cluster_index);
    15721711                exit(1);
    15731712            }
    15741713
    1575             if ((found_icu && use_xicu) || (!found_icu && !use_xicu)) {
     1714            if (!found_icu)
     1715            {
    15761716                printf("[XML ERROR] illegal or missing icu peripheral in cluster %d\n", cluster_index);
    15771717                exit(1);
    15781718            }
    15791719
    1580             if (!found_xicu && use_xicu) {
     1720            if (!found_dma)
     1721            {
    15811722                printf("[XML ERROR] illegal or missing dma peripheral in cluster %d\n", cluster_index);
    15821723                exit(1);
    15831724            }
    15841725
    1585             if (!found_dma) {
    1586                 printf("[XML ERROR] illegal or missing dma peripheral in cluster %d\n", cluster_index);
    1587                 exit(1);
    1588             }
    1589 
    1590 
    1591             if (nb_proc_max < cluster[cluster_index]->procs) {
     1726
     1727            if (nb_proc_max < cluster[cluster_index]->procs)
     1728            {
    15921729                nb_proc_max = cluster[cluster_index]->procs;
    15931730            }
     
    16091746
    16101747//////////////////////////////////////////////
    1611 void clusterSetNode(xmlTextReaderPtr reader) {
    1612     if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) {
    1613         return;
    1614     }
     1748void clusterSetNode(xmlTextReaderPtr reader)
     1749{
     1750    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { return; }
    16151751
    16161752#if XML_PARSER_DEBUG
     
    16191755
    16201756    int status = xmlTextReaderRead(reader);
    1621     while (status == 1) {
     1757    while (status == 1)
     1758    {
    16221759        const char * tag = (const char *) xmlTextReaderConstName(reader);
    16231760
    1624         if (strcmp(tag, "cluster")    == 0) {
    1625             clusterNode(reader);
    1626         }
     1761        if      (strcmp(tag, "cluster")    == 0) { clusterNode(reader); }
    16271762        else if (strcmp(tag, "#text")      == 0) { }
    16281763        else if (strcmp(tag, "#comment")   == 0) { }
    1629         else if (strcmp(tag, "clusterset") == 0) {
     1764        else if (strcmp(tag, "clusterset") == 0)
     1765        {
    16301766            // checking source file consistency
    1631             if (cluster_index != header->clusters) {
     1767            if (cluster_index != header->clusters)
     1768            {
    16321769                printf("[XML ERROR] Wrong number of clusters\n");
    16331770                exit(1);
    16341771            }
    16351772
    1636             if (header->tty_clusterid == 0xFFFFFFFF) {
     1773            // At least one TTY terminal for system boot
     1774            if (header->tty_cluster == 0xFFFFFFFF)
     1775            {
    16371776                printf("[XML ERROR] illegal or missing tty peripheral");
    16381777                exit(1);
     
    16471786            header->coprocs = coproc_index;
    16481787            header->cp_ports = cp_port_index;
     1788            header->periphs = periph_index;
    16491789            return;
    16501790        }
     
    16691809
    16701810    int status = xmlTextReaderRead(reader);
    1671     while (status == 1) {
     1811    while (status == 1)
     1812    {
    16721813        const char * tag = (const char *) xmlTextReaderConstName(reader);
    16731814
    1674         if (strcmp(tag, "vseg") == 0) {
    1675             vsegNode(reader);
    1676         }
     1815        if      (strcmp(tag, "vseg")      == 0) { vsegNode(reader); }
    16771816        else if (strcmp(tag, "#text")     == 0) { }
    16781817        else if (strcmp(tag, "#comment")  == 0) { }
     
    17361875
    17371876//////////////////////////////////////////
    1738 void headerNode(xmlTextReaderPtr reader) {
     1877void headerNode(xmlTextReaderPtr reader)
     1878{
    17391879    char * name;
    17401880    unsigned int value;
    17411881    unsigned int ok;
    17421882
    1743     if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) {
    1744         return;
    1745     }
     1883    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { return; }
    17461884
    17471885#if XML_PARSER_DEBUG
     
    18201958    }
    18211959
    1822     //////// initialise non replicated peripherals cluster_id
    1823     header->tty_clusterid = 0xFFFFFFFF;
    1824     header->nic_clusterid = 0xFFFFFFFF;
    1825     header->ioc_clusterid = 0xFFFFFFFF;
    1826     header->fbf_clusterid = 0xFFFFFFFF;
     1960    //////// initialise non replicated peripherals cluster index
     1961    header->tty_cluster = 0xFFFFFFFF;
     1962    header->nic_cluster = 0xFFFFFFFF;
     1963    header->ioc_cluster = 0xFFFFFFFF;
     1964    header->fbf_cluster = 0xFFFFFFFF;
     1965    header->cma_cluster = 0xFFFFFFFF;
     1966    header->iob_cluster = 0xFFFFFFFF;
     1967    header->tty_cluster_bis = 0xFFFFFFFF;
     1968    header->nic_cluster_bis = 0xFFFFFFFF;
     1969    header->ioc_cluster_bis = 0xFFFFFFFF;
     1970    header->fbf_cluster_bis = 0xFFFFFFFF;
     1971    header->cma_cluster_bis = 0xFFFFFFFF;
     1972    header->iob_cluster_bis = 0xFFFFFFFF;
    18271973
    18281974    ///////// set signature
     
    19402086// this function set the value the vobj_id fiels of all cp_ports
    19412087///////////////////////////////////////////////////////////////////////
    1942 void prepareBuild() {
     2088void prepareBuild()
     2089{
    19432090    unsigned int i;
    19442091    //asign for all cp_ports the correct vspaceid and vobjid
     
    19722119}
    19732120
    1974 
    19752121//////////////////////////////////////////
    1976 void file_write(int fdout, char * towrite) {
     2122void file_write(int fdout, char * towrite)
     2123{
    19772124    unsigned int size = strlen(towrite);
    1978     if (size != write(fdout, towrite, size)) {
     2125    if (size != write(fdout, towrite, size))
     2126    {
    19792127        printf("file_write error");
    19802128        exit(1);
     
    19822130}
    19832131
    1984 
    19852132//////////////////////////////////////////////////
    1986 void def_int_write(int fdout, char * def, int num) {
     2133void def_int_write(int fdout, char * def, int num)
     2134{
    19872135    char  buf[64];
    19882136    sprintf(buf, "#define\t %s  %d\n", def, num);
     
    19902138}
    19912139
    1992 
    1993 /////////////////////////////////////////////////
    1994 void def_hex_write(int fdout, char * def, int num) {
     2140//////////////////////////////////////////////////
     2141void def_hex_write(int fdout, char * def, int num)
     2142{
    19952143    char  buf[64];
    19962144    sprintf(buf, "#define\t %s  0x%x\n", def, num);
     
    19982146}
    19992147
    2000 
    2001 ///////////////////////////////////////
    2002 void  genHd(const char * file_path) {
     2148///////////////////////////////////
     2149void  genHd(const char * file_path)
     2150{
    20032151    int fdout = open_file(file_path);
    20042152
    2005     char * prol = " /* Generated from the mapping_info file */\n\n#ifndef _HD_CONFIG_H\n#define _HD_CONFIG_H\n\n";
     2153    char * prol   = "/* Generated from the mapping_info file */\n\n";
     2154    char * ifdef  = "#ifndef _HD_CONFIG_H\n#define _HD_CONFIG_H\n\n";
     2155    char * epil   = "\n#endif //_HD_CONFIG_H";
     2156
    20062157    file_write(fdout, prol);
    2007 
    2008     def_int_write(fdout, "CLUSTER_X"    , cluster_x);
    2009     def_int_write(fdout, "CLUSTER_Y"    , cluster_y);
    2010     def_int_write(fdout, "NB_CLUSTERS"  , cluster_index);
    2011     def_hex_write(fdout, "CLUSTER_SIZE" , (((unsigned long long) 1) << 32) / cluster_index);
    2012     def_int_write(fdout, "NB_PROCS_MAX" , nb_proc_max);
    2013     def_int_write(fdout, "NB_TIMERS_MAX", nb_timer_channel_max);
    2014     def_int_write(fdout, "NB_DMAS_MAX"  , nb_dma_channel_max);
    2015     def_int_write(fdout, "NB_TTYS"      , nb_tty_channel);
    2016     def_int_write(fdout, "NB_IOCS"      , nb_ioc_channel);
    2017     def_int_write(fdout, "NB_NICS"      , nb_nic_channel);
    2018     def_int_write(fdout, "NB_TASKS"     , nb_tasks_max);
     2158    file_write(fdout, ifdef);
     2159
     2160    def_int_write(fdout, "CLUSTER_X         ", cluster_x);
     2161    def_int_write(fdout, "CLUSTER_Y         ", cluster_y);
     2162    def_int_write(fdout, "NB_CLUSTERS       ", cluster_index);
     2163    def_int_write(fdout, "NB_PROCS_MAX      ", nb_proc_max);
     2164    def_int_write(fdout, "NB_TASKS_MAX      ", nb_tasks_max);
    20192165
    20202166    file_write(fdout, "\n");
    2021     def_int_write(fdout, "USE_XICU"     , use_xicu);
    2022     def_int_write(fdout, "IOMMU_ACTIVE ", io_mmu_active);
    2023 
    2024     char * epil = "\n#endif //_HD_CONFIG_H";
     2167
     2168    def_int_write(fdout, "NB_TIM_CHANNELS   ", tim_channels);
     2169    def_int_write(fdout, "NB_DMA_CHANNELS   ", dma_channels);
     2170
     2171    file_write(fdout, "\n");
     2172
     2173    def_int_write(fdout, "NB_TTY_CHANNELS   ", tty_channels);
     2174    def_int_write(fdout, "NB_IOC_CHANNELS   ", ioc_channels);
     2175    def_int_write(fdout, "NB_NIC_CHANNELS   ", nic_channels);
     2176    def_int_write(fdout, "NB_CMA_CHANNELS   ", cma_channels);
     2177
     2178    file_write(fdout, "\n");
     2179
     2180    def_int_write(fdout, "USE_XICU          ", use_xicu);
     2181    def_int_write(fdout, "IOMMU_ACTIVE      ", io_mmu_active);
     2182
    20252183    file_write(fdout, epil);
    20262184
     
    20282186}
    20292187
    2030 
    20312188////////////////////////////////////////////////////////
    2032 void ld_write(int fdout, char * seg, unsigned int addr) {
     2189void ld_write(int fdout, char * seg, unsigned int addr)
     2190{
    20332191    char buf[64];
    20342192    sprintf(buf, "%s = 0x%x;\n", seg, addr);
    20352193    file_write(fdout, buf);
    2036 
    20372194}
    20382195
    2039 
    2040 ///////////////////////////////////////
    2041 void genLd(const char * file_path) {
    2042     int fdout = open_file(file_path);
     2196//////////////////////////////////
     2197void genLd(const char * file_path)
     2198{
     2199    int          fdout = open_file(file_path);
     2200    unsigned int count = 0;
     2201    unsigned int vseg_id;
    20432202
    20442203    char * prol = "/* Generated from the mapping_info file */\n\n";
    20452204    file_write(fdout, prol);
    20462205
    2047     //boot
    2048     ld_write(fdout, "seg_boot_code_base", boot_code_base);
    2049     ld_write(fdout, "seg_boot_stack_base", boot_stack_base);
    2050     ld_write(fdout, "seg_mapping_base", boot_mapping_base);
    2051 
    2052     //kernel
    2053     ld_write(fdout, "\nseg_kernel_code_base",  kernel_code_base);
    2054     ld_write(fdout, "seg_kernel_data_base",    kernel_data_base);
    2055     ld_write(fdout, "seg_kernel_uncdata_base", kernel_uncdata_base);
    2056     ld_write(fdout, "seg_kernel_init_base",    kernel_init_base);
    2057 
    2058     //peripherals
    2059     ld_write(fdout, "\nseg_fbf_base", fbf_base_offset);
    2060     ld_write(fdout, "seg_icu_base",   icu_base_offset);
    2061     ld_write(fdout, "seg_ioc_base",   ioc_base_offset);
    2062     ld_write(fdout, "seg_nic_base",   nic_base_offset);
    2063     ld_write(fdout, "seg_tty_base",   tty_base_offset);
    2064     ld_write(fdout, "seg_dma_base",   dma_base_offset);
    2065     ld_write(fdout, "seg_tim_base",   tim_base_offset);
    2066     ld_write(fdout, "seg_gcd_base",   gcd_base_offset);
    2067     ld_write(fdout, "seg_iob_base",   iob_base_offset);
     2206    // boot and kernel segments
     2207    for (vseg_id = 0 ; vseg_id < header->vsegs ; vseg_id++)
     2208    {
     2209        if ( strcmp(vseg[vseg_id]->name, "seg_boot_code") == 0 )
     2210        {
     2211            ld_write(fdout, "seg_boot_code_base      ",  vseg[vseg_id]->vbase);
     2212            count++;
     2213        }
     2214        else if ( strcmp(vseg[vseg_id]->name, "seg_boot_stack") == 0 )
     2215        {
     2216            ld_write(fdout, "seg_boot_stack_base     ",  vseg[vseg_id]->vbase);
     2217            count++;
     2218        }
     2219        else if ( strcmp(vseg[vseg_id]->name, "seg_boot_mapping") == 0 )
     2220        {
     2221            ld_write(fdout, "seg_mapping_base        ",  vseg[vseg_id]->vbase);
     2222            count++;
     2223        }
     2224        else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_code") == 0 )
     2225        {
     2226            ld_write(fdout, "seg_kernel_code_base    ",  vseg[vseg_id]->vbase);
     2227            count++;
     2228        }
     2229        else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_data") == 0 )
     2230        {
     2231            ld_write(fdout, "seg_kernel_data_base    ",  vseg[vseg_id]->vbase);
     2232            count++;
     2233        }
     2234        else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_uncdata") == 0 )
     2235        {
     2236            ld_write(fdout, "seg_kernel_uncdata_base ",  vseg[vseg_id]->vbase);
     2237            count++;
     2238        }
     2239        else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_init") == 0 )
     2240        {
     2241            ld_write(fdout, "seg_kernel_init_base    ",  vseg[vseg_id]->vbase);
     2242            count++;
     2243        }
     2244    }
     2245    if ( count != 7 )
     2246    {
     2247        printf ("[XML ERROR] Missing Boot or Kernel vseg : only %d\n", count);
     2248        printf ("Mandatory segments are :\n");
     2249        printf (" - seg_boot_code\n");
     2250        printf (" - seg_boot_stack\n");
     2251        printf (" - seg_boot_mapping\n");
     2252        printf (" - seg_kernel_code\n");
     2253        printf (" - seg_kernel_data\n");
     2254        printf (" - seg_kernel_uncdata\n");
     2255        printf (" - seg_kernel_init\n");
     2256    }
     2257
     2258    file_write(fdout, "\n");
     2259
     2260    // non replicated peripherals
     2261    ld_write(fdout, "\nseg_fbf_base            ", periph_vbase_array[PERIPH_TYPE_FBF]);
     2262    ld_write(fdout, "seg_ioc_base            ",   periph_vbase_array[PERIPH_TYPE_IOC]);
     2263    ld_write(fdout, "seg_nic_base            ",   periph_vbase_array[PERIPH_TYPE_NIC]);
     2264    ld_write(fdout, "seg_tty_base            ",   periph_vbase_array[PERIPH_TYPE_TTY]);
     2265    ld_write(fdout, "seg_gcd_base            ",   periph_vbase_array[PERIPH_TYPE_GCD]);
     2266    ld_write(fdout, "seg_iob_base            ",   periph_vbase_array[PERIPH_TYPE_IOB]);
     2267
     2268    file_write(fdout, "\n");
     2269
     2270    // replicated peripherals
     2271    ld_write(fdout, "seg_icu_base            ",   periph_vbase_array[PERIPH_TYPE_ICU]);
     2272    ld_write(fdout, "seg_dma_base            ",   periph_vbase_array[PERIPH_TYPE_DMA]);
     2273    ld_write(fdout, "seg_tim_base            ",   periph_vbase_array[PERIPH_TYPE_TIM]);
    20682274
    20692275    close(fdout);
    20702276}
    20712277
    2072 
    2073 char * buildPath(const char * path, const char * name) {
     2278//////////////////////////////////////////////////////
     2279char * buildPath(const char * path, const char * name)
     2280{
    20742281    char * res = calloc(strlen(path) + strlen(name) + 1, 1);
    20752282    strcat(res, path);
     
    20802287
    20812288
    2082 /////////////////////////////////////
    2083 int main(int argc, char * argv[]) {
     2289//////////////////////////////////
     2290int main(int argc, char * argv[])
     2291{
    20842292    if (argc < 3) {
    20852293        printf("Usage: xml2bin <input_file_path> <output_path>\n");
Note: See TracChangeset for help on using the changeset viewer.