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.

File:
1 edited

Legend:

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