Ignore:
Timestamp:
Aug 14, 2013, 11:19:29 PM (11 years ago)
Author:
alain
Message:

1/ introducing support to display images on the frame buffer
with the vci_chbuf_dma (in stdio.c and drivers.c)
2/ introducing support for mem_cache configuration segment
as the memory cache is considered as another addressable peripheral type
(in drivers.c)
3/ Introducing the new "increment" parameter in the mapping header.
This parameter define the virtual address increment for the vsegs
associated to the replicated peripherals (ICU, XICU, MDMA, TIMER, MMC).
This parameter is mandatory, and all map.xml files the "mappings"
directory have been updated.

File:
1 edited

Legend:

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

    r249 r253  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The drivers.c and drivers.h files are part ot the GIET-VM nano kernel.
     7// The drivers.c and drivers.h files are part ot the GIET-VM kernel.
     8//
    89// They contains the drivers for the peripherals available in the SoCLib library:
    910// - vci_multi_tty
     
    1112// - vci_multi_dma
    1213// - vci_multi_icu
    13 // - vci_xicu & vci_multi_icu
     14// - vci_xicu
    1415// - vci_gcd
    1516// - vci_frame_buffer
    1617// - vci_block_device
    17 //
    18 // For the peripherals replicated in each cluster (ICU, TIMER, DMA),
     18// - vci_multi_nic
     19// - vci_chbuf_dma
     20//
     21// For the peripherals replicated in each cluster (ICU, TIMER, XCU, DMA, MMC),
    1922// the corresponding (virtual) base addresses must be completed by an offset
    2023// depending on the cluster index.
    21 //
    22 // The following global parameter must be defined in the giet_config.h file:
    23 // - GIET_CLUSTER_INCREMENT
    2424//
    2525// The following global parameters must be defined in the hard_config.h file:
     
    3232// The following virtual base addresses must be defined in the giet_vsegs.ld file:
    3333// - seg_icu_base
     34// - seg_xcu_base
    3435// - seg_tim_base
    3536// - seg_dma_base
     
    4243// - seg_iob_base
    4344// - seg_mmc_base
    44 //
     45// - vseg_cluster_increment
    4546///////////////////////////////////////////////////////////////////////////////////
    4647
     
    6869#if (NB_PROCS_MAX > 8)
    6970# error: NB_PROCS_MAX cannot be larger than 8!
    70 #endif
    71 
    72 #if !defined(GIET_CLUSTER_INCREMENT)
    73 # error: You must define GIET_CLUSTER_INCREMENT in the giet_config.h file
    7471#endif
    7572
     
    153150// The (virtual) base address of the associated segment is:
    154151//
    155 //       timer_address = seg_icu_base + cluster_id * GIET_CLUSTER_INCREMENT
    156 //
    157 // - cluster id is an explicit argument of all access functions
    158 // - seg_icu_base must be defined in the giet_vsegs.ld file
    159 // - GIET_CLUSTER_INCREMENT must be defined in the giet_config.h file
     152//       timer_address = seg_tim_base + cluster_id * vseg_cluster_increment
     153//   or  timer_address = seg_xcu_base + cluster_id * vseg_cluster_increment
     154//
    160155////////////////////////////////////////////////////////////////////////////////
    161156
     
    184179
    185180#if USE_XICU
    186     unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base +
    187                                                      (cluster_id * GIET_CLUSTER_INCREMENT));
     181    unsigned int* timer_address = (unsigned int *) ((unsigned int)&seg_xcu_base +
     182                                  (cluster_id * (unsigned int)&vseg_cluster_increment));
    188183
    189184    timer_address[XICU_REG(XICU_PTI_PER, local_id)] = period;
    190185#else
    191     unsigned int* timer_address = (unsigned int *) ((char *) &seg_tim_base +
    192                                                     (cluster_id * GIET_CLUSTER_INCREMENT));
     186    unsigned int* timer_address = (unsigned int *) ((unsigned int)&seg_tim_base +
     187                                  (cluster_id * (unsigned int)&vseg_cluster_increment));
    193188
    194189    timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period;
     
    212207
    213208#if USE_XICU
    214     unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base +
    215                                                      (cluster_id * GIET_CLUSTER_INCREMENT));
     209    unsigned int * timer_address = (unsigned int *) ((unsigned int)&seg_xcu_base +
     210                                   (cluster_id * (unsigned int)&vseg_cluster_increment));
    216211
    217212    timer_address[XICU_REG(XICU_PTI_PER, local_id)] = 0;
    218213#else
    219     unsigned int* timer_address = (unsigned int *) ((char *) &seg_tim_base +
    220                                                     (cluster_id * GIET_CLUSTER_INCREMENT));
     214    unsigned int* timer_address = (unsigned int *) ((unsigned int)&seg_tim_base +
     215                                  (cluster_id * (unsigned int)&vseg_cluster_increment));
    221216
    222217    timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0;
     
    224219    return 0;
    225220}
    226 
    227221
    228222//////////////////////////////////////////////////////////////////////////////
     
    242236
    243237#if USE_XICU
    244     unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base +
    245                                                      (cluster_id * GIET_CLUSTER_INCREMENT));
     238    unsigned int * timer_address = (unsigned int *) ((unsigned int)&seg_xcu_base +
     239                                   (cluster_id * (unsigned int)&vseg_cluster_increment));
    246240
    247241    unsigned int bloup = timer_address[XICU_REG(XICU_PTI_ACK, local_id)];
    248242    bloup++; // to avoid a warning
    249243#else
    250     unsigned int * timer_address = (unsigned int *) ((char *) &seg_tim_base +
    251             (cluster_id * GIET_CLUSTER_INCREMENT));
     244    unsigned int * timer_address = (unsigned int *) ((unsigned int)&seg_tim_base +
     245                                   (cluster_id * (unsigned int)&vseg_cluster_increment));
    252246
    253247    timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0;
     
    255249    return 0;
    256250}
    257 
    258 
    259251
    260252///////////////////////////////////////////////////////////////////////
     
    263255// This function resets the period at the end of which
    264256// an interrupt is sent. To do so, we re-write the period
    265 // ini the proper register, what causes the count to restart.
     257// in the proper register, what causes the count to restart.
    266258// The period value is read from the same (TIMER_PERIOD) register,
    267259// this is why in appearance we do nothing useful (read a value
     
    269261// This function is called during a context switch (user or preemptive)
    270262///////////////////////////////////////////////////////////////////////
    271 unsigned int _timer_reset_irq_cpt(unsigned int cluster_id, unsigned int local_id) {
     263unsigned int _timer_reset_irq_cpt( unsigned int cluster_id,
     264                                   unsigned int local_id) {
    272265    // parameters checking
    273266    if (cluster_id >= NB_CLUSTERS) {
     
    279272
    280273#if USE_XICU
    281     unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base + (cluster_id * GIET_CLUSTER_INCREMENT));
     274    unsigned int * timer_address = (unsigned int *) ((unsigned int) &seg_xcu_base +
     275                                   (cluster_id * (unsigned int)&vseg_cluster_increment));
     276
    282277    unsigned int timer_period = timer_address[XICU_REG(XICU_PTI_PER, local_id)];
    283278
    284     // we write 0 first because if the timer is currently running, the corresponding timer counter is not reset
     279    // we write 0 first because if the timer is currently running,
     280    //the corresponding timer counter is not reset
    285281    timer_address[XICU_REG(XICU_PTI_PER, local_id)] = 0;
    286282    timer_address[XICU_REG(XICU_PTI_PER, local_id)] = timer_period;
    287283#else
    288284    // We suppose that the TIMER_MODE register value is 0x3
    289     unsigned int * timer_address = (unsigned int *) ((char *) &seg_tim_base + (cluster_id * GIET_CLUSTER_INCREMENT));
     285    unsigned int * timer_address = (unsigned int *) ((unsigned int)&seg_tim_base +
     286                                   (cluster_id * (unsigned int)&vseg_cluster_increment));
     287
    290288    unsigned int timer_period = timer_address[local_id * TIMER_SPAN + TIMER_PERIOD];
    291289
     
    295293    return 0;
    296294}
    297 
    298295
    299296/////////////////////////////////////////////////////////////////////////////////
     
    412409// This hardware component is replicated in all clusters.
    413410// There is one vci_multi_icu (or vci_xicu) component per cluster,
    414 // and the number of independant ICUs is equal to NB_PROCS_MAX,
     411// and the number of ICU channels is equal to NB_PROCS_MAX,
    415412// because there is one private interrupt controler per processor.
    416413////////////////////////////////////////////////////////////////////////////////
    417414// The (virtual) base address of the associated segment is:
    418415//
    419 //       icu_address = seg_icu_base + cluster_id * GIET_CLUSTER_INCREMENT
    420 //
    421 // - cluster id is an explicit argument of all access functions
    422 // - seg_icu_base must be defined in the giet_vsegs.ld file
    423 // - GIET_CLUSTER_INCREMENT must be defined in the giet_config.h file
     416//       icu_address = seg_icu_base + cluster_id * vseg_cluster_increment
     417//  or   icu_address = seg_xcu_base + cluster_id * vseg_cluster_increment
     418//
    424419////////////////////////////////////////////////////////////////////////////////
    425420
     
    434429                            unsigned int proc_id,
    435430                            unsigned int value,
    436                             unsigned int is_timer)
     431                            unsigned int is_PTI)
    437432{
    438433    // parameters checking
     
    440435    if (proc_id >= NB_PROCS_MAX)   return 1;
    441436
    442     unsigned int * icu_address = (unsigned int *) ((char *) &seg_icu_base +
    443                                                    (cluster_id * GIET_CLUSTER_INCREMENT));
    444437#if USE_XICU
    445     if (is_timer)
     438    unsigned int * icu_address = (unsigned int *) ((unsigned int)&seg_xcu_base +
     439                                 (cluster_id * (unsigned int)&vseg_cluster_increment));
     440    if (is_PTI)
    446441    {
    447442        icu_address[XICU_REG(XICU_MSK_PTI_ENABLE, proc_id)] = value;
     
    452447    }
    453448#else
     449    unsigned int * icu_address = (unsigned int *) ((unsigned int)&seg_icu_base +
     450                                 (cluster_id * (unsigned int)&vseg_cluster_increment));
     451
    454452    icu_address[proc_id * ICU_SPAN + ICU_MASK_SET] = value;
    455453#endif
    456454    return 0;
    457455}
    458 
    459456
    460457////////////////////////////////////////////////////////////////////////////////
     
    473470    if (proc_id >= NB_PROCS_MAX)    return 1;
    474471
    475     unsigned int * icu_address = (unsigned int *) ((char *) &seg_icu_base +
    476                                                    (cluster_id * GIET_CLUSTER_INCREMENT));
    477472#if USE_XICU
     473    unsigned int * icu_address = (unsigned int *) ((unsigned int)&seg_xcu_base +
     474                                 (cluster_id * (unsigned int)&vseg_cluster_increment));
     475
    478476    unsigned int prio = icu_address[XICU_REG(XICU_PRIO, proc_id)];
    479477    unsigned int pti_ok = (prio & 0x00000001);
     
    488486    else             { *buffer = 32; }
    489487#else
     488    unsigned int * icu_address = (unsigned int *) ((unsigned int)&seg_icu_base +
     489                                 (cluster_id * (unsigned int)&vseg_cluster_increment));
     490
    490491    *buffer = icu_address[proc_id * ICU_SPAN + ICU_IT_VECTOR];
    491492#endif
    492493    return 0;
    493494}
    494 
    495495
    496496////////////////////////////////////////////////////////////////////////////////
     
    912912// The (virtual) base address of the associated segment is:
    913913//
    914 //       dma_address = seg_dma_base + cluster_id * GIET_CLUSTER_INCREMENT
    915 //
    916 // - seg_dma_base  must be defined in the giet_vsegs.ld file
    917 // - GIET_CLUSTER_INCREMENT  must be defined in the giet_config.h file
     914//       dma_address = seg_dma_base + cluster_id * vseg_cluster_increment
     915//
    918916////////////////////////////////////////////////////////////////////////////////
    919917
     
    942940
    943941    // compute DMA base address
    944     unsigned int * dma_address = (unsigned int *) ((char *) &seg_dma_base +
    945                                                    (cluster_id * GIET_CLUSTER_INCREMENT));
     942    unsigned int * dma_address = (unsigned int *) ((unsigned int)&seg_dma_base +
     943                                 (cluster_id * (unsigned int)&vseg_cluster_increment));
    946944
    947945    dma_address[channel_id * DMA_SPAN + DMA_RESET] = 0;           
     
    951949#endif
    952950}
    953 
    954951
    955952//////////////////////////////////////////////////////////////////////////////////
     
    966963
    967964    // compute DMA base address
    968     unsigned int * dma_address = (unsigned int *) ((char *) &seg_dma_base +
    969                                                    (cluster_id * GIET_CLUSTER_INCREMENT));
     965    unsigned int * dma_address = (unsigned int *) ((unsigned int)&seg_dma_base +
     966                                 (cluster_id * (unsigned int)&vseg_cluster_increment));
    970967
    971968    *status = dma_address[channel_id * DMA_SPAN + DMA_LEN];
     
    975972#endif
    976973}
    977 
    978974
    979975//////////////////////////////////////////////////////////////////////////////////
     
    10311027    unsigned int cluster_id  = dma_id / NB_DMA_CHANNELS;
    10321028    unsigned int channel_id  = dma_id % NB_DMA_CHANNELS;
    1033     unsigned int * dma_vbase  = (unsigned int *) ((char *) &seg_dma_base +
    1034                                                 (cluster_id * GIET_CLUSTER_INCREMENT));
     1029    unsigned int * dma_vbase = (unsigned int *) ((unsigned int)&seg_dma_base +
     1030                               (cluster_id * (unsigned int)&vseg_cluster_increment));
    10351031    // get page table address
    10361032    unsigned int user_ptab = _get_context_slot(CTX_PTAB_ID);
     
    11961192}  // end _dma_transfer() 
    11971193
    1198 
    11991194//////////////////////////////////////////////////////////////////////////////////
    12001195// _dma_completed()
     
    12571252//     VciFrameBuffer driver
    12581253//////////////////////////////////////////////////////////////////////////////////
    1259 // The vci_frame_buffer device can be accessed directly by software with memcpy(),
    1260 // or it can be accessed through a multi-channels DMA component:
     1254// There three methods to access the VciFrameBuffer device:
    12611255// 
    1262 // The '_fb_sync_write' and '_fb_sync_read' functions use a memcpy strategy to
    1263 // implement the transfer between a data buffer (user space) and the frame
     1256// 1) The _fb_sync_write() and _fb_sync_read() functions use a memcpy strategy
     1257// to implement the transfer between a data buffer (user space) and the frame
    12641258// buffer (kernel space). They are blocking until completion of the transfer.
    12651259//
    1266 // The '_fb_write()', '_fb_read()' and '_fb_completed()' functions use the
    1267 // VciMultiDma components (distributed in the clusters) to transfer data
    1268 // between the user buffer and the frame buffer. A DMA channel is
    1269 // allocated to each task requesting it in the mapping_info data structure.
     1260// 2) The _fb_dma_write(), _fb_dma_read() and _fb_mdma_completed() functions use
     1261// the VciMultiDma components (distributed in the clusters) to transfer data
     1262// between the user buffer and the frame buffer.
     1263// A DMA channel is allocated to the task requesting it in the mapping_info,
     1264// and stored in the task context.
     1265//
     1266// 3) The _fb_cma_init(), _fb_cma_write() and _fb_cma_stop() functions use
     1267// the VciChbufDma component (non replicated) to transfer a flow of images from
     1268// an user space chained buffer (two buffers) to the frame buffer.
     1269// A CMA channel is allocated to the task requesting it in the mapping_info,
     1270// and stored in the task context.
    12701271//////////////////////////////////////////////////////////////////////////////////
    12711272
     
    13061307
    13071308//////////////////////////////////////////////////////////////////////////////////
    1308 // _fb_write()
     1309// _fb_dma_write()
    13091310// Transfer data from a memory buffer to the frame_buffer device using  DMA.
    13101311// - offset : offset (in bytes) in the frame buffer.
     
    13131314// Returns 0 if success, > 0 if error.
    13141315//////////////////////////////////////////////////////////////////////////////////
    1315 unsigned int _fb_write( unsigned int   offset,
    1316                         const void*    buffer,
    1317                         unsigned int   length)
     1316unsigned int _fb_dma_write( unsigned int   offset,
     1317                            const void*    buffer,
     1318                            unsigned int   length)
    13181319{
    13191320    return _dma_transfer( 0,             // frame buffer
     
    13231324                          length );
    13241325}
    1325 
    1326 
    1327 //////////////////////////////////////////////////////////////////////////////////
    1328 // _fb_read()
     1326//////////////////////////////////////////////////////////////////////////////////
     1327// _fb_dma_read()
    13291328// Transfer data from the frame_buffer device to a memory buffer using  DMA.
    13301329// - offset : offset (in bytes) in the frame buffer.
    1331 // - buffer : base address of the memory buffer.
    1332 // - length : number of bytes to be transfered.
     1330// - buffer : virtual base address of the user buffer.
     1331// - length : buffer size (number of bytes)
    13331332// Returns 0 if success, > 0 if error.
    13341333//////////////////////////////////////////////////////////////////////////////////
    1335 unsigned int _fb_read( unsigned int   offset,
    1336                        const void*    buffer,
    1337                        unsigned int   length )
     1334unsigned int _fb_dma_read( unsigned int   offset,
     1335                           const void*    buffer,
     1336                           unsigned int   length )
    13381337{
    13391338    return _dma_transfer( 0,    // frame buffer
     
    13431342                          length );
    13441343}
    1345 
    1346 
    13471344//////////////////////////////////////////////////////////////////////////////////
    13481345// _fb_completed()
     
    13521349// (1 == read error / 2 == DMA idle error / 3 == write error)
    13531350//////////////////////////////////////////////////////////////////////////////////
    1354 unsigned int _fb_completed()
     1351unsigned int _fb_dma_completed()
    13551352{
    13561353    return _dma_completed();
    13571354}
    13581355
     1356// This structure contains two chbuf descriptors that can be used by
     1357// the VciChbufDma component to tranfer a flow of images:
     1358// - The SRC chbuf descriptor contain two slots (two user buffers)
     1359// - The DST chbuf descriptor contains only one slot (frame buffer)
     1360typedef struct fb_cma_channel_s
     1361{
     1362    paddr_t buf0;   // physical address + status for user buffer 0
     1363    paddr_t buf1;   // physical address + status for user buffer 1
     1364    paddr_t fbf;    // physical address + status for frame buffer
     1365} fb_cma_channel_t;
     1366
     1367in_unckdata volatile fb_cma_channel_t _fb_cma_channel[NB_CMA_CHANNELS];
     1368
     1369//////////////////////////////////////////////////////////////////////////////////
     1370// _fb_cma_init()
     1371// This function does two things:
     1372// 1) Initialises the SRC chbuf descriptor (two buffers), and the DST
     1373//    chbuf descriptor (one single frame buffer), after translating 
     1374//    virtual addresses to physical addresses, and checking access rights.
     1375// 2) Starts the CMA hardware channel, that will permanently try to display
     1376//    images as soon as the SRC buffers are filled.
     1377// Arguments are:
     1378// - vbase0 : virtual base address of the first user buffer.
     1379// - vbase1 : virtual base address of the second user buffer.
     1380// - length : user buffer size (number of bytes)
     1381// Returns 0 if success, > 0 if error
     1382//////////////////////////////////////////////////////////////////////////////////
     1383unsigned int _fb_cma_init( const void*  vbase0,
     1384                           const void*  vbase1,
     1385                           unsigned int length )
     1386{
     1387#if NB_CMA_CHANNELS > 0
     1388
     1389    unsigned int  channel_id;       // CMA channel index
     1390    unsigned int  user_ptab;        // page table virtual address
     1391    unsigned int  ko;               // unsuccessfull V2P translation
     1392    unsigned int  vpn;              // virtual page number
     1393    unsigned int  flags;            // protection flags
     1394    unsigned int  ppn;              // physical page number
     1395    paddr_t       src_chbuf_pbase;  // physical address for SRC chbuf descriptor
     1396    paddr_t       dst_chbuf_pbase;  // physical address for SRC chbuf descriptor
     1397
     1398    // get CMA channel index
     1399    channel_id = _get_context_slot(CTX_CMA_ID);
     1400    if ( channel_id >= NB_CMA_CHANNELS )
     1401    {
     1402        _get_lock(&_tty_put_lock);
     1403        _puts("\n[GIET ERROR] in _fb_cma_init() : CMA channel index too large\n");
     1404        _release_lock(&_tty_put_lock);
     1405        return 1;
     1406    }
     1407
     1408    // check user buffer virtual addresses and length alignment
     1409    if ( ((unsigned int)vbase0 & 0x3) || ((unsigned int)vbase1 & 0x3) || (length & 0x3) )
     1410    {
     1411        _get_lock(&_tty_put_lock);
     1412        _puts("\n[GIET ERROR] in _fb_cma_init() : user buffer not word aligned\n");
     1413        _release_lock(&_tty_put_lock);
     1414        return 1;
     1415    }
     1416
     1417    // get page table virtual address
     1418    user_ptab = _get_context_slot(CTX_PTAB_ID);
     1419
     1420    // get frame buffer virtual address
     1421
     1422    // compute and register frame buffer physical address
     1423    vpn = ((unsigned int)&seg_fbf_base) >> 12;
     1424    ko = _v2p_translate( (page_table_t*) user_ptab,
     1425                         vpn,
     1426                         &ppn,
     1427                         &flags );
     1428    if (ko)
     1429    {
     1430        _get_lock(&_tty_put_lock);
     1431        _puts("\n[GIET ERROR] in _fb_cma_init() : frame buffer unmapped\n");
     1432        _release_lock(&_tty_put_lock);
     1433        return 1;
     1434    }
     1435    _fb_cma_channel[channel_id].fbf = ((paddr_t)ppn << 12) | (vpn & 0x00000FFF);
     1436
     1437    // Compute and register first user buffer physical address
     1438    vpn = (unsigned int)vbase0 >> 12;
     1439    ko = _v2p_translate( (page_table_t*) user_ptab,
     1440                         vpn,
     1441                         &ppn,
     1442                         &flags );
     1443    if (ko)
     1444    {
     1445        _get_lock(&_tty_put_lock);
     1446        _puts("\n[GIET ERROR] in _fb_cma_init() : user buffer 0 unmapped\n");
     1447        _release_lock(&_tty_put_lock);
     1448        return 1;
     1449    }
     1450    if ((flags & PTE_U) == 0)
     1451    {
     1452        _get_lock(&_tty_put_lock);
     1453        _puts("[GIET ERROR] in _fb_cma_init() : user buffer 0 not in user space\n");
     1454        _release_lock(&_tty_put_lock);
     1455        return 1;
     1456    }
     1457    _fb_cma_channel[channel_id].buf0 = ((paddr_t)ppn << 12) | (vpn & 0x00000FFF);
     1458
     1459    // Compute and register second user buffer physical address
     1460    vpn = (unsigned int)vbase1 >> 12;
     1461    ko = _v2p_translate( (page_table_t*) user_ptab,
     1462                         vpn,
     1463                         &ppn,
     1464                         &flags );
     1465    if (ko)
     1466    {
     1467        _get_lock(&_tty_put_lock);
     1468        _puts("\n[GIET ERROR] in _fb_cma_init() : user buffer 1 unmapped\n");
     1469        _release_lock(&_tty_put_lock);
     1470        return 1;
     1471    }
     1472    if ((flags & PTE_U) == 0)
     1473    {
     1474        _get_lock(&_tty_put_lock);
     1475        _puts("[GIET ERROR] in _fb_cma_init() : user buffer 1 not in user space\n");
     1476        _release_lock(&_tty_put_lock);
     1477        return 1;
     1478    }
     1479    _fb_cma_channel[channel_id].buf1 = ((paddr_t)ppn << 12) | (vpn & 0x00000FFF);
     1480
     1481    // Compute physical adress of the SRC chbuf descriptor
     1482    vpn = ((unsigned int)(&_fb_cma_channel[channel_id].buf0)) >> 12;
     1483    ko = _v2p_translate( (page_table_t*) user_ptab,
     1484                         vpn,
     1485                         &ppn,
     1486                         &flags );
     1487    if (ko)
     1488    {
     1489        _get_lock(&_tty_put_lock);
     1490        _puts("\n[GIET ERROR] in _fb_cma_init() : SRC chbuf descriptor unmapped\n");
     1491        _release_lock(&_tty_put_lock);
     1492        return 1;
     1493    }
     1494    src_chbuf_pbase = (((paddr_t)ppn) << 12) | (vpn & 0x00000FFF);
     1495
     1496    // Compute physical adress of the DST chbuf descriptor
     1497    vpn = ((unsigned int)(&_fb_cma_channel[channel_id].fbf)) >> 12;
     1498    ko = _v2p_translate( (page_table_t*) user_ptab,
     1499                         vpn,
     1500                         &ppn,
     1501                         &flags );
     1502    if (ko)
     1503    {
     1504        _get_lock(&_tty_put_lock);
     1505        _puts("\n[GIET ERROR] in _fb_cma_init() : DST chbuf descriptor unmapped\n");
     1506        _release_lock(&_tty_put_lock);
     1507        return 1;
     1508    }
     1509    dst_chbuf_pbase = (((paddr_t)ppn) << 12) | (vpn & 0x00000FFF);
     1510
     1511    // CMA channel activation
     1512    unsigned int* cma_vbase = (unsigned int *)&seg_cma_base;
     1513    unsigned int  offset     = channel_id * CHBUF_CHANNEL_SPAN;
     1514
     1515    cma_vbase[offset + CHBUF_SRC_DESC]  = (unsigned int)(src_chbuf_pbase & 0xFFFFFFFF);
     1516    cma_vbase[offset + CHBUF_SRC_EXT]   = (unsigned int)(src_chbuf_pbase >> 32);
     1517    cma_vbase[offset + CHBUF_SRC_NBUFS] = 2;
     1518    cma_vbase[offset + CHBUF_DST_DESC]  = (unsigned int)(dst_chbuf_pbase & 0xFFFFFFFF);
     1519    cma_vbase[offset + CHBUF_DST_EXT]   = (unsigned int)(dst_chbuf_pbase >> 32);
     1520    cma_vbase[offset + CHBUF_DST_NBUFS] = 1;
     1521    cma_vbase[offset + CHBUF_BUF_SIZE]  = length;
     1522    cma_vbase[offset + CHBUF_PERIOD]    = 300;
     1523    cma_vbase[offset + CHBUF_RUN]       = 1;
     1524
     1525    return 0;
     1526
     1527#else
     1528
     1529    _get_lock(&_tty_put_lock);
     1530    _puts("\n[GIET ERROR] in _fb_cma_init() : no CMA channel allocated\n");
     1531    _release_lock(&_tty_put_lock);
     1532
     1533    return 1;
     1534#endif
     1535}
     1536//////////////////////////////////////////////////////////////////////////////////
     1537// _fb_cma_write()
     1538// This function updates the status of the SRC and DST chbuf descriptors
     1539// to allows the CMA component to transfer another buffer.
     1540// - buffer_id : user buffer index (0 => buf0 / not 0 => buf1)
     1541// Returns 0 if success, > 0 if error
     1542//////////////////////////////////////////////////////////////////////////////////
     1543unsigned int _fb_cma_write( unsigned int buffer_id )
     1544{
     1545#if NB_CMA_CHANNELS > 0
     1546
     1547    // get CMA channel index
     1548    unsigned int channel_id = _get_context_slot(CTX_CMA_ID);
     1549    if ( channel_id >= NB_CMA_CHANNELS )
     1550    {
     1551        _get_lock(&_tty_put_lock);
     1552        _puts("\n[GIET ERROR] in _fb_cma_write() : CMA channel index too large\n");
     1553        _release_lock(&_tty_put_lock);
     1554        return 1;
     1555    }
     1556    // set SRC full
     1557    if ( buffer_id == 0 )
     1558    _fb_cma_channel[channel_id].buf0 = _fb_cma_channel[channel_id].buf0
     1559                                       | 0x8000000000000000ULL;
     1560    else
     1561    _fb_cma_channel[channel_id].buf1 = _fb_cma_channel[channel_id].buf1
     1562                                       | 0x8000000000000000ULL;
     1563    // set DST empty
     1564    _fb_cma_channel[channel_id].fbf  = _fb_cma_channel[channel_id].fbf
     1565                                       & 0x7FFFFFFFFFFFFFFFULL;
     1566    return 0;
     1567
     1568#else
     1569
     1570    _get_lock(&_tty_put_lock);
     1571    _puts("\n[GIET ERROR] in _fb_cma_channel() : no CMA channel allocated\n");
     1572    _release_lock(&_tty_put_lock);
     1573    return 1;
     1574
     1575#endif
     1576}
     1577//////////////////////////////////////////////////////////////////////////////////
     1578// _fb_cma_stop()
     1579// This function desactivates the CMA channel allocated to the calling task.
     1580// Returns 0 if success, > 0 if error
     1581//////////////////////////////////////////////////////////////////////////////////
     1582unsigned int _fb_cma_stop( unsigned int buffer_id )
     1583{
     1584#if NB_CMA_CHANNELS > 0
     1585
     1586    // get CMA channel allocated
     1587    unsigned int channel_id = _get_context_slot(CTX_CMA_ID);
     1588    if ( channel_id >= NB_CMA_CHANNELS )
     1589    {
     1590        _get_lock(&_tty_put_lock);
     1591        _puts("\n[GIET ERROR] in _fb_cma_stop() : CMA channel index too large\n");
     1592        _release_lock(&_tty_put_lock);
     1593        return 1;
     1594    }
     1595    // CMA channel desactivation
     1596    unsigned int* cma_vbase = (unsigned int *)&seg_cma_base;
     1597    unsigned int  offset     = channel_id * CHBUF_CHANNEL_SPAN;
     1598    cma_vbase[offset + CHBUF_RUN] = 0;
     1599    return 0;
     1600
     1601#else
     1602
     1603    _get_lock(&_tty_put_lock);
     1604    _puts("\n[GIET ERROR] in _fb_cma_stop() : no CMA channel allocated\n");
     1605    _release_lock(&_tty_put_lock);
     1606    return 1;
     1607
     1608#endif
     1609}
     1610   
    13591611//////////////////////////////////////////////////////////////////////////////////
    13601612//     VciMultiNic driver
    13611613//////////////////////////////////////////////////////////////////////////////////
    13621614// The VciMultiNic device can be accessed directly by software with memcpy(),
    1363 // or it can be accessed through a multi-channels DMA component:
     1615// or it can be accessed through a multi-channels CMA component:
    13641616// 
    13651617// The '_nic_sync_write' and '_nic_sync_read' functions use a memcpy strategy to
     
    13671619// buffer (kernel space). They are blocking until completion of the transfer.
    13681620//
    1369 // The '_nic_write()', '_nic_read()' and '_nic_completed()' functions use the
    1370 // VciMultiDma components (distributed in the clusters) to transfer data
    1371 // between the user buffer and the NIC. A  NIDMA channel is allocated to each
    1372 // task requesting it in the mapping_info data structure.
     1621// The _nic_cma_init() and _nic_cma_stop() functions use the VciChbufDma component
     1622// to transfer a flow of packets from the NIC RX hard chbuf (two containers)
     1623// to an user RX chbuf (two containers), and to transfer another flow of packets
     1624// from an user TX chbuf (two containers) to the NIC TX chbuf (two containers).
     1625// One NIC channel and two CMA channels must be allocated to the task
     1626// in the mapping_info data structure.
    13731627//////////////////////////////////////////////////////////////////////////////////
    13741628
     
    13761630// _nic_sync_write()
    13771631// Transfer data from an memory buffer to the NIC device using a memcpy.
    1378 // - offset : offset (in bytes) in the frame buffer.
    13791632// - buffer : base address of the memory buffer.
    13801633// - length : number of bytes to be transfered.
    13811634//////////////////////////////////////////////////////////////////////////////////
    1382 unsigned int _nic_sync_write( unsigned int   offset,
    1383                               const void*    buffer,
     1635unsigned int _nic_sync_write( const void*    buffer,
    13841636                              unsigned int   length )
    13851637{
    1386     unsigned char* nic_address = (unsigned char *) &seg_nic_base + offset;
    1387     memcpy((void *) nic_address, (void *) buffer, length);
    1388     return 0;
    1389 }
    1390 
    1391 
     1638    // To be defined
     1639    // unsigned char* nic_address = (unsigned char *) &seg_nic_base;
     1640    // memcpy((void *) nic_address, (void *) buffer, length);
     1641    return 0;
     1642}
    13921643//////////////////////////////////////////////////////////////////////////////////
    13931644// _nic_sync_read()
    13941645// Transfer data from the NIC device to a memory buffer using a memcpy.
    1395 // - offset : offset (in bytes) in the frame buffer.
    13961646// - buffer : base address of the memory buffer.
    13971647// - length : number of bytes to be transfered.
    13981648//////////////////////////////////////////////////////////////////////////////////
    1399 unsigned int _nic_sync_read(unsigned int offset, const void * buffer, unsigned int length) {
    1400     unsigned char *nic_address = (unsigned char *) &seg_nic_base + offset;
    1401     memcpy((void *) buffer, (void *) nic_address, length);
    1402     return 0;
    1403 }
    1404 
    1405 
    1406 //////////////////////////////////////////////////////////////////////////////////
    1407 // _nic_write()
    1408 // Transfer data from a memory buffer to the NIC device using  DMA.
    1409 // - offset : offset (in bytes) in the frame buffer.
    1410 // - buffer : base address of the memory buffer.
    1411 // - length : number of bytes to be transfered.
     1649unsigned int _nic_sync_read( const void*    buffer,
     1650                             unsigned int   length )
     1651{
     1652    // To be defined
     1653    // unsigned char* nic_address = (unsigned char *) &seg_nic_base;
     1654    // memcpy((void *) buffer, (void *) nic_address, length);
     1655    return 0;
     1656}
     1657//////////////////////////////////////////////////////////////////////////////////
     1658// _nic_cma_rx_init()
    14121659// Returns 0 if success, > 0 if error.
    14131660//////////////////////////////////////////////////////////////////////////////////
    1414 unsigned int _nic_write(unsigned int offset, const void * buffer, unsigned int length) {
    1415     return _dma_transfer(
    1416             1,            // NIC
    1417             0,            // write
    1418             offset,
    1419             (unsigned int) buffer,
    1420             length );   
    1421 }
    1422 
    1423 
    1424 //////////////////////////////////////////////////////////////////////////////////
    1425 // _nic_read()
    1426 // Transfer data from the NIC device to a memory buffer using  DMA.
    1427 // - offset : offset (in bytes) in the frame buffer.
    1428 // - buffer : base address of the memory buffer.
    1429 // - length : number of bytes to be transfered.
     1661unsigned int _nic_cma_rx_init( const void*  buf0,
     1662                               const void*  buf1,
     1663                               unsigned int length )
     1664{
     1665    // to be defined
     1666    // unsigned char* nic_address = (unsigned char *) &seg_nic_base;
     1667    return 0;
     1668}
     1669//////////////////////////////////////////////////////////////////////////////////
     1670// _nic_cma_tx_init()
    14301671// Returns 0 if success, > 0 if error.
    14311672//////////////////////////////////////////////////////////////////////////////////
    1432 unsigned int _nic_read(unsigned int offset, const void * buffer, unsigned int length) {
    1433     return _dma_transfer(
    1434             1,            // NIC
    1435             1,            // read
    1436             offset,
    1437             (unsigned int) buffer,
    1438             length );   
    1439 }
    1440 
    1441 
    1442 //////////////////////////////////////////////////////////////////////////////////
    1443 // _nic_completed()
    1444 // This function checks completion of a DMA transfer to or fom a NIC channel.
    1445 // As it is a blocking call, the processor is busy waiting.
    1446 // Returns 0 if success, > 0 if error
    1447 // (1 == read error / 2 == DMA idle error / 3 == write error)
    1448 //////////////////////////////////////////////////////////////////////////////////
    1449 unsigned int _nic_completed()
    1450 {
    1451     return _dma_completed();
    1452 }
     1673unsigned int _nic_cma_tx_init( const void*  buf0,
     1674                               const void*  buf1,
     1675                               unsigned int length )
     1676{
     1677    // to be defined
     1678    // unsigned char* nic_address = (unsigned char *) &seg_nic_base;
     1679    return 0;
     1680}//////////////////////////////////////////////////////////////////////////////////
     1681// _nic_cma_stop()
     1682// Returns 0 if success, > 0 if error.
     1683//////////////////////////////////////////////////////////////////////////////////
     1684unsigned int _nic_cma_stop()
     1685{
     1686    // to be defined
     1687    // unsigned char* nic_address = (unsigned char *) &seg_nic_base;
     1688    return 0;
     1689}
     1690
    14531691
    14541692//////////////////////////////////////////////////////////////////////////////////
     
    14581696// as a set of uncached, memory mapped registers.
    14591697///////////////////////////////////////////////////////////////////////////////////
     1698// The (virtual) base address of the associated segment is:
     1699//
     1700//       mmc_address = seg_mmc_base + cluster_id * vseg_cluster_increment
     1701//
     1702////////////////////////////////////////////////////////////////////////////////
    14601703
    14611704///////////////////////////////////////////////////////////////////////////////////
     
    14701713    unsigned int cluster_id    = (unsigned int)((buf_paddr>>32)/(256/NB_CLUSTERS));
    14711714
    1472     unsigned int * mmc_address = (unsigned int *) ((char *) &seg_mmc_base +
    1473                                                    (cluster_id * GIET_CLUSTER_INCREMENT));
     1715    unsigned int * mmc_address = (unsigned int *) ((unsigned int)&seg_mmc_base +
     1716                                 (cluster_id * (unsigned int)&vseg_cluster_increment));
    14741717
    14751718    // get the lock protecting exclusive access to MEMC
     
    14851728    mmc_address[MEMC_LOCK] = 0;
    14861729}
     1730
    14871731///////////////////////////////////////////////////////////////////////////////////
    14881732// _heap_info()
Note: See TracChangeset for help on using the changeset viewer.