Ignore:
Timestamp:
Jul 15, 2015, 6:15:52 PM (9 years ago)
Author:
bellefin
Message:

Change the syscalls related to the NIC and the CMA
1) In a CHBUF, every buffer is linked to a variable called “status” which is equal to 1 if the buffer is full or 0 if it is empty. The status occupies 64 bytes to simplify cache coherence
2) The CHBUF descriptor now contains the physical addresses of the buffer and its status. It only occupies 64 bits.

Location:
soft/giet_vm/giet_kernel
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_kernel/sys_handler.c

    r592 r614  
    102102
    103103////////////////////////////////////////////////////////////////////////////
    104 //     NIC_RX and NIC_TX chbuf arrays
     104//     NIC_RX and NIC_TX kernel chbuf arrays
    105105////////////////////////////////////////////////////////////////////////////
    106106
    107107__attribute__((section(".kdata")))
    108 nic_chbuf_t  _nic_rx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64)));
     108ker_chbuf_t  _nic_ker_rx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64)));
    109109
    110110__attribute__((section(".kdata")))
    111 nic_chbuf_t  _nic_tx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64)));
     111ker_chbuf_t  _nic_ker_tx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64)));
    112112
    113113////////////////////////////////////////////////////////////////////////////
    114114// FBF related chbuf descriptors array, indexed by the CMA channel index.
    115115// Physical addresses of these chbuf descriptors required for L2 cache sync.
     116// FBF status
    116117////////////////////////////////////////////////////////////////////////////
    117118
     
    121122__attribute__((section(".kdata")))
    122123unsigned long long _fbf_chbuf_paddr[NB_CMA_CHANNELS];
     124
     125__attribute__((section(".kdata")))
     126buffer_status_t _fbf_status[NB_CMA_CHANNELS] __attribute__((aligned(64)));
    123127
    124128////////////////////////////////////////////////////////////////////////////
     
    141145    &_sys_global_task_id,            /* 0x09 */
    142146    &_sys_fbf_cma_alloc,             /* 0x0A */
    143     &_sys_fbf_cma_start,             /* 0x0B */
    144     &_sys_fbf_cma_display,           /* 0x0C */
    145     &_sys_fbf_cma_stop,              /* 0x0D */
    146     &_sys_task_exit,                 /* 0x0E */
    147     &_sys_procs_number,              /* 0x0F */
    148 
    149     &_sys_fbf_sync_write,            /* 0x10 */
    150     &_sys_fbf_sync_read,             /* 0x11 */
    151     &_sys_thread_id,                 /* 0x12 */
    152     &_sys_ukn,                       /* 0x13 */
     147    &_sys_fbf_cma_init_buf,          /* 0x0B */
     148    &_sys_fbf_cma_start,             /* 0x0C */
     149    &_sys_fbf_cma_display,           /* 0x0D */
     150    &_sys_fbf_cma_stop,              /* 0x0E */
     151    &_sys_task_exit,                 /* 0x0F */
     152
     153    &_sys_procs_number,              /* 0x10 */
     154    &_sys_fbf_sync_write,            /* 0x11 */
     155    &_sys_fbf_sync_read,             /* 0x12 */
     156    &_sys_thread_id,                 /* 0x13 */
    153157    &_sys_tim_alloc,                 /* 0x14 */
    154158    &_sys_tim_start,                 /* 0x15 */
     
    785789    }
    786790
     791    ////////////////////////////////////////////////////////
     792    // Step 1: get and register CMA and NIC channel index //
     793    ////////////////////////////////////////////////////////
     794
    787795    // get a NIC_RX or NIC_TX channel index
    788796    unsigned int nic_channel;
     
    826834    }
    827835
     836    /////////////////////////////////////////////////////////////////////////////////
     837    // Step 2: loop on all the clusters                                            //
     838    // Allocate the kernel containers and status, compute the container and the    //
     839    // status physical addresses, fill and synchronize the kernel CHBUF descriptor //
     840    /////////////////////////////////////////////////////////////////////////////////
     841
    828842    // physical addresses to be registered in the CMA registers
    829843    unsigned long long nic_chbuf_pbase;     // NIC chbuf physical address
    830844    unsigned long long ker_chbuf_pbase;     // kernel chbuf physical address
    831845
    832     // allocate one kernel container per cluster in the (xmax / ymax) mesh
     846    // allocate one kernel container and one status variable per cluster in the
     847    // (xmax / ymax) mesh
    833848    unsigned int        cx;                 // cluster X coordinate
    834849    unsigned int        cy;                 // cluster Y coordinate
     
    836851    unsigned int        vaddr;              // virtual address
    837852    unsigned long long  cont_paddr;         // container physical address
     853    unsigned long long  sts_paddr;          // container status physical address
    838854
    839855    unsigned int        flags;              // for _v2p_translate()
     
    859875            cont_paddr = _v2p_translate( vaddr , &flags );
    860876
     877            // checking container address alignment
     878            if ( cont_paddr & 0x3F )
     879            {
     880                _printf("\n[GIET ERROR] in _sys_nic_alloc() : container address of cluster[%d,%d] not aligned\n",
     881                        cx, cy);
     882                return -1;
     883            }
     884
     885#if GIET_DEBUG_NIC
     886_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_alloc()\n"
     887        " allocates in cluster[%d,%d]:\n"
     888        " - container vaddr = %x / paddr = %l\n",
     889        thread , cx , cy , vaddr, cont_paddr );
     890#endif
     891
     892            // allocate the kernel container status
     893            // it occupies 64 bytes but only last bit is useful (1 for full and 0 for empty)
     894            vaddr = (unsigned int)_remote_malloc( 64, cx, cy );
     895
     896            if ( vaddr == 0 )  // not enough kernel heap memory in cluster[cx,cy]
     897            {
     898                _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough kenel heap"
     899                        " in cluster[%d,%d]\n", cx, cy );
     900                return -1;
     901            }
     902
     903            // compute status physical address
     904            sts_paddr = _v2p_translate( vaddr , &flags );
     905
     906            // checking status address alignment
     907            if ( sts_paddr & 0x3F )
     908            {
     909                _printf("\n[GIET ERROR] in _sys_nic_alloc() : status address of cluster[%d,%d] not aligned\n",
     910                        cx, cy);
     911                return -1;
     912            }
     913
    861914            // initialize chbuf entry
    862             if ( is_rx ) _nic_rx_chbuf[nic_channel].buffer[index].desc = cont_paddr;
    863             else         _nic_tx_chbuf[nic_channel].buffer[index].desc = cont_paddr;
     915            // The buffer descriptor has the following structure:
     916            // - the 26 LSB bits contain bits[6:31] of the buffer physical address
     917            // - the 26 following bits contain bits[6:31] of the physical address where the
     918            //   buffer status is located
     919            // - the 12 MSB bits contain the common address extension of the buffer and its
     920            //   status
     921            if ( is_rx )
     922                _nic_ker_rx_chbuf[nic_channel].buf_desc[index] =
     923                    (unsigned long long)
     924                    ((sts_paddr & 0xFFFFFFFFULL) >> 6) +
     925                    (((cont_paddr & 0xFFFFFFFFFFFULL) >> 6) << 26);
     926            else
     927                _nic_ker_tx_chbuf[nic_channel].buf_desc[index] =
     928                    (unsigned long long)
     929                    ((sts_paddr & 0xFFFFFFC0ULL) >> 6) +
     930                    (((cont_paddr & 0xFFFFFFFFFC0ULL) >> 6) << 26);
    864931
    865932#if GIET_DEBUG_NIC
    866 _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_alloc()"
    867         " allocates container in cluster[%d,%d]\n"
    868         "  vaddr = %x / paddr = %l\n",
    869         thread , cx , cy , vaddr , cont_paddr );
     933_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_alloc()\n"
     934        " - status vaddr = %x / paddr = %l\n"
     935        " Buffer descriptor = %l\n",
     936        thread, vaddr, sts_paddr,
     937        (unsigned long long)((sts_paddr & 0xFFFFFFFFULL) >> 6) +
     938        (((cont_paddr & 0xFFFFFFFFFFFULL) >> 6) << 26) );
    870939#endif
    871940        }
     
    875944    if ( is_rx )
    876945    {
    877         _nic_rx_chbuf[nic_channel].xmax = xmax;
    878         _nic_rx_chbuf[nic_channel].ymax = ymax;
     946        _nic_ker_rx_chbuf[nic_channel].xmax = xmax;
     947        _nic_ker_rx_chbuf[nic_channel].ymax = ymax;
    879948    }
    880949    else
    881950    {
    882         _nic_tx_chbuf[nic_channel].xmax = xmax;
    883         _nic_tx_chbuf[nic_channel].ymax = ymax;
    884     }
    885 
    886     // compute the NIC chbuf descriptor physical address
    887     unsigned int offset;
    888     if ( is_rx ) offset = 0x4000;
    889     else         offset = 0x4080;
    890     nic_chbuf_pbase = (((unsigned long long)((X_IO << Y_WIDTH) + Y_IO))<<32) |
    891                       (SEG_NIC_BASE + (nic_channel<<15) + offset);
    892 
    893 #if GIET_DEBUG_NIC
    894 _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_alloc() get NIC chbuf : paddr = %l\n",
    895         thread , nic_chbuf_pbase );
    896 #endif
     951        _nic_ker_tx_chbuf[nic_channel].xmax = xmax;
     952        _nic_ker_tx_chbuf[nic_channel].ymax = ymax;
     953    }
    897954
    898955    // compute the kernel chbuf descriptor physical address
    899     if ( is_rx ) vaddr = (unsigned int)( &_nic_rx_chbuf[nic_channel] );
    900     else         vaddr = (unsigned int)( &_nic_tx_chbuf[nic_channel] );
     956    if ( is_rx ) vaddr = (unsigned int)( &_nic_ker_rx_chbuf[nic_channel] );
     957    else         vaddr = (unsigned int)( &_nic_ker_tx_chbuf[nic_channel] );
    901958
    902959    ker_chbuf_pbase = _v2p_translate( vaddr , &flags );
     
    909966
    910967    // sync the kernel chbuf in L2 after write in L2
    911     _mmc_sync( ker_chbuf_pbase, sizeof( nic_chbuf_t ) );
    912 
    913     // initializes CMA registers defining the source & destination chbufs
     968    _mmc_sync( ker_chbuf_pbase, sizeof( ker_chbuf_t ) );
     969
     970    ///////////////////////////////////////////////////////////////
     971    // Step 3: compute the NIC chbuf descriptor physical address //
     972    ///////////////////////////////////////////////////////////////
     973
     974    unsigned int offset;
     975    if ( is_rx ) offset = 0x4100;
     976    else         offset = 0x4110;
     977    nic_chbuf_pbase = (((unsigned long long)((X_IO << Y_WIDTH) + Y_IO))<<32) |
     978                      (SEG_NIC_BASE + (nic_channel<<15) + offset);
     979
     980#if GIET_DEBUG_NIC
     981_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_alloc() get NIC chbuf : paddr = %l\n",
     982        thread , nic_chbuf_pbase );
     983#endif
     984
     985    ////////////////////////////////////////////////////////////////////////////////
     986    // Step 4: initialize CMA registers defining the source & destination chbufs //
     987    ////////////////////////////////////////////////////////////////////////////////
     988
    914989    if ( is_rx )               // NIC to kernel
    915990    {
     
    9841059
    9851060    // activates NIC channel
    986     _nic_channel_start( nic_channel, is_rx, GIET_NIC_MAC4, GIET_NIC_MAC2 ); 
     1061    _nic_channel_start( nic_channel, is_rx, GIET_NIC_MAC4, GIET_NIC_MAC2 );
    9871062
    9881063#if GIET_DEBUG_NIC
    989 _printf("\n[GIET DEBUG NIC] Task %d exit _sys_nic_start() at cycle %d\n",
    990         thread , _get_proctime() );
     1064    _printf("\n[GIET DEBUG NIC] Task %d exit _sys_nic_start() at cycle %d\n",
     1065            thread , _get_proctime() );
    9911066#endif
    9921067
     
    10151090
    10161091    // get kernel chbuf virtual address
    1017     nic_chbuf_t* chbuf;
    1018     if ( is_rx )  chbuf = &_nic_rx_chbuf[channel];
    1019     else          chbuf = &_nic_tx_chbuf[channel];
     1092    ker_chbuf_t* ker_chbuf;
     1093    if ( is_rx )  ker_chbuf = &_nic_ker_rx_chbuf[channel];
     1094    else          ker_chbuf = &_nic_ker_tx_chbuf[channel];
    10201095
    10211096    // get xmax / ymax parameters
    1022     unsigned int xmax = chbuf->xmax;
    1023     unsigned int ymax = chbuf->ymax;
     1097    unsigned int xmax = ker_chbuf->xmax;
     1098    unsigned int ymax = ker_chbuf->ymax;
    10241099
    10251100    // get cluster coordinates for the processor running the calling task
     
    10421117    }
    10431118   
    1044     unsigned long long user_buffer_paddr;    // user buffer physical address
    1045     unsigned long long kernel_buffer_paddr;  // kernel buffer physical address
    1046     unsigned long long kernel_chbuf_paddr;   // kernel chbuf physical address
    1047     unsigned long long buffer_descriptor;    // kernel buffer descriptor
    1048     unsigned long long buffer_desc_paddr;    // kernel buffer descriptor paddr
    1049     unsigned int       index;                // kernel buffer index in chbuf
    1050     unsigned int       flags;                // for _v2P_translate
     1119    unsigned long long usr_buf_paddr;       // user buffer physical address
     1120    unsigned long long ker_buf_paddr;       // kernel buffer physical address
     1121    unsigned long long ker_sts_paddr;       // kernel buffer status physical address
     1122    unsigned long long ker_buf_desc;        // kernel buffer descriptor
     1123    unsigned int       ker_sts;             // kernel buffer status (full or empty)
     1124    unsigned int       index;               // kernel buffer index in chbuf
     1125    unsigned int       flags;               // for _v2P_translate
    10511126
    10521127    // Compute user buffer physical address and check access rights
    1053     user_buffer_paddr = _v2p_translate( (unsigned int)buffer , &flags );
     1128    usr_buf_paddr = _v2p_translate( (unsigned int)buffer , &flags );
    10541129
    10551130    if ( (flags & PTE_U) == 0 )
    10561131    {
    1057         _printf("\n[GIET ERROR] in _sys_nic_tx_move() : illegal buffer address\n");
     1132        _printf("\n[GIET ERROR] in _sys_nic_tx_move() : illegal user buffer address\n");
    10581133        return -1;
    10591134    }
     
    10611136#if GIET_DEBUG_NIC
    10621137_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_move() get user buffer : paddr = %l\n",
    1063         thread, user_buffer_paddr );
    1064 #endif
    1065 
    1066     // compute kernel chbuf physical address (required for sync)
    1067     kernel_chbuf_paddr = _v2p_translate( (unsigned int)chbuf , &flags );
     1138        thread, usr_buf_paddr );
     1139#endif
     1140
     1141    // compute buffer index, buffer descriptor paddr and buffer status paddr
     1142    index = (ymax * cx) + cy;
     1143    ker_buf_desc = ker_chbuf->buf_desc[index];
     1144    ker_sts_paddr = ((ker_buf_desc & 0xFFF0000000000000ULL) >> 20) +
     1145                    ((ker_buf_desc & 0x3FFFFFFULL) << 6);
     1146
     1147#if GIET_DEBUG_NIC
     1148_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_move() read ker_buf_desc %d at cycle %d\n"
     1149        "  kernel buffer descriptor = %l\n",
     1150        thread, index, _get_proctime(), ker_buf_desc );
     1151#endif
    10681152
    10691153    // poll local kernel container status until success
    10701154    while ( 1 )
    10711155    {
    1072         // compute buffer index and buffer descriptor paddr
    1073         index = (ymax * cx) + cy;
    1074         buffer_desc_paddr = kernel_chbuf_paddr + (index<<6);
    1075 
    10761156        // inval buffer descriptor in L2 before read in L2
    1077         _mmc_inval( buffer_desc_paddr , 8 );
    1078         buffer_descriptor = chbuf->buffer[index].desc;
     1157        _mmc_inval( ker_sts_paddr, 4 );
     1158        ker_sts = _physical_read( ker_sts_paddr );
    10791159
    10801160#if GIET_DEBUG_NIC
    1081 _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_move() read buf_desc %d at cycle %d\n"
    1082         "  paddr = %l / buffer descriptor = %l\n",
    1083         thread, index, _get_proctime(), buffer_desc_paddr, buffer_descriptor );
     1161_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_move() read ker_buf_sts %d at cycle %d\n"
     1162        "  paddr = %l / kernel buffer status = %x\n",
     1163        thread, index, _get_proctime(), ker_sts_paddr, ker_sts );
    10841164#endif
    10851165
    10861166        // test buffer status and break if found
    1087         if ( ( is_rx != 0 ) && (buffer_descriptor >> 63) == 1 ) break;
    1088         if ( ( is_rx == 0 ) && (buffer_descriptor >> 63) == 0 ) break;
     1167        if ( ( is_rx != 0 ) && ( ker_sts == 0x1 ) ) break;
     1168        if ( ( is_rx == 0 ) && ( ker_sts == 0 ) ) break;
    10891169    }
    10901170
    10911171    // compute kernel buffer physical address
    1092     kernel_buffer_paddr = buffer_descriptor & 0x0000FFFFFFFFFFFFULL;
     1172    ker_buf_paddr = (ker_buf_desc & 0xFFFFFFFFFC000000ULL) >> 20;
    10931173   
    10941174    // move one container
     
    10961176    {
    10971177        // inval kernel buffer in L2 before read in L2
    1098         _mmc_inval( kernel_buffer_paddr, NIC_CONTAINER_SIZE );
     1178        _mmc_inval( ker_buf_paddr, NIC_CONTAINER_SIZE );
    10991179
    11001180        // transfer data from kernel buffer to user buffer
    1101         _physical_memcpy( user_buffer_paddr,
    1102                           kernel_buffer_paddr,
     1181        _physical_memcpy( usr_buf_paddr,
     1182                          ker_buf_paddr,
    11031183                          NIC_CONTAINER_SIZE );
    11041184#if GIET_DEBUG_NIC
    11051185_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_move() transfer kernel buffer %l\n"
    11061186        " to user buffer %l at cycle %d\n",
    1107         thread , kernel_buffer_paddr , user_buffer_paddr , _get_proctime() );
     1187        thread , ker_buf_paddr , usr_buf_paddr , _get_proctime() );
    11081188#endif
    11091189
     
    11121192    {
    11131193        // transfer data from user buffer to kernel buffer
    1114         _physical_memcpy( kernel_buffer_paddr,
    1115                           user_buffer_paddr,
     1194        _physical_memcpy( ker_buf_paddr,
     1195                          usr_buf_paddr,
    11161196                          NIC_CONTAINER_SIZE );
    11171197
    11181198        // sync kernel buffer in L2 after write in L2
    1119         _mmc_sync( kernel_buffer_paddr, NIC_CONTAINER_SIZE );
     1199        _mmc_sync( ker_buf_paddr, NIC_CONTAINER_SIZE );
    11201200
    11211201#if GIET_DEBUG_NIC
    11221202_printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_move() transfer "
    11231203        "user buffer %l to kernel buffer %l at cycle %d\n",
    1124         thread , user_buffer_paddr , kernel_buffer_paddr , _get_proctime() );
     1204        thread , usr_buf_paddr , ker_buf_paddr , _get_proctime() );
    11251205#endif
    11261206
     
    11281208
    11291209    // update kernel chbuf status
    1130     if ( is_rx ) chbuf->buffer[index].desc = kernel_buffer_paddr & 0x0000FFFFFFFFFFFFULL;
    1131     else         chbuf->buffer[index].desc = kernel_buffer_paddr | 0x8000000000000000ULL;
     1210    if ( is_rx ) _physical_write ( ker_sts_paddr, 0 );
     1211    else         _physical_write ( ker_sts_paddr, 0x1 );
    11321212
    11331213    // sync kernel chbuf in L2 after write in L2
    1134     _mmc_sync( kernel_chbuf_paddr + (index<<6) , 8 );
     1214    _mmc_sync( ker_sts_paddr, 4 );
    11351215
    11361216#if GIET_DEBUG_NIC
     
    13391419} // end sys_fbf_cma_alloc()
    13401420
    1341 ////////////////////////////////////////////
    1342 int _sys_fbf_cma_start( void*        vbase0,
    1343                         void*        vbase1, 
    1344                         unsigned int length )
     1421
     1422////////////////////////
     1423int _sys_fbf_cma_init_buf(void*        buf0_vbase,
     1424                          void*        buf1_vbase,
     1425                          void*        sts0_vaddr,
     1426                          void*        sts1_vaddr )
    13451427{
    13461428#if NB_CMA_CHANNELS > 0
     
    13481430    unsigned int       vaddr;           // virtual address
    13491431    unsigned int       flags;           // for _v2p_translate()
     1432    unsigned long long fbf_paddr;       // fbf physical address
     1433    unsigned long long fbf_sts_paddr;   // fbf status physical address
     1434    unsigned long long buf0_pbase;      // buffer 0 base physical address
     1435    unsigned long long sts0_paddr;      // buffer 0 status physical address
     1436    unsigned long long buf1_pbase;      // buffer 1 base physical address
     1437    unsigned long long sts1_paddr;      // buffer 1 status physical address
    13501438
    13511439    // get channel index
     
    13541442    if ( channel >= NB_CMA_CHANNELS )
    13551443    {
    1356         _printf("\n[GIET ERROR] in _fbf_cma_start() : CMA channel index too large\n");
     1444        _printf("\n[GIET ERROR] in _fbf_cma_init_buf() : CMA channel index too large\n");
    13571445        return -1;
    13581446    }
    13591447
    13601448#if GIET_DEBUG_FBF_CMA
    1361 _printf("\n[FBF_CMA DEBUG] enters _sys_fbf_cma_start()\n"
    1362         " - channel      = %d\n"
    1363         " - buf0   vbase = %x\n"
    1364         " - buf1   vbase = %x\n"
    1365         " - buffer size  = %x\n",
     1449_printf("\n[FBF_CMA DEBUG] enters _sys_fbf_cma_init_buf()\n"
     1450        " - channel           = %d\n"
     1451        " - buf0        vbase = %x\n"
     1452        " - buf1        vbase = %x\n"
     1453        " - sts0        vaddr = %x\n"
     1454        " - sts1        vaddr = %x\n",
    13661455        channel,
    1367         (unsigned int)vbase0,
    1368         (unsigned int)vbase1,
    1369         length );
    1370 #endif
    1371 
    1372     // checking user buffers virtual addresses and length alignment
    1373     if ( ((unsigned int)vbase0 & 0x3) ||
    1374          ((unsigned int)vbase1 & 0x3) ||
    1375          (length & 0x3) )
    1376     {
    1377         _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer not aligned\n");
     1456        (unsigned int)buf0_vbase,
     1457        (unsigned int)buf1_vbase,
     1458        (unsigned int)sts0_vaddr,
     1459        (unsigned int)sts1_vaddr );
     1460#endif
     1461
     1462    // checking user buffers virtual addresses alignment
     1463    if ( ((unsigned int)buf0_vbase & 0x3F) ||
     1464         ((unsigned int)buf1_vbase & 0x3F) )
     1465    {
     1466        _printf("\n[GIET ERROR] in _fbf_cma_inti_buf() : user buffer not aligned\n");
     1467        return -1;
     1468    }
     1469
     1470    // checking user buffers status virtual addresses alignment
     1471    if ( ((unsigned int)sts0_vaddr & 0x3F) ||
     1472         ((unsigned int)sts1_vaddr & 0x3F) )
     1473    {
     1474        _printf("\n[GIET ERROR] in _fbf_cma_init_buf() : user buffer status not aligned\n");
    13781475        return -1;
    13791476    }
     
    13811478    // compute frame buffer physical address and initialize _fbf_chbuf[channel]
    13821479    vaddr = (unsigned int)SEG_FBF_BASE;
    1383     _fbf_chbuf[channel].fbf.desc = _v2p_translate( vaddr , &flags );
     1480    fbf_paddr = _v2p_translate( vaddr , &flags );
     1481    vaddr = (unsigned int)&_fbf_status[channel];
     1482    fbf_sts_paddr = _v2p_translate( vaddr , &flags );
     1483
     1484    _fbf_chbuf[channel].fbf_desc =
     1485        (unsigned long long) ((fbf_sts_paddr & 0xFFFFFFFFULL) >> 6) +
     1486        (((fbf_paddr & 0xFFFFFFFFULL) >> 6 ) << 26);
    13841487
    13851488    // Compute user buffer 0 physical addresses and intialize _fbf_chbuf[channel]
    1386     vaddr = (unsigned int)vbase0;
    1387     _fbf_chbuf[channel].buf0.desc = _v2p_translate( vaddr , &flags );
    1388 
     1489    vaddr = (unsigned int)buf0_vbase;
     1490    buf0_pbase = _v2p_translate( vaddr , &flags );
    13891491    if ((flags & PTE_U) == 0)
    13901492    {
     
    13931495    }
    13941496
     1497    vaddr = (unsigned int)sts0_vaddr;
     1498    sts0_paddr = _v2p_translate( vaddr , &flags );
     1499    if ((flags & PTE_U) == 0)
     1500    {
     1501        _printf("\n[GIET ERROR] in _fbf_cma_start() : sts0 not in user space\n");
     1502        return -1;
     1503    }
     1504
     1505    _fbf_chbuf[channel].buf0_desc =
     1506        (unsigned long long) ((sts0_paddr & 0xFFFFFFFFULL) >> 6) +
     1507        (((buf0_pbase & 0xFFFFFFFFULL) >> 6 ) << 26);
     1508
    13951509    // Compute user buffer 1 physical addresses and intialize _fbf_chbuf[channel]
    1396     vaddr = (unsigned int)vbase1;
    1397     _fbf_chbuf[channel].buf1.desc = _v2p_translate( vaddr , &flags );
    1398 
     1510    vaddr = (unsigned int)buf1_vbase;
     1511    buf1_pbase = _v2p_translate( vaddr , &flags );
    13991512    if ((flags & PTE_U) == 0)
    14001513    {
     
    14031516    }
    14041517
    1405     // initializes buffer length
    1406     _fbf_chbuf[channel].length = length;
     1518    vaddr = (unsigned int)sts1_vaddr;
     1519    sts1_paddr = _v2p_translate( vaddr , &flags );
     1520    if ((flags & PTE_U) == 0)
     1521    {
     1522        _printf("\n[GIET ERROR] in _fbf_cma_start() : sts1 not in user space\n");
     1523        return -1;
     1524    }
     1525
     1526    _fbf_chbuf[channel].buf1_desc =
     1527        (unsigned long long) ((sts1_paddr & 0xFFFFFFFFULL) >> 6) +
     1528        (((buf1_pbase & 0xFFFFFFFFULL) >> 6 ) << 26);
    14071529
    14081530    // Compute and register physical adress of the fbf_chbuf descriptor
     
    14101532    _fbf_chbuf_paddr[channel] = _v2p_translate( vaddr , &flags );
    14111533 
     1534#if GIET_DEBUG_FBF_CMA
     1535_printf(" - fbf         pbase = %l\n"
     1536        " - fbf status  paddr = %l\n"
     1537        " - buf0        pbase = %l\n"
     1538        " - buf0 status paddr = %l\n"
     1539        " - buf1        pbase = %l\n"
     1540        " - buf0 status paddr = %l\n"
     1541        " - chbuf       pbase = %l\n",
     1542        fbf_paddr,
     1543        fbf_sts_paddr,
     1544        buf0_pbase,
     1545        sts0_paddr,
     1546        buf1_pbase,
     1547        sts1_paddr,
     1548        _fbf_chbuf_paddr[channel] );
     1549#endif
     1550
     1551    return 0;
     1552
     1553#else
     1554
     1555    _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : NB_CMA_CHANNELS = 0\n");
     1556    return -1;
     1557
     1558#endif 
     1559} // end sys_fbf_cma_init_buf()
     1560
     1561////////////////////////////////////////////
     1562int _sys_fbf_cma_start( unsigned int length )
     1563{
     1564#if NB_CMA_CHANNELS > 0
     1565
     1566    // get channel index
     1567    unsigned int channel = _get_context_slot( CTX_CMA_FB_ID );
     1568
     1569    if ( channel >= NB_CMA_CHANNELS )
     1570    {
     1571        _printf("\n[GIET ERROR] in _fbf_cma_start() : CMA channel index too large\n");
     1572        return -1;
     1573    }
     1574
     1575    // check buffers initialization
     1576    if ( ( _fbf_chbuf[channel].buf0_desc == 0x0ULL ) &&
     1577         ( _fbf_chbuf[channel].buf1_desc == 0x0ULL) &&
     1578         ( _fbf_chbuf[channel].fbf_desc == 0x0ULL) )
     1579    {
     1580        _printf("\n[GIET ERROR] in _sys_fbf_cma_start() :\n"
     1581                "Buffer initialization has not been done\n");
     1582        return -1;
     1583    }
     1584
     1585    // initializes buffer length
     1586    _fbf_chbuf[channel].length = length;
     1587
    14121588    if ( USE_IOB )
    14131589    {
     
    14151591        _mmc_sync( _fbf_chbuf_paddr[channel] , sizeof( fbf_chbuf_t ) );
    14161592    }
    1417 
    1418 #if GIET_DEBUG_FBF_CMA
    1419 _printf(" - fbf    pbase = %l\n"
    1420         " - buf0   pbase = %l\n"
    1421         " - buf1   pbase = %l\n"
    1422         " - chbuf  pbase = %l\n",
    1423         _fbf_chbuf[channel].fbf.desc,
    1424         _fbf_chbuf[channel].buf0.desc,
    1425         _fbf_chbuf[channel].buf1.desc,
    1426         _fbf_chbuf_paddr[channel] );
    1427 #endif
    14281593
    14291594    // start CMA transfer
     
    14311596    unsigned int src_chbuf_paddr_lsb = (unsigned int)(paddr & 0xFFFFFFFF);
    14321597    unsigned int src_chbuf_paddr_ext = (unsigned int)(paddr >> 32);
    1433     unsigned int dst_chbuf_paddr_lsb = src_chbuf_paddr_lsb + 128;
     1598    unsigned int dst_chbuf_paddr_lsb = src_chbuf_paddr_lsb + 16;
    14341599    unsigned int dst_chbuf_paddr_ext = src_chbuf_paddr_ext;
    14351600
     
    14761641#if GIET_DEBUG_FBF_CMA
    14771642_printf("\n[FBF_CMA DEBUG] enters _sys_fb_cma_display()\n"
    1478         " - cma channel     = %d\n"
    1479         " - buffer index    = %d\n"
    1480         " - buf0_desc value = %l\n"
    1481         " - buf1_desc value = %l\n"
    1482         " - fbf_desc  value = %l\n",
     1643        " - cma channel      = %d\n"
     1644        " - buffer index     = %d\n"
     1645        " - buf0_desc value  = %l\n"
     1646        " - buf1_desc value  = %l\n"
     1647        " - fbf_desc  value  = %l\n",
    14831648        channel , buffer_index,
    1484         _fbf_chbuf[channel].buf0.desc,
    1485         _fbf_chbuf[channel].buf1.desc,
    1486         _fbf_chbuf[channel].fbf.desc );
    1487 #endif
     1649        _fbf_chbuf[channel].buf0_desc,
     1650        _fbf_chbuf[channel].buf1_desc,
     1651        _fbf_chbuf[channel].fbf_desc );
     1652#endif
     1653
     1654    unsigned long long buf_sts_paddr;
     1655    unsigned long long buf_paddr;
     1656    unsigned long long fbf_sts_paddr;
    14881657
    14891658    if ( buffer_index == 0 )    // user buffer 0
    14901659    {
    1491         // INVAL L1 and L2 cache copies of user buffer descriptor,
     1660        buf_sts_paddr =
     1661            ((pdesc->buf0_desc & 0xFFF0000000000000ULL) >> 20) + // compute address extension
     1662            ((pdesc->buf0_desc & 0x3FFFFFFULL) << 6);            // compute 32 LSB of the address
     1663
     1664        buf_paddr =
     1665            (pdesc->buf0_desc & 0xFFFFFFFFFC000000ULL) >> 20;  // compute the entire address
     1666    }
     1667    else                        // user buffer 1
     1668    {
     1669        buf_sts_paddr =
     1670            ((pdesc->buf1_desc & 0xFFF0000000000000ULL) >> 20) +
     1671            ((pdesc->buf1_desc & 0x3FFFFFFULL) << 6);
     1672
     1673        buf_paddr =
     1674            (pdesc->buf1_desc & 0xFFFFFFFFFC000000ULL) >> 20;
     1675    }
     1676
     1677    fbf_sts_paddr =
     1678        ((pdesc->fbf_desc & 0xFFF0000000000000ULL) >> 20) +
     1679        ((pdesc->fbf_desc & 0x3FFFFFFULL) << 6);
     1680
     1681#if GIET_DEBUG_FBF_CMA
     1682_printf(" - fbf status paddr = %l\n"
     1683        " - buf        pbase = %l\n"
     1684        " - buf status paddr = %l\n",
     1685        fbf_sts_paddr,
     1686        buf_paddr,
     1687        buf_sts_paddr );
     1688#endif
     1689       
     1690    // waiting user buffer released by the CMA component)
     1691    while ( full )
     1692    { 
     1693        // INVAL L2 cache copy of user buffer descriptor,
    14921694        // because it has been modified in RAM by the CMA component
    1493         _dcache_buf_invalidate( (unsigned int)pdesc , sizeof(buffer_descriptor_t) );
    1494         _mmc_inval( _fbf_chbuf_paddr[channel] , sizeof(buffer_descriptor_t) );
    1495 
    1496         // waiting user buffer released by the CMA component)
    1497         while ( full )
    1498         { 
    1499             full = (unsigned int)(pdesc->buf0.desc >> 63);
    1500         }
    1501 
    1502         // SYNC request for the user buffer, because
    1503         // it will be read from XRAM by the CMA component
    1504         _mmc_sync( pdesc->buf0.desc , pdesc->length );
    1505 
    1506         // set user buffer status
    1507         pdesc->buf0.desc = pdesc->buf0.desc | 0x8000000000000000ULL;
    1508 
    1509         // reset fbf buffer status
    1510         pdesc->fbf.desc  = pdesc->fbf.desc  & 0x7FFFFFFFFFFFFFFFULL;
    1511 
    1512         // SYNC request, because these buffer descriptors
    1513         // will be read from XRAM by the CMA component
    1514         _mmc_sync( _fbf_chbuf_paddr[channel] , sizeof(fbf_chbuf_t) );
    1515     }
    1516     else                        // user buffer 1
    1517     {
    1518         // INVAL L1 and L2 cache copies of user buffer descriptor,
    1519         // because it has been modified in RAM by the CMA component
    1520         _dcache_buf_invalidate( (unsigned int)pdesc + 64, sizeof(buffer_descriptor_t) );
    1521         _mmc_inval( _fbf_chbuf_paddr[channel] + 64, sizeof(buffer_descriptor_t) );
    1522 
    1523         // waiting user buffer released by the CMA component)
    1524         while ( full )
    1525         { 
    1526             full = (unsigned int)(pdesc->buf1.desc >> 63);
    1527         }
    1528 
    1529         // SYNC request for the user buffer, because
    1530         // it will be read from XRAM by the CMA component
    1531         _mmc_sync( pdesc->buf1.desc , pdesc->length );
    1532 
    1533         // set user buffer status
    1534         pdesc->buf1.desc = pdesc->buf1.desc | 0x8000000000000000ULL;
    1535 
    1536         // reset fbf buffer status
    1537         pdesc->fbf.desc  = pdesc->fbf.desc  & 0x7FFFFFFFFFFFFFFFULL;
    1538 
    1539         // SYNC request, because these buffer descriptors
    1540         // will be read from XRAM by the CMA component
    1541         _mmc_sync( _fbf_chbuf_paddr[channel] , sizeof(fbf_chbuf_t) );
    1542     }
    1543 
    1544 #if GIET_DEBUG_FBF_CMA
    1545 _printf("\n[FBF_CMA DEBUG] exit _sys_fb_cma_display()\n"
    1546         " - buf0_desc value = %l\n"
    1547         " - buf1_desc value = %l\n"
    1548         " - fbf_desc  value = %l\n",
    1549         _fbf_chbuf[channel].buf0.desc,
    1550         _fbf_chbuf[channel].buf1.desc,
    1551         _fbf_chbuf[channel].fbf.desc );
    1552 #endif
     1695        _mmc_inval( buf_sts_paddr , 4 );       
     1696
     1697        full = _physical_read( buf_sts_paddr );
     1698    }
     1699
     1700    // SYNC request for the user buffer, because
     1701    // it will be read from XRAM by the CMA component
     1702    _mmc_sync( buf_paddr , pdesc->length );
     1703
     1704    // set user buffer status
     1705    _physical_write( buf_sts_paddr, 0x1 );
     1706
     1707    // reset fbf buffer status
     1708    _physical_write( fbf_sts_paddr, 0x0 );
     1709   
     1710    // SYNC request, because these buffer descriptors
     1711    // will be read from XRAM by the CMA component
     1712    _mmc_sync( buf_sts_paddr, 4 );
     1713    _mmc_sync( fbf_sts_paddr, 4 );
    15531714
    15541715    return 0;
     
    15611722#endif
    15621723} // end _sys_fbf_cma_display()
    1563 
    15641724
    15651725///////////////////////
  • soft/giet_vm/giet_kernel/sys_handler.h

    r556 r614  
    2424
    2525///////////////////////////////////////////////////////////////////////////////
    26 // This structure is used by the nic_chbuf_t and fbf_chbuf_t structures.
    27 // It describes a single buffer descriptor. The useful information is
    28 // contained in one single 64 bits word (desc field):
    29 // - the 48 LSB bits contain the buffer physical address
    30 // - the MSB bit 63 indicates the buffer state (empty if 0)
    31 // This descriptor must be aligned on a cache line (64 bytes) to simplify
     26// This structure is used by the CMA component to store the status of the
     27// frame buffer (full or empty). The useful information is contained in the
     28// "status" integer (1 for full and 0 for empty).
     29// This structure must be aligned on a cache line (64 bytes) to simplify
    3230// the software L2/L3 cache coherence when the IO bridge is used.
    3331///////////////////////////////////////////////////////////////////////////////
    3432
    35 typedef struct buffer_descriptor_s
     33typedef struct buffer_status_s
    3634{
    37     unsigned long long  desc;
    38     unsigned int        padding[14];
    39 } buffer_descriptor_t;
    40  
     35    unsigned int status;
     36    unsigned int padding[15];
     37} buffer_status_t;
     38
    4139///////////////////////////////////////////////////////////////////////////////
    4240// This structure is used by the CMA component to move a stream
     
    4543// - The SRC chbuf contains two buffers (buf0 & buf1), in user space.
    4644// - The DST cbuf contains one single buffer (fbf), that is the frame buffer.
    47 // - The length field define the buffer size (bytes)
     45// Each buffer is described with a 64 bits buffer descriptor:
     46// - the 26 LSB bits contain bits[6:31] of the buffer physical address
     47// - the 26 following bits contain bits[6:31] of the physical address where the
     48//   buffer status is located
     49// - the 12 MSB bits contain the common address extension of the buffer and its
     50//   status
     51// The length field define the buffer size (bytes)
    4852// This structure must be 64 bytes aligned.
    4953///////////////////////////////////////////////////////////////////////////////
     
    5155typedef struct fbf_chbuf_s
    5256{
    53     buffer_descriptor_t  buf0;         // first user buffer descriptor
    54     buffer_descriptor_t  buf1;         // second user buffer descriptor
    55     buffer_descriptor_t  fbf;          // frame buffer descriptor
    56     unsigned int         length;       // buffer length (bytes)
    57     unsigned int         padding[15];  // padding for 64 bytes alignment
     57    unsigned long long  buf0_desc;     // first user buffer descriptor
     58    unsigned long long  buf1_desc;     // second user buffer descriptor
     59    unsigned long long  fbf_desc;      // frame buffer descriptor
     60    unsigned int        length;        // buffer length (bytes)
     61    unsigned int        padding[9];    // padding for 64 bytes alignment
    5862} fbf_chbuf_t;   
    5963
     
    6569// The number of distributed containers can be smaller than (X_SIZE * YSIZE).
    6670// The actual number of buffers used in the chbuf is defined by (xmax * ymax).
     71// Each buffer is described with a 64 bits buffer descriptor:
     72// - the 26 LSB bits contain bits[6:31] of the buffer physical address
     73// - the 26 following bits contain bits[6:31] of the physical address where the
     74//   buffer status is located
     75// - the 12 MSB bits contain the common address extension of the buffer and its
     76//   status
    6777// This structure must be 64 bytes aligned.
    6878///////////////////////////////////////////////////////////////////////////////
    6979
    70 typedef struct nic_chbuf_s
     80typedef struct ker_chbuf_s
    7181{
    72     buffer_descriptor_t  buffer[X_SIZE*Y_SIZE];  // kernel chbuf
    73     unsigned int         xmax;                   // nb clusters in a row
    74     unsigned int         ymax;                   // nb clusters in a column
    75 } nic_chbuf_t;
     82    unsigned long long   buf_desc[X_SIZE*Y_SIZE]; // kernel chbuf descriptor
     83    unsigned int         xmax;                        // nb clusters in a row
     84    unsigned int         ymax;                        // nb clusters in a column
     85} ker_chbuf_t;
    7686
    7787
     
    171181int _sys_fbf_cma_alloc();
    172182
    173 int _sys_fbf_cma_start( void*        vbase0,
    174                         void*        vbase1, 
    175                         unsigned int length );
     183int _sys_fbf_cma_init_buf(void*        buf0_vbase,
     184                          void*        buf1_vbase,
     185                          void*        sts0_vaddr,
     186                          void*        sts1_vaddr );
     187
     188int _sys_fbf_cma_start( unsigned int length );
    176189
    177190int _sys_fbf_cma_display( unsigned int buffer_index );
Note: See TracChangeset for help on using the changeset viewer.