Changeset 238 for soft/giet_vm/sys


Ignore:
Timestamp:
May 29, 2013, 1:24:09 AM (11 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/sys
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/sys/common.c

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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