Changeset 199


Ignore:
Timestamp:
Aug 9, 2012, 2:38:06 PM (12 years ago)
Author:
alain
Message:

Introducing the "idle" to improve the exit mechanism.

Location:
soft/giet_vm
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/boot/boot_init.c

    r198 r199  
    2323// and the mapping:
    2424// - physical segmentation of the physical address space,
    25 // - number of virtual spaces (one multi-task application per vspace),
    26 // - static placement of tasks on the processors,
    27 // - static placement of virtual segments (vseg) in the physical segments (pseg).
    28 // - static placement of virtual objects (vobj) on virtual segments (vseg).
     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,
    2929//
    30 // The page table are statically constructed in the boot phase, and they do not
     30// The page table are statically build in the boot phase, and they do not
    3131// change during execution. The GIET uses only 4 Kbytes pages.
    3232// As most applications use only a limited number of segments, the number of PT2s
    3333// actually used by a given virtual space is generally smaller than 2048, and is
    34 // computed using the length of the vobj and stored in the boot_max_pt2 global variable,
    35 // which is a table indexed by the vspace_id.
    36 
    37 // defined by the (GIET_NB_PT2_MAX) configuration parameter.
     34// computed during the boot phase.
    3835// The max number of virtual spaces (GIET_NB_VSPACE_MAX) is a configuration parameter.
    3936//
     
    794791    mapping_periph_t*   periph  = boot_get_periph_base( header );
    795792
    796     unsigned int periph_id;
    797     unsigned int cluster_id;
    798     unsigned int channels;
    799 
    800793    // checking mapping availability
    801794    if ( header->signature != IN_MAPPING_SIGNATURE )
     
    807800    }
    808801
    809     // checking NB_CLUSTERS
     802    // checking Rnumber of clusters
    810803    if ( header->clusters != NB_CLUSTERS )
    811804    {
     
    819812    }
    820813
    821     // checking NB_PROC_MAX
     814    // checking number of virtual spaces
     815    if ( header->vspaces > GIET_NB_VSPACE_MAX )
     816    {
     817        boot_puts("\n[BOOT ERROR] : number of vspaces > GIET_NB_VSPACE_MAX\n");
     818        boot_puts("\n");
     819        boot_exit();
     820    }
     821
     822    // checking harware
     823    unsigned int periph_id;
     824    unsigned int cluster_id;
     825    unsigned int channels;
     826    unsigned int tty_found = 0;
     827    unsigned int nic_found = 0;
    822828    for ( cluster_id = 0 ; cluster_id < NB_CLUSTERS ; cluster_id++ )
    823829    {
     830        // NB_PROCS_MAX
    824831        if ( cluster[cluster_id].procs > NB_PROCS_MAX )
    825832        {
    826833            boot_puts("\n[BOOT ERROR] too much processors in cluster ");
    827834            boot_putw( cluster_id );
    828             boot_puts("\n             - In giet_config, NB_PROCS_MAX = ");
    829             boot_putw ( NB_PROCS_MAX );
    830             boot_puts("\n             - In mapping_info, nprocs = ");
     835            boot_puts(" : procs = ");
    831836            boot_putw ( cluster[cluster_id].procs );
    832837            boot_puts("\n");
    833838            boot_exit();
    834839        }
    835     }
    836 
    837     // checking number of virtual spaces
    838     if ( header->vspaces > GIET_NB_VSPACE_MAX )
    839     {
    840         boot_puts("\n[BOOT ERROR] : number of vspaces > GIET_NB_VSPACE_MAX\n");
    841         boot_puts("\n");
    842         boot_exit();
    843     }
    844 
    845     // checking TTY number
    846     cluster_id = header->tty_clusterid;
    847     for ( periph_id = cluster[cluster_id].periph_offset ;
    848           periph_id < cluster[cluster_id].periph_offset + cluster[cluster_id].periphs ;
    849           periph_id++ )
    850     {
    851         if ( periph[periph_id].type == PERIPH_TYPE_TTY )
    852         {
    853             channels = periph[periph_id].channels;
    854             break;
    855         }
    856                
    857     }
    858     if ( channels > NB_TTYS )
    859     {
    860         boot_puts("\n[BOOT ERROR] Incoherent NB_TTYS");
    861         boot_puts("\n             - In giet_config,  value = ");
    862         boot_putw ( NB_TTYS );
    863         boot_puts("\n             - In mapping_info, value = ");
    864         boot_putw ( channels );
    865         boot_puts("\n");
    866         boot_exit();
    867     }
    868 
    869     // TODO same type of checking for TIMERS, DMAS, NIC channels
    870 
     840
     841        for ( periph_id = cluster[cluster_id].periph_offset ;
     842              periph_id < cluster[cluster_id].periph_offset + cluster[cluster_id].periphs ;
     843              periph_id++ )
     844        {
     845            // NB_TTYS
     846            if ( periph[periph_id].type == PERIPH_TYPE_TTY )
     847            {
     848                if ( tty_found )
     849                {
     850                    boot_puts("\n[BOOT ERROR] TTY component should not be replicated\n");
     851                    boot_exit();
     852                }
     853                if ( periph[periph_id].channels > NB_TTYS )
     854                {
     855                    boot_puts("\n[BOOT ERROR] Too much TTY terminals in cluster ");
     856                    boot_putw( cluster_id );
     857                    boot_puts(" : ttys = ");
     858                    boot_putw ( periph[periph_id].channels );
     859                    boot_puts("\n");
     860                    boot_exit();
     861                }
     862                tty_found = 1;
     863            }
     864            // NB_NICS
     865            if ( periph[periph_id].type == PERIPH_TYPE_NIC )
     866            {
     867                if ( nic_found )
     868                {
     869                    boot_puts("\n[BOOT ERROR] NIC component should not be replicated\n");
     870                    boot_exit();
     871                }
     872                if ( periph[periph_id].channels > NB_NICS )
     873                {
     874                    boot_puts("\n[BOOT ERROR] Too much NIC channels in cluster ");
     875                    boot_putw( cluster_id );
     876                    boot_puts(" : nics = ");
     877                    boot_putw ( periph[periph_id].channels );
     878                    boot_puts("\n");
     879                    boot_exit();
     880                }
     881                nic_found = 1;
     882            }
     883            // NB_TIMERS
     884            if ( periph[periph_id].type == PERIPH_TYPE_TIM )
     885            {
     886                if ( periph[periph_id].channels > NB_TIMERS_MAX )
     887                {
     888                    boot_puts("\n[BOOT ERROR] Too much user timers in cluster ");
     889                    boot_putw( cluster_id );
     890                    boot_puts(" : timers = ");
     891                    boot_putw ( periph[periph_id].channels );
     892                    boot_puts("\n");
     893                    boot_exit();
     894                }
     895            }
     896            // NB_DMAS
     897            if ( periph[periph_id].type == PERIPH_TYPE_DMA )
     898            {
     899                if ( periph[periph_id].channels > NB_DMAS_MAX )
     900                {
     901                    boot_puts("\n[BOOT ERROR] Too much DMA channels in cluster ");
     902                    boot_putw( cluster_id );
     903                    boot_puts(" : channels = ");
     904                    boot_putw ( periph[periph_id].channels );
     905                    boot_puts("\n");
     906                    boot_exit();
     907                }
     908            }
     909        } // end for periphs
     910    } // end for clusters
    871911} // end boot_check_mapping()
    872912
     
    14191459              task_id++ )
    14201460        {
    1421             // ra :  the return address is &boot_eret()
    1422             unsigned int ra = (unsigned int)&boot_eret;
    1423 
    1424             // sr : value required before an eret instruction
    1425             unsigned int sr = 0x0000FF13;
    1426 
    1427             // ptpr : page table physical base address (shifted by 13 bit)
    1428             unsigned int ptpr = (unsigned int)boot_ptabs_paddr[vspace_id] >> 13;
    1429 
    1430             // ptab : page_table virtual base address (not a register)
    1431             unsigned int ptab = (unsigned int)boot_ptabs_vaddr[vspace_id];
    1432 
    1433             // tty : terminal global index provided by a global allocator
    1434             unsigned int tty = 0xFFFFFFFF;
     1461            // ctx_ra :  the return address is &boot_eret()
     1462            unsigned int ctx_ra = (unsigned int)&boot_eret;
     1463
     1464            // ctx_sr : value required before an eret instruction
     1465            unsigned int ctx_sr = 0x0000FF13;
     1466
     1467            // ctx_ptpr : page table physical base address (shifted by 13 bit)
     1468            unsigned int ctx_ptpr = (unsigned int)boot_ptabs_paddr[vspace_id] >> 13;
     1469
     1470            // ctx_ptab : page_table virtual base address
     1471            unsigned int ctx_ptab = (unsigned int)boot_ptabs_vaddr[vspace_id];
     1472
     1473            // ctx_tty : terminal global index provided by a global allocator
     1474            unsigned int ctx_tty = 0xFFFFFFFF;
    14351475            if ( task[task_id].use_tty )
    14361476            {
     
    14441484                    boot_exit();
    14451485                }
    1446                 tty = alloc_tty_channel;
     1486                ctx_tty = alloc_tty_channel;
    14471487                alloc_tty_channel++;
    14481488            }
    14491489
    1450             // nic : NIC channel global index provided by a global allocator
    1451             unsigned int nic = 0xFFFFFFFF;
     1490            // ctx_nic : NIC channel global index provided by a global allocator
     1491            unsigned int ctx_nic = 0xFFFFFFFF;
    14521492            if ( task[task_id].use_nic )
    14531493            {
     
    14611501                    boot_exit();
    14621502                }
    1463                 nic = alloc_nic_channel;
     1503                ctx_nic = alloc_nic_channel;
    14641504                alloc_nic_channel++;
    14651505            }
    14661506
    1467             // timer : user TIMER global index provided by a cluster allocator
    1468             unsigned int timer = 0xFFFFFFFF;
     1507            // ctx_timer : user TIMER global index provided by a cluster allocator
     1508            unsigned int ctx_timer = 0xFFFFFFFF;
    14691509            if ( task[task_id].use_timer )
    14701510            {
     
    14791519                    boot_exit();
    14801520                }
    1481                 timer = cluster_id*NB_TIMERS_MAX + alloc_timer_channel[cluster_id];
     1521                ctx_timer = cluster_id*NB_TIMERS_MAX + alloc_timer_channel[cluster_id];
    14821522                alloc_timer_channel[cluster_id]++;
    14831523            }
    14841524
    1485             // fbdma : DMA global index provided by a cluster allocator 
    1486             unsigned int fbdma = 0xFFFFFFFF;
     1525            // ctx_fbdma : DMA global index provided by a cluster allocator 
     1526            unsigned int ctx_fbdma = 0xFFFFFFFF;
    14871527            if ( task[task_id].use_fbdma )
    14881528            {
     
    14971537                    boot_exit();
    14981538                }
    1499                 fbdma = cluster_id*NB_DMAS_MAX + alloc_fbdma_channel[cluster_id];
     1539                ctx_fbdma = cluster_id*NB_DMAS_MAX + alloc_fbdma_channel[cluster_id];
    15001540                alloc_fbdma_channel[cluster_id]++;
    15011541            }
    15021542
    1503             // epc : Get the (virtual) base address of the start_vector containing
    1504             // the start addresses for all tasks defined in the vspace.
     1543            // ctx_epc : Get the virtual address of the start function
    15051544            mapping_vobj_t* pvobj = &vobj[vspace[vspace_id].vobj_offset +
    15061545                                          vspace[vspace_id].start_offset];
    15071546            unsigned int* start_vector_vbase = (unsigned int*)pvobj->vaddr;
    1508             unsigned int epc = start_vector_vbase[task[task_id].startid];
    1509 
    1510             // sp :  Get the vobj containing the stack
     1547            unsigned int ctx_epc = start_vector_vbase[task[task_id].startid];
     1548
     1549            // ctx_sp :  Get the vobj containing the stack
    15111550            unsigned int vobj_id = task[task_id].vobjlocid + vspace[vspace_id].vobj_offset;
    1512             unsigned int sp = vobj[vobj_id].vaddr + vobj[vobj_id].length;
     1551            unsigned int ctx_sp = vobj[vobj_id].vaddr + vobj[vobj_id].length;
    15131552
    15141553            // compute gpid = global processor index
     
    15161555                                task[task_id].proclocid;
    15171556
    1518             // sched : scheduler physical address
    1519             unsigned int sched = (unsigned int)boot_schedulers_paddr[gpid];
    1520 
    15211557            // In the code below, we access the scheduler with specific access
    15221558            // functions, because we only have the physical address of the scheduler,
     
    15261562            unsigned int ltid = boot_scheduler_get_tasks( gpid );
    15271563
    1528             if ( ltid >= 15 )
     1564            if ( ltid >= IDLE_TASK_INDEX )
    15291565            {
    15301566                boot_puts("\n[BOOT ERROR] : ");
     
    15431579
    15441580            // initializes the task context in scheduler[gpid]
    1545             boot_scheduler_set_context( gpid, ltid, CTX_SR_ID    , sr    );
    1546             boot_scheduler_set_context( gpid, ltid, CTX_SP_ID    , sp    );
    1547             boot_scheduler_set_context( gpid, ltid, CTX_RA_ID    , ra    );
    1548             boot_scheduler_set_context( gpid, ltid, CTX_EPC_ID   , epc   );
    1549             boot_scheduler_set_context( gpid, ltid, CTX_PTPR_ID  , ptpr  );
    1550             boot_scheduler_set_context( gpid, ltid, CTX_TTY_ID   , tty   );
    1551             boot_scheduler_set_context( gpid, ltid, CTX_TIMER_ID , timer );
    1552             boot_scheduler_set_context( gpid, ltid, CTX_FBDMA_ID , fbdma );
    1553             boot_scheduler_set_context( gpid, ltid, CTX_PTAB_ID  , ptab  );
    1554             boot_scheduler_set_context( gpid, ltid, CTX_SCHED_ID , sched );
     1581            boot_scheduler_set_context( gpid, ltid, CTX_SR_ID    , ctx_sr     );
     1582            boot_scheduler_set_context( gpid, ltid, CTX_SP_ID    , ctx_sp     );
     1583            boot_scheduler_set_context( gpid, ltid, CTX_RA_ID    , ctx_ra     );
     1584            boot_scheduler_set_context( gpid, ltid, CTX_EPC_ID   , ctx_epc    );
     1585            boot_scheduler_set_context( gpid, ltid, CTX_PTPR_ID  , ctx_ptpr   );
     1586            boot_scheduler_set_context( gpid, ltid, CTX_TTY_ID   , ctx_tty    );
     1587            boot_scheduler_set_context( gpid, ltid, CTX_FBDMA_ID , ctx_fbdma  );
     1588            boot_scheduler_set_context( gpid, ltid, CTX_NIC_ID   , ctx_nic    );
     1589            boot_scheduler_set_context( gpid, ltid, CTX_TIMER_ID , ctx_timer  );
     1590            boot_scheduler_set_context( gpid, ltid, CTX_PTAB_ID  , ctx_ptab   );
     1591            boot_scheduler_set_context( gpid, ltid, CTX_LTID_ID  , ltid       );
     1592            boot_scheduler_set_context( gpid, ltid, CTX_VSID_ID  , vspace_id  );
     1593            boot_scheduler_set_context( gpid, ltid, CTX_RUN_ID   , 1          );
    15551594                                       
    15561595#if BOOT_DEBUG_SCHED
     
    15591598boot_puts(" allocated to processor ");
    15601599boot_putw( gpid );
    1561 boot_puts(" / ltid = ");
     1600boot_puts("  - ctx[LTID]  = ");
    15621601boot_putw( ltid );
    15631602boot_puts("\n");
    15641603
    1565 boot_puts("  - SR          = ");
    1566 boot_putw( sr );
    1567 boot_puts("\n");
    1568 
    1569 boot_puts("  - SP          = ");
    1570 boot_putw( sp );
    1571 boot_puts("\n");
    1572 
    1573 boot_puts("  - RA          = ");
    1574 boot_putw( ra );
    1575 boot_puts("\n");
    1576 
    1577 boot_puts("  - EPC         = ");
    1578 boot_putw( epc );
    1579 boot_puts("\n");
    1580 
    1581 boot_puts("  - PTPR        = ");
    1582 boot_putw( ptpr<<13 );
    1583 boot_puts("\n");
    1584 
    1585 boot_puts("  - TTY         = ");
    1586 boot_putw( tty );
    1587 boot_puts("\n");
    1588 
    1589 boot_puts("  - TIMER       = ");
    1590 boot_putw( timer );
    1591 boot_puts("\n");
    1592 
    1593 boot_puts("  - FBDMA       = ");
    1594 boot_putw( fbdma );
    1595 boot_puts("\n");
    1596 
    1597 boot_puts("  - PTAB        = ");
    1598 boot_putw( ptab );
    1599 boot_puts("\n");
    1600 
    1601 boot_puts("  - SCHED       = ");
    1602 boot_putw( sched );
    1603 boot_puts("\n");
     1604boot_puts("  - ctx[SR]     = ");
     1605boot_putw( ctx_sr );
     1606boot_puts("\n");
     1607
     1608boot_puts("  - ctx[SR]     = ");
     1609boot_putw( ctx_sp );
     1610boot_puts("\n");
     1611
     1612boot_puts("  - ctx[RA]     = ");
     1613boot_putw( ctx_ra );
     1614boot_puts("\n");
     1615
     1616boot_puts("  - ctx[EPC]    = ");
     1617boot_putw( ctx_epc );
     1618boot_puts("\n");
     1619
     1620boot_puts("  - ctx[PTPR]   = ");
     1621boot_putw( ctx_ptpr );
     1622boot_puts("\n");
     1623
     1624boot_puts("  - ctx[TTY]    = ");
     1625boot_putw( ctx_tty );
     1626boot_puts("\n");
     1627
     1628boot_puts("  - ctx[NIC]    = ");
     1629boot_putw( ctx_nic );
     1630boot_puts("\n");
     1631
     1632boot_puts("  - ctx[TIMER]  = ");
     1633boot_putw( ctx_timer );
     1634boot_puts("\n");
     1635
     1636boot_puts("  - ctx[FBDMA]  = ");
     1637boot_putw( ctx_fbdma );
     1638boot_puts("\n");
     1639
     1640boot_puts("  - ctx[PTAB]   = ");
     1641boot_putw( ctx_ptab );
     1642boot_puts("\n");
     1643
     1644boot_puts("  - ctx[VSID]   = ");
     1645boot_putw( vspace_id );
     1646boot_puts("\n");
     1647
    16041648#endif
    16051649
  • soft/giet_vm/boot/reset.S

    r189 r199  
    115115    jal         boot_puts
    116116    nop
    117     mfc0        a0,     CP0_BAR
     117    mfc0        a0,     CP0_BVAR
    118118        jal             boot_putw
    119119    nop
  • soft/giet_vm/giet_config.h

    r197 r199  
    1313
    1414#define BOOT_DEBUG_PERI     0       /* display peripherals initialisation on TTY0 */
    15 #define BOOT_DEBUG_PT           1           /* display page tables initialisation on TTY0 */
     15#define BOOT_DEBUG_PT           0           /* display page tables initialisation on TTY0 */
    1616#define BOOT_DEBUG_VOBJS        0               /* display vobjs initialisation on TTY0 */
    17 #define BOOT_DEBUG_SCHED        1               /* display schedulers initialisation on TTY0 */
     17#define BOOT_DEBUG_SCHED        0               /* display schedulers initialisation on TTY0 */
    1818
    19 #define GIET_DEBUG_INIT         0               /* display parallel kernel initialisation on TTY0 */
     19#define GIET_DEBUG_INIT         1               /* display parallel kernel initialisation on TTY0 */
    2020#define GIET_DEBUG_SWITCH       0           /* display context switchs on TTY0 */
    2121
     
    3131#define NB_DMAS_MAX                     1           /* max number of DMA channels per cluster*/
    3232#define NB_TTYS                         8           /* total number of TTY channels */
    33 #define NB_IOCS                         1           /* total number of IOC channels */
    34 #define NB_NICS                         1           /* total number of NIC channels */
     33#define NB_IOCS                         0           /* total number of IOC channels */
     34#define NB_NICS                         0           /* total number of NIC channels */
    3535
    3636/* software parameters */
  • soft/giet_vm/hello/main.c

    r191 r199  
    33__attribute__((constructor)) void main()
    44{
    5         unsigned int    i;
    65        char                byte;
    76    unsigned int        proc = giet_procid();
     7    unsigned int*       illegal = 0xFFFFFFF0;
    88
    9         for( i=0 ; i<1000 ; i++ )
     9        while (1)
    1010        {
    11                 if( giet_tty_printf(" hello from processor %d\n", proc) )
    12                 {
    13                         giet_tty_puts("echec tty_printf\n");
    14                         giet_exit();
    15                 }
    16         if( giet_tty_getc((void*)&byte) )
    17         {
    18                         giet_tty_puts("echec tty_getc_irq\n");
    19                         giet_exit();
    20                 }
     11                giet_tty_printf(" hello from processor %d\n", proc);
     12        giet_tty_getc((void*)&byte);
    2113        if ( byte == 'q' ) giet_exit();
     14        if ( byte == 'x' ) *illegal = 1;
    2215        }
    23     giet_exit();
    24 
    2516} // end main
    2617
  • soft/giet_vm/sys/common.c

    r189 r199  
    324324    return _physical_read_access( &(psched->current) );
    325325}
     326////////////////////////////////////////////////////////////////////////////
     327//    _set_current_task_id()
     328// This function returns the index of the currently running task.
     329////////////////////////////////////////////////////////////////////////////
     330void _set_current_task_id( unsigned int value )
     331{
     332    static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
     333    _physical_write_access( &(psched->current), value );
     334}
    326335///////////////////////////////////////////////////////////////////////////////
    327 //    _get_current_context_slot()
    328 // This function returns the global TTY index for the currently running task.
     336//    _get_context_slot()
     337// This function returns a slot content for the task defined by task_id.
    329338///////////////////////////////////////////////////////////////////////////////
    330 unsigned int _get_current_context_slot(unsigned int slot_id)
    331 {
    332     static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
    333     unsigned int                        current = _physical_read_access( &(psched->current) );
    334     return _physical_read_access( &(psched->context[current][slot_id]) );
    335 }
    336 /////////////////////////////////////////////i//////////////////////////////////
     339unsigned int _get_context_slot( unsigned int task_id,
     340                                unsigned int slot_id )
     341{
     342    static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
     343    return _physical_read_access( &(psched->context[task_id][slot_id]) );
     344}
     345///////////////////////////////////////////////////////////////////////////////
     346//    _set_context_slot()
     347// This function returns a slot content for the task defined by task_id.
     348///////////////////////////////////////////////////////////////////////////////
     349void _set_context_slot( unsigned int task_id,
     350                        unsigned int slot_id,
     351                        unsigned int value )
     352{
     353    static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
     354    _physical_write_access( &(psched->context[task_id][slot_id]), value );
     355}
     356////////////////////////////////////////////////////////////////////////////////
    337357//    _get_interrupt_vector_entry()
    338358// This function returns the interrupt_vector entry defined by argument index.
     
    342362    static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
    343363    return _physical_read_access( &(psched->interrupt_vector[index]) );
    344 }
    345 ////////////////////////////////////////////////////////////////////////////
    346 //    _set_current_task_id()
    347 // This function returns the index of the currently running task.
    348 ////////////////////////////////////////////////////////////////////////////
    349 void _set_current_task_id( unsigned int value )
    350 {
    351     static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
    352     _physical_write_access( &(psched->current), value );
    353364}
    354365
  • soft/giet_vm/sys/common.h

    r189 r199  
    3636void                            _putd(unsigned int val);
    3737
    38 unsigned int            _strncmp(const char* s1, const char* s2, unsigned int n);
     38unsigned int            _strncmp( const char* s1,
     39                              const char* s2,
     40                              unsigned int n );
    3941
    40 void                            _dcache_buf_invalidate(const void *buffer, unsigned int size);
    41 
    42 void                            _itoa_dec(unsigned int val, char* buf);
    43 void                            _itoa_hex(unsigned int val, char* buf);
     42void                            _dcache_buf_invalidate( const void *buffer,
     43                                            unsigned int size );
    4444
    4545void                            _dtlb_off(void);
     
    5555unsigned int            _get_sched(void);
    5656
    57 unsigned int            _get_current_context_slot(unsigned int index);
     57unsigned int            _get_context_slot( unsigned int task_id,
     58                                       unsigned int slot_id );
     59
     60void                            _set_context_slot( unsigned int task_id,
     61                                       unsigned int slot_id,
     62                                       unsigned int value );
     63
    5864unsigned int            _get_interrupt_vector_entry(unsigned int index);
    59 unsigned int            _get_current_task_id(void);
     65
     66unsigned int            _get_current_task_id( void );
     67void                            _set_current_task_id( unsigned int value );
     68
    6069unsigned int            _get_tasks_number(void);
    6170
    62 void                            _set_current_task_id( unsigned int value);
    6371
    6472void                            _get_lock(unsigned int* lock);
  • soft/giet_vm/sys/ctx_handler.c

    r189 r199  
    1 ///////////////////////////////////////////////////////////////////////////////////////
     1/////////////////////////////////////////////////////////////////////////////////////////
    22// File     : ctx_handler.c
    33// Date     : 01/04/2012
    44// Authors  : alain greiner & joel porquet
    55// Copyright (c) UPMC-LIP6
    6 ///////////////////////////////////////////////////////////////////////////////////////
     6/////////////////////////////////////////////////////////////////////////////////////////
    77// The ctx_handler.h and ctx_handler.c files are part of the GIET-VM nano-kernel.
    88// This code is used to support context switch when several tasks are executing
    99// in time multiplexing on a single processor.
    10 // The tasks must be statically allocated to a processor in the boot phase, and
    11 // there is one private scheduler per processor.
    12 // Each sheduler contains up to 15 task contexts.
    13 ///////////////////////////////////////////////////////////////////////////////////////
     10// The tasks are statically allocated to a processor in the boot phase, and
     11// there is one private scheduler per processor. Each sheduler occupies 4K bytes,
     12// and contains up to 14 task contexts (task_id is from 0 to 13).
     13// The task context [14] is reserved for the "idle" task that does nothing, and
     14// is launched by the scheduler when there is no other runable task.
     15/////////////////////////////////////////////////////////////////////////////////////////
    1416
    1517#include <giet_config.h>
     
    2022#include <sys_handler.h>
    2123
    22 ///////////////////////////////////////////////////////////////////////////////////////
     24/////////////////////////////////////////////////////////////////////////////////////////
    2325// A task context is an array of 64 words = 256 bytes.
    24 // It contains copies of processor registers (when the task is preempted),
    25 // and some general informations associated to the task.
     26// It contains copies of processor registers (when the task is preempted):
     27// - GPR[i], generally stored in slot (i). $0, *26 & $27 are not saved.
     28// - HI & LO registers
     29// - CP0 registers: EPC, SR, CR, BVAR
     30// - CP2 registers : PTPR
     31// It contains some general informations associated to the task:
     32// - TTY        : terminal global index
     33// - FBDMA      : DMA channel global index
     34// - NIC        : NIC channel global index
     35// - TIMER  : Timer global index
     36// - PTAB   : page table virtual base address
     37// - LTID       : Task local index (in scheduler)
     38// - VSID   : Virtual space index
     39// - RUN        : Task state (0 => sleeping / 1 => runable )
    2640//
    27 // - It contains GPR[i], generally stored in slot (i). $0, *26 & $27 are not saved.
    28 // - It contains HI & LO registers.
    29 // - It contains CP0 registers: EPC, SR, CR, SCHED
    30 // - It contains CP2 registers : PTPR and MODE.
    31 // - It contains TTY global index, the FBDMA global index, the virtual base
    32 //   address of the page table (PTAB), and the task global index (TASK).
    33 //
    34 // ctx[0]<- SR|ctx[8] <- $8 |ctx[16]<- $16|ctx[24]<- $24|ctx[32]<- EPC |ctx[40]<- TTY
    35 // ctx[1]<- $1|ctx[9] <- $9 |ctx[17]<- $17|ctx[25]<- $25|ctx[33]<- CR  |ctx[41]<- FBDMA
    36 // ctx[2]<- $2|ctx[10]<- $10|ctx[18]<- $18|ctx[26]<- LO |ctx[34]<- *** |ctx[42]<- PTAB
    37 // ctx[3]<- $3|ctx[11]<- $11|ctx[19]<- $19|ctx[27]<- HI |ctx[35]<- PTPR|ctx[43]<- TASK
    38 // ctx[4]<- $4|ctx[12]<- $12|ctx[20]<- $20|ctx[28]<- $28|ctx[36]<- MODE|ctx[44]<- SCHED
    39 // ctx[5]<- $5|ctx[13]<- $13|ctx[21]<- $21|ctx[29]<- SP |ctx[37]<- *** |ctx[45]<- TIMER
    40 // ctx[6]<- $6|ctx[14]<- $14|ctx[22]<- $22|ctx[30]<- $30|ctx[38]<- *** |ctx[46]<- ***
    41 // ctx[7]<- $7|ctx[15]<- $15|ctx[23]<- $23|ctx[31]<- RA |ctx[39]<- *** |ctx[47]<- ***
    42 ////////////////////////////////////////////////////////////////////////////////////////
     41// ctx[0]<- ***|ctx[8] <- $8 |ctx[16]<- $16|ctx[24]<- $24|ctx[32]<- EPC  |ctx[40]<- TTY
     42// ctx[1]<- $1 |ctx[9] <- $9 |ctx[17]<- $17|ctx[25]<- $25|ctx[33]<- CR   |ctx[41]<- FBDMA
     43// ctx[2]<- $2 |ctx[10]<- $10|ctx[18]<- $18|ctx[26]<- LO |ctx[34]<- SR   |ctx[42]<- NIC
     44// ctx[3]<- $3 |ctx[11]<- $11|ctx[19]<- $19|ctx[27]<- HI |ctx[35]<- BVAR |ctx[43]<- TIMER
     45// ctx[4]<- $4 |ctx[12]<- $12|ctx[20]<- $20|ctx[28]<- $28|ctx[36]<- ***  |ctx[44]<- PTAB
     46// ctx[5]<- $5 |ctx[13]<- $13|ctx[21]<- $21|ctx[29]<- SP |ctx[37]<- ***  |ctx[45]<- LTID
     47// ctx[6]<- $6 |ctx[14]<- $14|ctx[22]<- $22|ctx[30]<- $30|ctx[38]<- ***  |ctx[46]<- VSID
     48// ctx[7]<- $7 |ctx[15]<- $15|ctx[23]<- $23|ctx[31]<- RA |ctx[39]<- PTPR |ctx[47]<- RUN
     49//////////////////////////////////////////////////////////////////////////////////////////
    4350
    4451extern void _task_switch(unsigned int*, unsigned int*);
     
    4754//      _ctx_switch()
    4855// This function performs a context switch between the running task
    49 // and  another task, using a round-robin sheduling policy.
     56// and  another task, using a round-robin sheduling policy between all
     57// tasks allocated to a given processor (static allocation).
     58// It selects the next runable task to resume execution.
     59// If the only runable task is the current task, return without context switch.
     60// If there is no runable task, the scheduler switch to the default "idle" task.
    5061//
    51 // It desactivate the DTLB, to directly access the scheduler using
    52 // the physical address stored in register CP0_SCHED.
    53 // All the context switch procedure is executed with interrupts masked.
    54 //
    55 // The return address contained in $31 is saved in the current task context
    56 // (in the ctx[31] slot), and the function actually returns to the address
    57 // contained in the ctx[31] slot of the next task context.
     62// Implementation notes:
     63// - As we only have the scheduler physical address (in CP0_SCHED register),
     64//   this function must use specific assess functions to access the scheduler.
     65// - All the context switch procedure is executed with interrupts masked.
     66// - The return address contained in $31 is saved in the current task context
     67//   (in the ctx[31] slot), and the function actually returns to the address
     68//   contained in the ctx[31] slot of the next task context.
    5869/////////////////////////////////////////////////////////////////////////////////
    5970void _ctx_switch()
    6071{
    61     unsigned int                        tasks;
    62     unsigned int                        curr_task_id;
    63     unsigned int                        next_task_id;
    64     unsigned int                        *curr_ctx_paddr;
    65     unsigned int                        *next_ctx_paddr;
    66 
    6772    // get scheduler physical address
    6873    static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
    6974
    7075    // get number of tasks allocated to scheduler
    71     tasks = _get_tasks_number();
     76    unsigned int        tasks = _get_tasks_number();
    7277
    73     // no switch if only one task
    74     if ( tasks > 1)
     78    // get current task index
     79    unsigned int        curr_task_id = _get_current_task_id();
     80
     81    // select the next task using a round-robin policy
     82    unsigned int        next_task_id;
     83    unsigned int        tid;
     84    unsigned int        found = 0;
     85
     86    for ( tid = curr_task_id + 1 ;
     87          tid < curr_task_id + 1 + tasks ;
     88          tid++ )
    7589    {
    76         // compute the context physical address for the current task
    77         curr_task_id = _get_current_task_id();
    78         curr_ctx_paddr = &(psched->context[curr_task_id][0]);
    79    
    80         // select the next task using a round-robin policy
    81         next_task_id = (curr_task_id + 1) % tasks;
    82    
    83         // compute the context physical address for the next task
    84         next_ctx_paddr = &(psched->context[next_task_id][0]);
     90        next_task_id = tid % tasks;
    8591
    86         // update the scheduler state
     92        // test if the task is runable
     93        if ( _get_context_slot( next_task_id, CTX_RUN_ID ) )   
     94        {
     95            found = 1;
     96                break;
     97        }
     98    }
     99
     100    // launch "idle" task if no runable task
     101    if ( found == 0 )
     102    {
     103        next_task_id = IDLE_TASK_INDEX;
     104    }
     105
     106    // no switch if no change
     107    if ( curr_task_id != next_task_id )
     108    {
     109        unsigned int*   curr_ctx_paddr = &(psched->context[curr_task_id][0]);
     110        unsigned int*   next_ctx_paddr = &(psched->context[next_task_id][0]);
     111
    87112        _set_current_task_id( next_task_id );
     113        _task_switch( curr_ctx_paddr, next_ctx_paddr );
    88114
    89115#if GIET_DEBUG_SWITCH
    90116_get_lock( &_tty_put_lock );
    91 _puts( "\n[GIET] Context switch for processor ");
    92 _putw( _procid() );
     117_puts( "\n[GIET DEBUG] Context switch for processor ");
     118_putd( _procid() );
    93119_puts( " at cycle ");
    94 _putw( _proctime() );
     120_putd( _proctime() );
    95121_puts("\n");
    96122_puts( " - tasks        = ");
    97 _putw( tasks );
     123_putd( tasks );
    98124_puts("\n");
    99125_puts( " - curr_task_id = ");
    100 _putw( curr_task_id );
     126_putd( curr_task_id );
    101127_puts("\n");
    102128_puts( " - next_task_id = ");
    103 _putw( next_task_id );
     129_putd( next_task_id );
    104130_puts("\n");
    105131_release_lock( &_tty_put_lock );
    106132#endif
    107133
    108         // makes the task switch
    109         _task_switch( curr_ctx_paddr, next_ctx_paddr );
     134    }
     135} //end _ctx_switch()
    110136
    111 /*
    112         asm volatile( "ori              $27,    $0,             0xB     \n"
    113                       "mtc2             $27,    $1                      \n"             // desactivate DTLB
     137/////////////////////////////////////////////////////////////////////////////////////
     138// This function is executed as the"idle" task when no other task can be executed
     139/////////////////////////////////////////////////////////////////////////////////////
     140void _ctx_idle()
     141{
     142    unsigned int delay = 1000000;
    114143
    115                       "add      $27,    %0,     $0  \n"         // $27 <= &curr_ctx
     144    while(1)
     145    {
     146        asm volatile("move  $3,   %0            \n"
     147                     "loop:                                     \n"
     148                     "addi      $3, $3, -1              \n"
     149                     "bnez  $3, loop            \n"
     150                     "nop                                       \n"
     151                     :
     152                     : "r"(delay)
     153                     : "$3" );
    116154
    117                       "mfc0     $26,    $12         \n"         // $26 <= SR
    118                       "sw       $26,    0*4($27)    \n"         // ctx[0] <= SR
    119                       ".set noat                    \n"
    120                       "sw       $1,     1*4($27)    \n"         // ctx[1] <= $1
    121                       ".set at                      \n"
    122                       "sw       $2,     2*4($27)    \n"         // ctx[2] <= $2
    123                       "sw       $3,     3*4($27)    \n"         // ctx[3] <= $3
    124                       "sw       $4,     4*4($27)    \n"         // ctx[4] <= $4
    125                       "sw       $5,     5*4($27)    \n"         // ctx[5] <= $5
    126                       "sw       $6,     6*4($27)    \n"         // ctx[6] <= $6
    127                       "sw       $7,     7*4($27)    \n"         // ctx[7] <= $7
    128                       "sw       $8,     8*4($27)    \n"         // ctx[8] <= $8
    129                       "sw       $9,     9*4($27)    \n"         // ctx[9] <= $9
    130                       "sw       $10,    10*4($27)   \n"         // ctx[10] <= $10
    131                       "sw       $11,    11*4($27)   \n"         // ctx[11] <= $11
    132                       "sw       $12,    12*4($27)   \n"         // ctx[12] <= $12
    133                       "sw       $13,    13*4($27)   \n"         // ctx[13] <= $13
    134                       "sw       $14,    14*4($27)   \n"         // ctx[14] <= $14
    135                       "sw       $15,    15*4($27)   \n"         // ctx[15] <= $15
    136                       "sw       $16,    16*4($27)   \n"         // ctx[16] <= $16
    137                       "sw       $17,    17*4($27)   \n"         // ctx[17] <= $17
    138                       "sw       $18,    18*4($27)   \n"         // ctx[18] <= $18
    139                       "sw       $19,    19*4($27)   \n"         // ctx[19] <= $19
    140                       "sw       $20,    20*4($27)   \n"         // ctx[20] <= $20
    141                       "sw       $21,    21*4($27)   \n"         // ctx[21] <= $21
    142                       "sw       $22,    22*4($27)   \n"         // ctx[22] <= $22
    143                       "sw       $23,    23*4($27)   \n"         // ctx[23] <= $23
    144                       "sw       $24,    24*4($27)   \n"         // ctx[24] <= $24
    145                       "sw       $25,    25*4($27)   \n"         // ctx[25] <= $25
    146                       "mflo     $26                 \n"
    147                       "sw       $26,    26*4($27)   \n"         // ctx[26] <= LO
    148                       "mfhi     $26                 \n"
    149                       "sw       $26,    27*4($27)   \n"         // ctx[27] <= H1
    150                       "sw       $28,    28*4($27)   \n"         // ctx[28] <= $28
    151                       "sw       $29,    29*4($27)   \n"         // ctx[29] <= $29
    152                       "sw       $30,    30*4($27)   \n"         // ctx[30] <= $30
    153                       "sw       $31,    31*4($27)   \n"         // ctx[31] <= $31
    154                       "mfc0     $26,    $14         \n"
    155                       "sw       $26,    32*4($27)   \n"         // ctx[32] <= EPC
    156                       "mfc0     $26,    $13         \n"
    157                       "sw       $26,    33*4($27)   \n"         // ctx[33] <= CR
    158                       "mfc2     $26,    $0          \n"
    159                       "sw       $26,    35*4($27)   \n"         // ctx[35] <= PTPR
     155        _get_lock( &_tty_put_lock );
     156        _puts( "\n[GIET WARNING] Processor ");
     157        _putd( _procid() );
     158        _puts( " still idle at cycle ");
     159        _putd( _proctime() );
     160        _puts("\n");
     161        _release_lock( &_tty_put_lock );
     162   
     163    }
     164} // end ctx_idle()
    160165
    161                       "add      $27,    %1,     $0      \n"             // $27<= &next_ctx
     166/////////////////////////////////////////////////////////////////////////////////
     167// The address of this functionis used to initialise the return address
     168// in the "idle" task context.
     169/////////////////////////////////////////////////////////////////////////////////
     170void _ctx_eret()
     171{
     172    asm volatile("eret");
     173}
    162174
    163                       "lw       $26,    35*4($27)       \n"
    164                       "mtc2     $26,    $0          \n"         // restore PTPR
    165                       "lw       $26,    0*4($27)        \n"
    166                       "mtc0     $26,    $12                     \n"             // restore SR
    167                       ".set noat                    \n"
    168                       "lw       $1,     1*4($27)        \n"             // restore $1
    169                       ".set at                      \n"
    170                           "lw       $2,     2*4($27)    \n"             // restore $2
    171                       "lw       $3,     3*4($27)    \n"         // restore $3
    172                       "lw       $4,     4*4($27)    \n"         // restore $4
    173                       "lw       $5,     5*4($27)    \n"         // restore $5
    174                       "lw       $6,     6*4($27)    \n"         // restore $6
    175                       "lw       $7,     7*4($27)    \n"         // restore $7
    176                       "lw       $8,     8*4($27)    \n"         // restore $8
    177                       "lw       $9,     9*4($27)    \n"         // restore $9
    178                       "lw       $10,    10*4($27)   \n"         // restore $10
    179                       "lw       $11,    11*4($27)   \n"         // restore $11
    180                       "lw       $12,    12*4($27)   \n"         // restore $12
    181                       "lw       $13,    13*4($27)   \n"         // restore $13
    182                       "lw       $14,    14*4($27)   \n"         // restore $14
    183                       "lw       $15,    15*4($27)   \n"         // restore $15
    184                       "lw       $16,    16*4($27)   \n"         // restore $16
    185                       "lw       $17,    17*4($27)   \n"         // restore $17
    186                       "lw       $18,    18*4($27)   \n"         // restore $18
    187                       "lw       $19,    19*4($27)   \n"         // restore $19
    188                       "lw       $20,    20*4($27)   \n"         // restore $20
    189                       "lw       $21,    21*4($27)   \n"         // restore $21
    190                       "lw       $22,    22*4($27)   \n"         // restore $22
    191                       "lw       $23,    23*4($27)   \n"         // restore $23
    192                       "lw       $24,    24*4($27)   \n"         // restore $24
    193                       "lw       $25,    25*4($27)   \n"         // restore $25
    194                       "lw       $26,    26*4($27)   \n"
    195                       "mtlo     $26                 \n"         // restore LO
    196                       "lw       $26,    27*4($27)   \n"
    197                       "mthi     $26                 \n"         // restore HI
    198                       "lw       $28,    28*4($27)   \n"         // restore $28
    199                       "lw       $29,    29*4($27)   \n"         // restore $29
    200                       "lw       $30,    30*4($27)   \n"         // restore $30
    201                       "lw       $31,    31*4($27)   \n"         // restore $31
    202                       "lw       $26,    32*4($27)   \n"
    203                       "mtc0     $26,    $14         \n"         // restore EPC
    204                       "lw       $26,    33*4($27)   \n"
    205                       "mtc0     $26,    $13         \n"         // restore CR
    206175
    207                       "ori              $27,    $0,             0xF \n"
    208                       "mtc2             $27,    $1          \n"         // activate DTLB
    209                       :
    210                       : "r"(curr_ctx_paddr), "r"(next_ctx_paddr)
    211                       : "$1" ,            "$4" ,"$5" ,"$6" ,"$7" ,"$8" ,"$9" ,"$10",
    212                         "$11","$12","$13","$14","$15","$16","$17","$18","$19","$20",
    213                         "$21","$22","$23","$24","$25","$26","$27",      "$29",
    214                         "$31" );
    215 */
    216     }
    217 } // end _ctx_switch
    218 
  • soft/giet_vm/sys/ctx_handler.h

    r189 r199  
    1616} static_scheduler_t;
    1717
     18
     19/////////////////////////////////////////////////////////////////////////////////
     20//  "idle" task index definition
     21/////////////////////////////////////////////////////////////////////////////////
     22
     23#define IDLE_TASK_INDEX         14
     24
    1825/////////////////////////////////////////////////////////////////////////////////
    1926//      Definition of the task context slots indexes
    2027/////////////////////////////////////////////////////////////////////////////////
    2128
    22 #define CTX_SR_ID               0
    2329#define CTX_SP_ID               29
    2430#define CTX_RA_ID               31
     
    2632#define CTX_EPC_ID              32
    2733#define CTX_CR_ID               33
    28 #define CTX_PTPR_ID             35
    29 #define CTX_MODE_ID             36
     34#define CTX_SR_ID               34
     35#define CTX_BVAR_ID             35
     36
     37#define CTX_PTPR_ID             39
    3038
    3139#define CTX_TTY_ID              40
    3240#define CTX_FBDMA_ID    41
    33 #define CTX_PTAB_ID             42
    34 #define CTX_TASK_ID             43
    35 #define CTX_SCHED_ID    44
    36 #define CTX_TIMER_ID    45
     41#define CTX_NIC_ID              42
     42#define CTX_TIMER_ID    43
     43#define CTX_PTAB_ID             44
     44#define CTX_LTID_ID             45
     45#define CTX_VSID_ID             46
     46#define CTX_RUN_ID              47
    3747
    3848//////////////////////////////////////////////////////////////////////////////////
     
    4151
    4252extern void _ctx_switch();
     53extern void _ctx_eret();
     54extern void _ctx_idle();
    4355
    4456extern static_scheduler_t _scheduler[];
  • soft/giet_vm/sys/drivers.c

    r189 r199  
    162162{
    163163    unsigned int buffer     = value;
    164     unsigned int timer_id   = _get_current_context_slot(CTX_TIMER_ID);
     164    unsigned int task_id    = _get_current_task_id();
     165    unsigned int timer_id   = _get_context_slot(task_id, CTX_TIMER_ID);
    165166    unsigned int cluster_id = timer_id / (NB_PROCS_MAX + NB_TIMERS_MAX);
    166167    unsigned int local_id   = timer_id % (NB_PROCS_MAX + NB_TIMERS_MAX);
     
    190191                          unsigned int* buffer )
    191192{
    192     unsigned int timer_id   = _get_current_context_slot(CTX_TIMER_ID);
     193    unsigned int task_id    = _get_current_task_id();
     194    unsigned int timer_id   = _get_context_slot(task_id, CTX_TIMER_ID);
    193195    unsigned int cluster_id = timer_id / (NB_PROCS_MAX + NB_TIMERS_MAX);
    194196    unsigned int local_id   = timer_id % (NB_PROCS_MAX + NB_TIMERS_MAX);
     
    232234//      _tty_error()
    233235////////////////////////////////////////////////////////////////////////////////
    234 void _tty_error()
    235 {
    236     unsigned int task_id = _get_current_task_id();
     236void _tty_error( unsigned int task_id )
     237{
    237238    unsigned int proc_id = _procid();
    238239
     
    259260    unsigned int        nwritten;
    260261
    261     unsigned int        tty_id = _get_current_context_slot(CTX_TTY_ID);
     262    unsigned int task_id  = _get_current_task_id();
     263    unsigned int tty_id   = _get_context_slot(task_id, CTX_TTY_ID);
     264
    262265    if ( tty_id >= NB_TTYS )
    263266    {
    264         _tty_error();
     267        _tty_error( task_id );
    265268        return 0;
    266269    }
     
    291294                            unsigned int        length)
    292295{
    293     unsigned int        tty_id = _get_current_context_slot(CTX_TTY_ID);
     296    unsigned int task_id  = _get_current_task_id();
     297    unsigned int tty_id   = _get_context_slot(task_id, CTX_TTY_ID);
    294298
    295299    if ( tty_id >= NB_TTYS )
    296300    {
    297         _tty_error();
     301        _tty_error( task_id );
    298302        return 0;
    299303    }
     
    320324                        unsigned int    length)
    321325{
    322     unsigned int        tty_id = _get_current_context_slot(CTX_TTY_ID);
     326    unsigned int task_id  = _get_current_task_id();
     327    unsigned int tty_id   = _get_context_slot(task_id, CTX_TTY_ID);
     328
    323329    if ( tty_id >= NB_TTYS )
    324330    {
    325         _tty_error();
     331        _tty_error( task_id );
    326332        return 0;
    327333    }
     
    544550
    545551    // get user space page table virtual address
    546     unsigned int user_pt_vbase = _get_current_context_slot(CTX_PTAB_ID);
     552    unsigned int task_id       = _get_current_task_id();
     553    unsigned int user_pt_vbase = _get_context_slot( task_id, CTX_PTAB_ID );
    547554   
    548555    user_vpn_min = user_vaddr >> 12;
     
    815822
    816823    // get DMA channel and compute DMA vbase address
    817     unsigned int        dma_id     = _get_current_context_slot(CTX_FBDMA_ID);
     824    unsigned int        task_id    = _get_current_task_id();
     825    unsigned int        dma_id     = _get_context_slot( task_id, CTX_FBDMA_ID );
    818826    unsigned int    cluster_id = dma_id / NB_DMAS_MAX;
    819827    unsigned int    loc_id     = dma_id % NB_DMAS_MAX;
     
    830838
    831839    // get user space page table virtual address
    832     unsigned int        user_ptab = _get_current_context_slot(CTX_PTAB_ID);
     840    unsigned int        user_ptab = _get_context_slot( task_id, CTX_PTAB_ID );
    833841
    834842    // compute frame buffer pbase address
     
    985993unsigned int _fb_completed()
    986994{
    987     unsigned int dma_id = _get_current_context_slot(CTX_FBDMA_ID);
     995    unsigned int task_id = _get_current_task_id();
     996    unsigned int dma_id  = _get_context_slot( task_id, CTX_FBDMA_ID );
    988997
    989998    // busy waiting with a pseudo random delay between bus access
  • soft/giet_vm/sys/exc_handler.c

    r189 r199  
    1010
    1111#include <exc_handler.h>
     12#include <ctx_handler.h>
    1213#include <sys_handler.h>
    1314#include <drivers.h>
     
    5354};
    5455
    55 static const char *exc_message_causes[] = {
    56     "\n\nException : strange unknown cause\n",
    57     "\n\nException : illegal read address \n",
    58     "\n\nException : illegal write address\n",
    59     "\n\nException : inst bus error       \n",
    60     "\n\nException : data bus error       \n",
    61     "\n\nException : breakpoint           \n",
    62     "\n\nException : reserved instruction \n",
    63     "\n\nException : illegal coproc access\n"
    64     "\n\nException : arithmetic overflow  \n",
     56static const char* exc_type[] = {
     57    "strange unknown cause",
     58    "illegal read address",
     59    "illegal write address",
     60    "inst bus error",
     61    "data bus error",
     62    "breakpoint",
     63    "reserved instruction",
     64    "illegal coproc access"
     65    "arithmetic overflow",
    6566};
    6667
    67 static void _cause(unsigned int msg_cause)
     68static void _display_cause(unsigned int type)
    6869{
    69     _puts( (char*)(exc_message_causes[msg_cause]) );
    70     _puts("\n - Cycle     : ");
     70    _puts("\n[GIET] Exception for task ");
     71    _putd( _get_current_task_id() );
     72    _puts(" on processor ");
     73    _putd( _procid() );
     74    _puts(" at cycle ");
    7175    _putd( _proctime() );
    72     _puts("\n - Processor : ");
    73     _putd( _procid() );
    74     _puts("\n - Task      : ");
    75     _putd( _get_current_task_id() );
     76    _puts("\n - type      : ");
     77    _puts( (char*)exc_type[type] );
    7678    _puts("\n - EPC       : ");
    7779    _putw( _get_epc() );
     
    7981    _putw( _get_bvar() );
    8082    _puts("\n");
    81     _exit();
     83
     84    // goes to sleeping state
     85    unsigned int task_id = _get_current_task_id();
     86    _set_context_slot( task_id, CTX_RUN_ID, 0 );
     87   
     88    // deschedule
     89    _ctx_switch();
    8290}
    8391
    84 static void _cause_ukn()  { _cause(0); }
    85 static void _cause_adel() { _cause(1); }
    86 static void _cause_ades() { _cause(2); }
    87 static void _cause_ibe()  { _cause(3); }
    88 static void _cause_dbe()  { _cause(4); }
    89 static void _cause_bp()   { _cause(5); }
    90 static void _cause_ri()   { _cause(6); }
    91 static void _cause_cpu()  { _cause(7); }
    92 static void _cause_ovf()  { _cause(8); }
     92static void _cause_ukn()  { _display_cause(0); }
     93static void _cause_adel() { _display_cause(1); }
     94static void _cause_ades() { _display_cause(2); }
     95static void _cause_ibe()  { _display_cause(3); }
     96static void _cause_dbe()  { _display_cause(4); }
     97static void _cause_bp()   { _display_cause(5); }
     98static void _cause_ri()   { _display_cause(6); }
     99static void _cause_cpu()  { _display_cause(7); }
     100static void _cause_ovf()  { _display_cause(8); }
    93101
  • soft/giet_vm/sys/kernel_init.c

    r189 r199  
    88// It contains the kernel entry point for the last step of system initialisation.
    99// All procs in this phase have their MMU activated, and are running in parallel.
    10 // - each processor updates its own scheduler, to replace the ISR index
    11 //   by the actual ISR virtual address, and set its own entry in the
    12 //   kernel _schedulers_paddr[] array.
    13 // - each processor initialises the SP, SR, PTPR, EPC registers, and starts
    14 //   its private Timer, before jumping to the user code with an eret.
     10// Each processor perform the following actions:
     11// 1/ contributes to _schedulers_paddr[] initialisation
     12// 2/ contributes to _ptabs_paddr[] and _ptabs_vaddr arrays initialisation
     13// 3/ computes and set the ICU mask for its private ICU channel
     14// 4/ initialises its private TICK timer (if required)
     15// 5/ initialises the "idle" task context in its private scheduler
     16// 6/ initialises the SP, SR, PTPR, EPC registers
     17// 7/ jumps to the user code with an eret.
    1518////////////////////////////////////////////////////////////////////////////////////
    1619
     
    3437
    3538__attribute__((section (".kdata")))
    36 page_table_t* _ptabs_paddr[GIET_NB_VSPACE_MAX];
    37 
    38 __attribute__((section (".kdata")))
    39 page_table_t* _ptabs_vaddr[GIET_NB_VSPACE_MAX];
    40 
    41 __attribute__((section (".kdata")))
    42 static_scheduler_t*     _schedulers_paddr[NB_CLUSTERS*NB_PROCS_MAX];
     39unsigned int                    _ptabs_paddr[GIET_NB_VSPACE_MAX];
     40
     41__attribute__((section (".kdata")))
     42unsigned int                    _ptabs_vaddr[GIET_NB_VSPACE_MAX];
     43
     44__attribute__((section (".kdata")))
     45static_scheduler_t*             _schedulers_paddr[NB_CLUSTERS*NB_PROCS_MAX];
     46
     47__attribute__((section (".kdata")))
     48unsigned int                    _idle_stack[NB_CLUSTERS*NB_PROCS_MAX*64];
    4349
    4450//////////////////////////////////////////////////////////////////////////////////
     
    4753__attribute__((section (".kinit"))) void _kernel_init()
    4854{
    49     // values to be written in registers
    50     unsigned int        sp_value;
    51     unsigned int        sr_value;
    52     unsigned int        ptpr_value;
    53     unsigned int        epc_value;
    54 
     55    // compute cluster and local processor index
    5556    unsigned int        proc_id    = _procid();
    5657    unsigned int    cluster_id = proc_id / NB_PROCS_MAX;
     
    6667_get_lock(&_tty_put_lock);
    6768_puts("\n[GIET DEBUG] step 1 for processor ");
    68 _putw( proc_id );
    69 _puts("\n");
    70 _puts("- scheduler pbase = ");
     69_putd( proc_id );
     70_puts(" / scheduler pbase = ");
    7171_putw( (unsigned int)psched );
    7272_puts("\n");
     
    7474#endif
    7575
    76     // step 2 : compute and set ICU mask
     76
     77    // step 2 : initialise page table addresse arrays
     78    //          it scans all tasks contexts in the scheduler
     79    //          and get VSID, PTAB and PTPR values
     80
     81    unsigned int ltid;
     82    unsigned int tasks = _get_tasks_number();
     83
     84    for ( ltid = 0 ; ltid < tasks ; ltid++ )
     85    {
     86        unsigned int vspace_id  = _get_context_slot( ltid , CTX_VSID_ID );
     87        unsigned int ptab_vaddr = _get_context_slot( ltid , CTX_PTAB_ID );
     88        unsigned int ptab_paddr = _get_context_slot( ltid , CTX_PTPR_ID ) << 13;
     89        _ptabs_vaddr[vspace_id] = ptab_vaddr;
     90        _ptabs_paddr[vspace_id] = ptab_paddr;
     91
     92#if GIET_DEBUG_INIT
     93_get_lock(&_tty_put_lock);
     94_puts("\n[GIET DEBUG] step 2 for processor ");
     95_putd( proc_id );
     96_puts(" / vspace ");
     97_putd( vspace_id );
     98_puts("\n- ptab vbase = ");
     99_putw( ptab_vaddr );
     100_puts("\n- ptab pbase = ");
     101_putw( ptab_paddr );
     102_puts("\n");
     103_release_lock(&_tty_put_lock);
     104#endif
     105
     106    }
     107 
     108    // step 3 : compute and set ICU mask
    77109    unsigned int irq_id;
    78110    unsigned int mask = 0;
     
    89121#if GIET_DEBUG_INIT
    90122_get_lock(&_tty_put_lock);
    91 _puts("\n[GIET DEBUG] step 2 for processor ");
    92 _putw( proc_id );
    93 _puts("\n");
    94 _puts("- ICU mask = ");
     123_puts("\n[GIET DEBUG] step 3 for processor ");
     124_putd( proc_id );
     125_puts(" / ICU mask = ");
    95126_putw( mask );
    96127_puts("\n");
     
    99130
    100131
    101     // step 3 : TODO initialise page table addresse arrays
    102 
    103 
    104132    // step 4 : start TICK timer if more than one task
    105     unsigned int tasks = _get_tasks_number();
    106133    if ( tasks > 1 )
    107134    {
     
    122149_get_lock(&_tty_put_lock);
    123150_puts("\n[GIET DEBUG] Step 4 for processor ");
    124 _putw( proc_id );
    125 _puts("\n");
    126 _puts("- TICK period = ");
    127 _putd( period );
    128 _puts("\n");
     151_putd( proc_id );
     152_puts(" / TICK activated\n");
    129153_release_lock(&_tty_put_lock);
    130154#endif
     
    132156    }
    133157
    134     // step 5 : each processor initialises SP, SR, PTPR, EPC, registers
     158    // step 5 : initialise the "idle" task context
     159    //          the SR initialisation value is 0xFF03 because
     160    //          the task _ctx_idle() executes in kernel mode...
     161    //          it uses the page table of vspace[0]
     162 
     163    _set_context_slot( IDLE_TASK_INDEX, CTX_RUN_ID,  1 );
     164    _set_context_slot( IDLE_TASK_INDEX, CTX_SR_ID,   0xFF03 );
     165    _set_context_slot( IDLE_TASK_INDEX, CTX_SP_ID,   (unsigned int)&_idle_stack[proc_id] + 64 );
     166    _set_context_slot( IDLE_TASK_INDEX, CTX_RA_ID,   (unsigned int)&_ctx_eret );
     167    _set_context_slot( IDLE_TASK_INDEX, CTX_EPC_ID,  (unsigned int)&_ctx_idle );
     168    _set_context_slot( IDLE_TASK_INDEX, CTX_LTID_ID, IDLE_TASK_INDEX );
     169    _set_context_slot( IDLE_TASK_INDEX, CTX_PTPR_ID, _ptabs_paddr[0] >> 13 );
     170
     171#if GIET_DEBUG_INIT
     172_get_lock(&_tty_put_lock);
     173_puts("\n[GIET DEBUG] Step 5 for processor ");
     174_putd( proc_id );
     175_puts(" / idle task context set\n");
     176_release_lock(&_tty_put_lock);
     177#endif
     178   
     179    // step 6 : each processor initialises SP, SR, PTPR, EPC, registers
    135180    //          with the values corresponding to the first allocated task,
    136     //          It does nothing, and keep idle if no task allocated.
    137 
    138     if ( tasks )                // at leat one task allocated
    139     {
    140         // initialise registers
    141         sp_value   = _get_current_context_slot(CTX_SP_ID);
    142         sr_value   = _get_current_context_slot(CTX_SR_ID);
    143         ptpr_value = _get_current_context_slot(CTX_PTPR_ID);
    144         epc_value  = _get_current_context_slot(CTX_EPC_ID);
    145 
    146 #if GIET_DEBUG_INIT
    147 _get_lock(&_tty_put_lock);
    148 _puts("\n[GIET DEBUG] step 5 for processor ");
    149 _putw( proc_id );
    150 _puts("\n");
     181    //          and starts the "idle" task if there is no task allocated.
     182
     183    unsigned int task_id;
     184
     185    if ( tasks == 0 )
     186    {
     187        task_id = IDLE_TASK_INDEX;
     188
     189        _get_lock( &_tty_put_lock );
     190        _puts("\n [GIET WARNING] No task allocated to processor ");
     191        _putw( proc_id );
     192        _puts(" => idle\n");
     193        _release_lock ( &_tty_put_lock );
     194    }
     195    else
     196    {
     197        task_id = 0;
     198    }
     199       
     200    unsigned int    sp_value   = _get_context_slot( task_id, CTX_SP_ID );
     201    unsigned int    sr_value   = _get_context_slot( task_id, CTX_SR_ID );
     202    unsigned int    ptpr_value = _get_context_slot( task_id, CTX_PTPR_ID );
     203    unsigned int    epc_value  = _get_context_slot( task_id, CTX_EPC_ID );
     204
     205#if GIET_DEBUG_INIT
     206_get_lock(&_tty_put_lock);
     207_puts("\n[GIET DEBUG] step 6 for processor ");
     208_putd( proc_id );
     209_puts(" / registers initialised \n");
    151210_puts("- sp   = ");
    152211_putw( sp_value );
     
    163222_release_lock(&_tty_put_lock);
    164223#endif
    165     }
    166     else                                        // no task allocated
    167     {
    168         _get_lock( &_tty_put_lock );
    169         _puts("\n No task allocated to processor ");
    170         _putw( proc_id );
    171         _puts(" => keep idle\n");
    172         _release_lock ( &_tty_put_lock );
    173 
    174         // enable interrupts in kernel mode
    175         asm volatile ( "li         $26, 0xFF01  \n"
    176                        "mtc0   $26, $12     \n"
    177                        ::: "$26" );
    178 
    179                 // infinite loop in kernel mode
    180         while (1) asm volatile("nop");
    181     }
    182 
    183     // set critical registers and jump to user code
    184     asm volatile (
    185        "move    $29,    %0              \n"             /* SP <= ctx[CTX_SP_ID] */
    186        "mtc0    %1,             $12             \n"             /* SR <= ctx[CTX_SR_ID] */
    187        "mtc2    %2,             $0              \n"             /* PTPR <= ctx[CTX_PTPR_ID] */
    188        "mtc0    %3,             $14             \n"             /* EPC <= ctx[CTX_EPC_ID] */
    189        "eret                                    \n"             /* jump to user code */
    190        "nop                                             \n"
    191        :
    192        : "r"(sp_value), "r"(sr_value), "r"(ptpr_value), "r"(epc_value) );
     224
     225    // set  registers and jump to user code
     226    asm volatile ( "move        $29,    %0              \n"             /* SP <= ctx[CTX_SP_ID] */
     227                   "mtc0        %1,             $12             \n"             /* SR <= ctx[CTX_SR_ID] */
     228                   "mtc2        %2,             $0              \n"             /* PTPR <= ctx[CTX_PTPR_ID] */
     229                   "mtc0        %3,             $14             \n"             /* EPC <= ctx[CTX_EPC_ID] */
     230                   "eret                                        \n"             /* jump to user code */
     231                   "nop                                         \n"
     232                   :
     233                   : "r"(sp_value), "r"(sr_value), "r"(ptpr_value), "r"(epc_value) );
    193234
    194235} // end _kernel_init()
  • soft/giet_vm/sys/mips32_registers.h

    r189 r199  
    4747/* CP0 registers */
    4848
    49 #define CP0_BAR                 $8
     49#define CP0_BVAR                $8
    5050#define CP0_TIME                $9
    5151#define CP0_SR                  $12
  • soft/giet_vm/sys/switch.s

    r189 r199  
    22* This function receives two arguments that are the current task context
    33* physical addresses and the next task context physical address.
     4* The DTLB is temporary desactivated...
    45******************************************************************************/
    56
     
    1718    add     $27,    $4,     $0  /* $27 <= &context[curr_task_id] */
    1819
    19     mfc0    $26,    $12         /* $26 <= SR */
    20     sw      $26,    0*4($27)    /* ctx[0] <= SR */
    2120    .set noat
    2221    sw      $1,     1*4($27)    /* ctx[1] <= $1 */
     
    4746    sw      $25,    25*4($27)   /* ctx[25] <= $25 */
    4847    mflo    $26
    49     sw      $26,    26*4($27)   /* ctx[26] <= LO */
     48    sw      $26,    26*4($27)   /* ctx[26] <= LO  */
    5049    mfhi    $26
    51     sw      $26,    27*4($27)   /* ctx[27] <= H1 */
     50    sw      $26,    27*4($27)   /* ctx[27] <= H1  */
    5251    sw      $28,    28*4($27)   /* ctx[28] <= $28 */
    5352    sw      $29,    29*4($27)   /* ctx[29] <= $29 */
     
    5756    sw      $26,    32*4($27)   /* ctx[32] <= EPC */
    5857    mfc0    $26,    $13
    59     sw      $26,    33*4($27)   /* ctx[33] <= CR */
     58    sw      $26,    33*4($27)   /* ctx[33] <= CR  */
     59    mfc0    $26,    $12
     60    sw      $26,    34*4($27)   /* ctx[34] <= SR  */
     61    mfc0    $26,    $8
     62    sw      $26,    35*4($27)   /* ctx[34] <= BVAR */
    6063    mfc2    $26,    $0
    61     sw      $26,    35*4($27)   /* ctx[35] <= PTPR */
     64    sw      $26,    39*4($27)   /* ctx[35] <= PTPR */
    6265
    6366    /* restore next task context */
    6467    add     $27,    $5,     $0  /* $27<= &context[next_task_id] */
    6568
    66     lw      $26,    35*4($27)
    67     mtc2    $26,    $0          /* restore PTPR */
    68     lw      $26,    0*4($27)
    69     mtc0    $26,    $12         /* restore SR */
    7069    .set noat
    7170    lw      $1,     1*4($27)    /* restore $1 */
     
    107106    lw      $26,    33*4($27)
    108107    mtc0    $26,    $13         /* restore CR */
     108    lw      $26,    34*4($27)
     109    mtc0    $26,    $12         /* restore SR */
     110    lw      $26,    35*4($27)
     111    mtc0    $26,    $8          /* restore BVAR */
     112    lw      $26,    39*4($27)
     113    mtc2    $26,    $0          /* restore PTPR */
    109114
    110115    /* activate DTLB */
  • soft/giet_vm/sys/sys_handler.c

    r189 r199  
    7575void _exit()
    7676{
    77 /*
    7877    unsigned int date    = _proctime();
    79 
    8078    unsigned int proc_id = _procid();
    81 
    8279    unsigned int task_id = _get_current_task_id();
    8380
    8481     // print death message
    8582    _get_lock(&_tty_put_lock);
    86     _puts("\n\n!!! Exit task ");
    87     _putw( task_id );
     83    _puts("\n[GIET] Exit task ");
     84    _putd( task_id );
    8885    _puts(" on processor ");
    89     _putw( proc_id );
     86    _putd( proc_id );
    9087    _puts(" at cycle ");
    91     _putw( date );
     88    _putd( date );
    9289    _puts("\n\n");
    9390    _release_lock(&_tty_put_lock);
    94 */
    9591   
    96     /* infinite loop */
    97     while (1) asm volatile("nop");
     92    // goes to sleeping state
     93    _set_context_slot( task_id, CTX_RUN_ID, 0 );
     94   
     95    // deschedule
     96    _ctx_switch();
    9897}
    9998//////////////////////////////////////////////////////////////////////////////
Note: See TracChangeset for help on using the changeset viewer.