Changeset 238 for soft/giet_vm/boot


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/boot
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.