Changeset 725 for soft


Ignore:
Timestamp:
Nov 21, 2015, 2:28:31 PM (9 years ago)
Author:
alain
Message:

Modify FBF_CMA syscall handlers to support chbufs containing more than two buffers.

Location:
soft/giet_vm/giet_kernel
Files:
4 edited

Legend:

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

    r714 r725  
    2929extern fat_desc_t  _fat;
    3030
    31 //////////////////////////////////////////////////////////////////
     31/////////////////////////////////////////////////////////////////////////////////
    3232// This function is called by the _ctx_switch() function.
    3333// It desactivates a thread that received a KILL signal.
    3434// We must release all ressources allocated to the thread
    35 // before the actual desactivation, that uses NORUN_MASK_THREAD.
    36 //////////////////////////////////////////////////////////////////
     35// before the actual desactivation, that set the NORUN_MASK_THREAD
     36// bit in the thread context.
     37//////////////////////////////////////////////////////////////////////////////////
    3738static void _ctx_kill_thread( unsigned int x,
    3839                              unsigned int y,
  • soft/giet_vm/giet_kernel/kernel_init.c

    r709 r725  
    379379    ////////////////////////////////////////////////////////////////////////////
    380380
    381     if (threads == 0) _printf("\n[GIET WARNING] No thread allocated to P[%d,%d,%d]\n",
    382                             x, y, p );
    383 
    384381    // default value for ltid
    385382    ltid = IDLE_THREAD_INDEX;
  • soft/giet_vm/giet_kernel/sys_handler.c

    r719 r725  
    160160
    161161__attribute__((section(".kdata")))
    162 ker_chbuf_t  _nic_ker_rx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64)));
     162nic_chbuf_t  _nic_ker_rx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64)));
    163163
    164164__attribute__((section(".kdata")))
    165 ker_chbuf_t  _nic_ker_tx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64)));
     165nic_chbuf_t  _nic_ker_tx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64)));
    166166
    167167////////////////////////////////////////////////////////////////////////////
    168 // FBF related chbuf descriptors array, indexed by the CMA channel index.
    169 // Physical addresses of these chbuf descriptors required for L2 cache sync.
    170 // FBF status
     168//     FBF related chbuf
     169// The physical address of this chbuf is required for L2 cache sync.
    171170////////////////////////////////////////////////////////////////////////////
    172171
    173172__attribute__((section(".kdata")))
    174 fbf_chbuf_t _fbf_chbuf[NB_CMA_CHANNELS] __attribute__((aligned(64)));
     173fbf_chbuf_t          _fbf_ker_chbuf __attribute__((aligned(64)));
    175174
    176175__attribute__((section(".kdata")))
    177 unsigned long long _fbf_chbuf_paddr[NB_CMA_CHANNELS];
    178 
    179 __attribute__((section(".kdata")))
    180 buffer_status_t _fbf_status[NB_CMA_CHANNELS] __attribute__((aligned(64)));
     176unsigned long long   _fbf_chbuf_paddr;
    181177
    182178////////////////////////////////////////////////////////////////////////////
     
    203199    &_sys_fbf_cma_display,           /* 0x0D */
    204200    &_sys_fbf_cma_stop,              /* 0x0E */
    205     &_sys_ukn,                       /* 0x0F */
     201    &_sys_fbf_cma_check,             /* 0x0F */
    206202
    207203    &_sys_applications_status,       /* 0x10 */
     
    15741570    unsigned int trdid = _get_thread_trdid();
    15751571
    1576     // check no TTY already allocated to calling thread
    1577     if ( _get_context_slot( CTX_TTY_ID ) < NB_TTY_CHANNELS )
    1578     {
    1579         _printf("\n[GIET_ERROR] in _sys_tty_alloc() : "
    1580                 "TTY channel already allocated to thread %x\n", trdid );
    1581         return SYSCALL_CHANNEL_ALREADY_ALLOCATED;
    1582     }
    1583 
    15841572    mapping_header_t  *header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    15851573    mapping_vspace_t  *vspace   = _get_vspace_base(header);
     
    19631951                "xmax or ymax argument too large for thread %x\n", trdid );
    19641952
    1965         return SYSCALL_ILLEGAL_XY_ARGUMENTS;
     1953        return SYSCALL_ILLEGAL_ARGUMENT;
    19661954    }
    19671955
     
    22012189
    22022190    // sync the kernel chbuf in L2 after write in L2
    2203     _mmc_sync( ker_chbuf_pbase, sizeof( ker_chbuf_t ) );
     2191    _mmc_sync( ker_chbuf_pbase, sizeof( nic_chbuf_t ) );
    22042192
    22052193    ///////////////////////////////////////////////////////////////
     
    23722360    // start CMA transfer
    23732361    _cma_set_register( cma_channel, CHBUF_BUF_SIZE , NIC_CONTAINER_SIZE );
    2374     _cma_set_register( cma_channel, CHBUF_PERIOD   , 0 );     // OUT_OF_ORDER
    2375     _cma_set_register( cma_channel, CHBUF_RUN      , 1 );
     2362    _cma_set_register( cma_channel, CHBUF_PERIOD   , 0 );                  // OUT_OF_ORDER
     2363    _cma_set_register( cma_channel, CHBUF_RUN      , MODE_NORMAL );
    23762364
    23772365    // activates NIC channel
     
    24162404
    24172405    // get kernel chbuf virtual address
    2418     ker_chbuf_t* ker_chbuf;
     2406    nic_chbuf_t* ker_chbuf;
    24192407    if ( is_rx )  ker_chbuf = &_nic_ker_rx_chbuf[channel];
    24202408    else          ker_chbuf = &_nic_ker_tx_chbuf[channel];
     
    24362424         cx , cy , xmax , ymax );
    24372425
    2438         return SYSCALL_ILLEGAL_XY_ARGUMENTS;
     2426        return SYSCALL_ILLEGAL_ARGUMENT;
    24392427    }
    24402428   
     
    25862574
    25872575    // desactivates the CMA channel
    2588     _cma_set_register( cma_channel, CHBUF_RUN , 0 );
     2576    _cma_set_register( cma_channel, CHBUF_RUN , MODE_IDLE );
    25892577
    25902578    // wait until CMA channel IDLE
     
    28532841}
    28542842
    2855 ////////////////////////
    2856 int _sys_fbf_cma_alloc()
    2857 {
     2843////////////////////////////////////////////
     2844int _sys_fbf_cma_alloc( unsigned int nbufs )
     2845{
     2846    // compute trdid and vsid for the calling thread
     2847    unsigned int vsid  = _get_context_slot( CTX_VSID_ID );
    28582848    unsigned int trdid = _get_thread_trdid();
    28592849
     
    28622852        _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : "
    28632853                "CMA channel already allocated for thread %x\n", trdid );
    2864 
    28652854        return SYSCALL_CHANNEL_ALREADY_ALLOCATED;
    28662855    }
     2856
     2857    // compute number of threads in vspace from mapping
     2858    mapping_header_t  *header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     2859    mapping_vspace_t  *vspace   = _get_vspace_base(header);
     2860    mapping_thread_t  *thread   = _get_thread_base(header);
     2861    unsigned int      first     = vspace[vsid].thread_offset;
     2862    unsigned int      threads   = vspace[vsid].threads;
    28672863
    28682864    // get a CMA channel
     
    28712867    {
    28722868        unsigned int*  palloc = &_cma_channel_alloc[channel];
    2873         if ( _atomic_test_and_set( palloc , 1 ) == 0 ) break;
    2874     }
     2869        if ( _atomic_test_and_set( palloc , threads ) == 0 ) break;
     2870    }
     2871
    28752872    if ( channel >= NB_CMA_CHANNELS )
    28762873    {
    28772874        _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : no CMA channel available\n");
    2878 
    28792875        return SYSCALL_NO_CHANNEL_AVAILABLE;
    28802876    }
    2881     else
    2882     {
    2883         _set_context_slot( CTX_CMA_FB_ID, channel );
    2884 
    2885         return SYSCALL_OK;
    2886     }
     2877
     2878    // check nbufs argument
     2879    if ( nbufs > 256 )
     2880    {
     2881        _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : nbufs larger than 256\n");
     2882        return SYSCALL_ILLEGAL_ARGUMENT;
     2883    }
     2884
     2885    // loop on all threads to register channel in thread contexts
     2886    unsigned int      tid;
     2887    for ( tid = first ; tid < (first + threads) ; tid++ )
     2888    {
     2889        unsigned int         y_size = header->y_size;
     2890        unsigned int         cid    = thread[tid].clusterid;
     2891        unsigned int         x      = cid / y_size;
     2892        unsigned int         y      = cid % y_size;
     2893        unsigned int         p      = thread[tid].proclocid;
     2894        unsigned int         ltid   = thread[tid].ltid;
     2895        static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
     2896        psched->context[ltid].slot[CTX_CMA_FB_ID] = channel;
     2897    }
     2898
     2899    unsigned int vaddr;
     2900    unsigned int flags;
     2901
     2902    // compute frame buffer physical addresses
     2903    vaddr = (unsigned int)SEG_FBF_BASE;
     2904    unsigned long long fbf_buf_paddr = _v2p_translate( vaddr , &flags );
     2905
     2906    // initialize the FBF chbuf
     2907    // we don't register a status address in the fbf_desc, because
     2908    // the CMA does not test the status for the frame buffer (no synchro)
     2909    _fbf_ker_chbuf.nbufs    = nbufs;
     2910    _fbf_ker_chbuf.fbf_desc = (((fbf_buf_paddr & 0xFFFFFFFFFFFULL) >> 6 ) << 26);
     2911
     2912    // register FBF chbuf physical address
     2913    vaddr = (unsigned int)(&_fbf_ker_chbuf);
     2914    _fbf_chbuf_paddr = _v2p_translate( vaddr , &flags );
     2915
     2916#if GIET_DEBUG_FBF_CMA
     2917_printf("\n[FBF_CMA DEBUG] _sys_fbf_cma_alloc()\n"
     2918        " - channel               = %d\n"
     2919        " - vaddr(_ker_fbf_chbuf) = %x\n"
     2920        " - paddr(_ker_fbf_chbuf) = %l\n"
     2921        " - nbufs                 = %d\n"
     2922        " - fbf_desc              = %l\n",
     2923        channel , vaddr , _fbf_chbuf_paddr , nbufs , _fbf_ker_chbuf.fbf_desc );
     2924#endif
     2925
     2926    return SYSCALL_OK;
    28872927} // end sys_fbf_cma_alloc()
    28882928
    28892929//////////////////////////
    2890 int _sys_fbf_cma_release()  // Not a syscall
     2930int _sys_fbf_cma_release()  // Not a syscall : used by _ctx_kill_thread()
    28912931{
    28922932    unsigned int channel = _get_context_slot( CTX_CMA_FB_ID );
     
    29012941    }
    29022942
    2903     // stop CMA transfer
    2904     _sys_fbf_cma_stop();
    2905 
    2906     // reset CTX_CMA_FB_ID for thread
     2943    if ( _cma_channel_alloc[channel] == 1 )  // the calling thread is the last user
     2944    {
     2945        // stop the CMA transfer
     2946        _sys_fbf_cma_stop();
     2947
     2948        // reset the CMA channel allocator
     2949        _cma_channel_alloc[channel] = 0;
     2950    }
     2951    else                                     // not the last user
     2952    {
     2953        // atomically decrement the CMA channel allocator
     2954        _atomic_increment( &_cma_channel_alloc[channel] , -1 );
     2955    }
     2956
     2957    // reset CTX_CMA_FB_ID slot in calling thread context
    29072958    _set_context_slot( CTX_CMA_FB_ID, 0xFFFFFFFF );
    29082959
    2909     // release CMA channel
    2910     _cma_channel_alloc[channel] = 0;
    2911 
    29122960    return SYSCALL_OK;
    2913 }
     2961} // end _sys_fbf_cma_release()
    29142962
    29152963///////////////////////////////////////////////////
    2916 int _sys_fbf_cma_init_buf( void*        buf0_vbase,
    2917                            void*        buf1_vbase,
    2918                            void*        sts0_vaddr,
    2919                            void*        sts1_vaddr )
     2964int _sys_fbf_cma_init_buf( unsigned int index,
     2965                           void*        buf_vaddr,
     2966                           void*        sts_vaddr )
    29202967{
    29212968    unsigned int       vaddr;           // virtual address
    29222969    unsigned int       flags;           // for _v2p_translate()
    2923     unsigned long long fbf_paddr;       // fbf physical address
    2924     unsigned long long fbf_sts_paddr;   // fbf status physical address
    2925     unsigned long long buf0_pbase;      // buffer 0 base physical address
    2926     unsigned long long sts0_paddr;      // buffer 0 status physical address
    2927     unsigned long long buf1_pbase;      // buffer 1 base physical address
    2928     unsigned long long sts1_paddr;      // buffer 1 status physical address
     2970    unsigned long long buf_paddr;       // user buffer physical address
     2971    unsigned long long sts_paddr;       // user status physical address
    29292972
    29302973    // get calling thread scheduler, ltid and trdid
     
    29552998#if GIET_DEBUG_FBF_CMA
    29562999_printf("\n[FBF_CMA DEBUG] _sys_fbf_cma_init_buf()\n"
    2957         " - channel           = %d\n"
    2958         " - buf0        vbase = %x\n"
    2959         " - buf1        vbase = %x\n"
    2960         " - sts0        vaddr = %x\n"
    2961         " - sts1        vaddr = %x\n",
    2962         channel,
    2963         (unsigned int)buf0_vbase,
    2964         (unsigned int)buf1_vbase,
    2965         (unsigned int)sts0_vaddr,
    2966         (unsigned int)sts1_vaddr );
    2967 #endif
    2968 
    2969     // checking user buffers virtual addresses alignment
    2970     if ( ((unsigned int)buf0_vbase & 0x3F) ||
    2971          ((unsigned int)buf1_vbase & 0x3F) )
     3000        " - channel     = %d / index = %d\n"
     3001        " - buf vaddr   = %x\n"
     3002        " - sts vaddr   = %x\n",
     3003        channel, index,
     3004        (unsigned int)buf_vaddr,
     3005        (unsigned int)sts_vaddr );
     3006#endif
     3007
     3008    // checking index argument
     3009    if ( index >= _fbf_ker_chbuf.nbufs )
    29723010    {
    29733011        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : "
    2974                 "user buffer not aligned for thread %x\n", trdid );
     3012                "user buffer index too large %x\n", trdid );
     3013
     3014        return SYSCALL_CHANNEL_NON_ALLOCATED;
     3015    }
     3016
     3017    // checking user buffer and status addresses alignment
     3018    if ( ((unsigned int)buf_vaddr & 0x3F) || ((unsigned int)sts_vaddr & 0x3F) )
     3019    {
     3020        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : "
     3021                "user buffer or status not aligned for thread %x\n", trdid );
    29753022
    29763023        return SYSCALL_ADDRESS_NON_ALIGNED;
    29773024    }
    29783025
    2979     // checking user buffers status virtual addresses alignment
    2980     if ( ((unsigned int)sts0_vaddr & 0x3F) ||
    2981          ((unsigned int)sts1_vaddr & 0x3F) )
     3026    // Compute user buffer and status physical addresses
     3027    vaddr = (unsigned int)buf_vaddr;
     3028    buf_paddr = _v2p_translate( vaddr , &flags );
     3029    if ((flags & PTE_U) == 0)
    29823030    {
    29833031        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : "
    2984                 "user status not aligned for thread %x\n", trdid );
    2985 
    2986         return SYSCALL_ADDRESS_NON_ALIGNED;
    2987     }
    2988 
    2989     // compute frame buffer physical address and initialize _fbf_chbuf[channel]
    2990     vaddr = (unsigned int)SEG_FBF_BASE;
    2991     fbf_paddr = _v2p_translate( vaddr , &flags );
    2992     vaddr = (unsigned int)&_fbf_status[channel];
    2993     fbf_sts_paddr = _v2p_translate( vaddr , &flags );
    2994 
    2995     _fbf_chbuf[channel].fbf_desc =
    2996         (unsigned long long) ((fbf_sts_paddr & 0xFFFFFFFFULL) >> 6) +
    2997         (((fbf_paddr & 0xFFFFFFFFULL) >> 6 ) << 26);
    2998 
    2999     // Compute user buffer 0 physical addresses and intialize _fbf_chbuf[channel]
    3000     vaddr = (unsigned int)buf0_vbase;
    3001     buf0_pbase = _v2p_translate( vaddr , &flags );
     3032                "buffer not in user space for thread %x\n", trdid );
     3033
     3034        return SYSCALL_ADDRESS_NON_USER_ACCESSIBLE;
     3035    }
     3036
     3037    vaddr = (unsigned int)sts_vaddr;
     3038    sts_paddr = _v2p_translate( vaddr , &flags );
    30023039    if ((flags & PTE_U) == 0)
    30033040    {
    30043041        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : "
    3005                 "buf0 not in user space for thread %x\n", trdid );
     3042                "status not in user space for thread %x\n", trdid);
    30063043
    30073044        return SYSCALL_ADDRESS_NON_USER_ACCESSIBLE;
    30083045    }
    30093046
    3010     vaddr = (unsigned int)sts0_vaddr;
    3011     sts0_paddr = _v2p_translate( vaddr , &flags );
    3012     if ((flags & PTE_U) == 0)
     3047    // check user buffer and user status in same cluster
     3048    if ( (buf_paddr & 0xFF00000000ULL) != (sts_paddr & 0xFF00000000ULL) )
    30133049    {
    30143050        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : "
    3015                 "sts0 not in user space for thread %x\n", trdid);
     3051                "user status and buffer not in same cluster for thread %x\n", trdid);
    30163052
    30173053        return SYSCALL_ADDRESS_NON_USER_ACCESSIBLE;
    30183054    }
    30193055
    3020     _fbf_chbuf[channel].buf0_desc =
    3021         (unsigned long long) ((sts0_paddr & 0xFFFFFFFFULL) >> 6) +
    3022         (((buf0_pbase & 0xFFFFFFFFULL) >> 6 ) << 26);
    3023 
    3024     // Compute user buffer 1 physical addresses and intialize _fbf_chbuf[channel]
    3025     vaddr = (unsigned int)buf1_vbase;
    3026     buf1_pbase = _v2p_translate( vaddr , &flags );
    3027     if ((flags & PTE_U) == 0)
    3028     {
    3029         _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : "
    3030                 "buf1 not in user space for thread %x\n", trdid );
    3031 
    3032         return SYSCALL_ADDRESS_NON_USER_ACCESSIBLE;
    3033     }
    3034 
    3035     vaddr = (unsigned int)sts1_vaddr;
    3036     sts1_paddr = _v2p_translate( vaddr , &flags );
    3037     if ((flags & PTE_U) == 0)
    3038     {
    3039         _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : "
    3040                 "sts1 not in user space for thread %x\n", trdid);
    3041 
    3042         return SYSCALL_ADDRESS_NON_USER_ACCESSIBLE;
    3043     }
    3044 
    3045     _fbf_chbuf[channel].buf1_desc =
    3046         (unsigned long long) ((sts1_paddr & 0xFFFFFFFFULL) >> 6) +
    3047         (((buf1_pbase & 0xFFFFFFFFULL) >> 6 ) << 26);
    3048 
    3049     // Compute and register physical adress of the fbf_chbuf descriptor
    3050     vaddr = (unsigned int)&_fbf_chbuf[channel];
    3051     _fbf_chbuf_paddr[channel] = _v2p_translate( vaddr , &flags );
    3052  
     3056    // initialize _fbf_ker_chbuf.usr_desc[index]
     3057    _fbf_ker_chbuf.usr_desc[index] = ((sts_paddr & 0xFFFFFFFFULL) >> 6) +
     3058                                     (((buf_paddr & 0xFFFFFFFFFFULL) >> 6 ) << 26);
     3059
    30533060#if GIET_DEBUG_FBF_CMA
    3054 _printf(" - fbf         pbase = %l\n"
    3055         " - fbf status  paddr = %l\n"
    3056         " - buf0        pbase = %l\n"
    3057         " - buf0 status paddr = %l\n"
    3058         " - buf1        pbase = %l\n"
    3059         " - buf0 status paddr = %l\n"
    3060         " - chbuf       pbase = %l\n",
    3061         fbf_paddr,
    3062         fbf_sts_paddr,
    3063         buf0_pbase,
    3064         sts0_paddr,
    3065         buf1_pbase,
    3066         sts1_paddr,
    3067         _fbf_chbuf_paddr[channel] );
     3061_printf(" - buf paddr   = %l\n"
     3062        " - sts paddr   = %l\n"
     3063        " - usr_desc[%d] = %l\n",
     3064        buf_paddr,
     3065        sts_paddr,
     3066        index , _fbf_ker_chbuf.usr_desc[index] );
    30683067#endif
    30693068
     
    30723071} // end sys_fbf_cma_init_buf()
    30733072
    3074 ////////////////////////////////////////////
    3075 int _sys_fbf_cma_start( unsigned int length )
     3073////////////////////////
     3074int _sys_fbf_cma_start()
    30763075{
    30773076    // get calling thread scheduler, ltid and trdid
     
    30893088    }
    30903089
    3091     // get channel index
     3090    // get CMA channel index
    30923091    unsigned int channel = _get_context_slot( CTX_CMA_FB_ID );
    30933092
     
    31013100
    31023101    // check buffers initialization
    3103     if ( ( _fbf_chbuf[channel].buf0_desc == 0x0ULL ) &&
    3104          ( _fbf_chbuf[channel].buf1_desc == 0x0ULL) &&
    3105          ( _fbf_chbuf[channel].fbf_desc == 0x0ULL) )
    3106     {
    3107         _printf("\n[GIET ERROR] in _sys_fbf_cma_start(): initialization not done\n");
     3102    if ( _fbf_ker_chbuf.nbufs == 0 )
     3103    {
     3104        _printf("\n[GIET ERROR] in _sys_fbf_cma_start(): "
     3105                "FBF chbuf not initialized for thread %x\n", trdid );
    31083106
    31093107        return SYSCALL_MISSING_INITIALISATION;
    31103108    }
    31113109
    3112     // initializes buffer length
    3113     _fbf_chbuf[channel].length = length;
    3114 
     3110    // synchronize FBF chbuf that will be read by CMA peripheral
    31153111    if ( USE_IOB )
    31163112    {
    31173113        // SYNC request for fbf_chbuf descriptor
    3118         _mmc_sync( _fbf_chbuf_paddr[channel] , sizeof( fbf_chbuf_t ) );
     3114        _mmc_sync( _fbf_chbuf_paddr , sizeof( fbf_chbuf_t ) );
    31193115    }
    31203116
    31213117    // start CMA transfer
    3122     unsigned long long paddr = _fbf_chbuf_paddr[channel];
    3123     unsigned int src_chbuf_paddr_lsb = (unsigned int)(paddr & 0xFFFFFFFF);
    3124     unsigned int src_chbuf_paddr_ext = (unsigned int)(paddr >> 32);
    3125     unsigned int dst_chbuf_paddr_lsb = src_chbuf_paddr_lsb + 16;
    3126     unsigned int dst_chbuf_paddr_ext = src_chbuf_paddr_ext;
     3118    unsigned long long paddr = _fbf_chbuf_paddr;
     3119    unsigned int dst_chbuf_paddr_lsb = (unsigned int)(paddr & 0xFFFFFFFF);
     3120    unsigned int dst_chbuf_paddr_ext = (unsigned int)(paddr >> 32);
     3121    unsigned int src_chbuf_paddr_lsb = dst_chbuf_paddr_lsb + 8;
     3122    unsigned int src_chbuf_paddr_ext = dst_chbuf_paddr_ext;
     3123
     3124#if GIET_DEBUG_FBF_CMA
     3125_printf("\n[FBF_CMA DEBUG] _sys_fbf_cma_start()\n"
     3126        " - src_chbuf_paddr_lsb = %x\n"
     3127        " - src_chbuf_paddr_ext = %x\n"
     3128        " - src_chbuf_nbufs     = %d\n"
     3129        " - dst_chbuf_paddr_lsb = %x\n"
     3130        " - dst_chbuf_paddr_ext = %x\n"
     3131        " - dst_chbuf_nbufs     = 1 \n"
     3132        " - buffer_size         = %d\n",
     3133        src_chbuf_paddr_lsb,
     3134        src_chbuf_paddr_ext,
     3135        _fbf_ker_chbuf.nbufs,
     3136        dst_chbuf_paddr_lsb,
     3137        dst_chbuf_paddr_ext,
     3138        FBUF_X_SIZE * FBUF_Y_SIZE );
     3139#endif
    31273140
    31283141    _cma_set_register( channel, CHBUF_SRC_DESC , src_chbuf_paddr_lsb );
    31293142    _cma_set_register( channel, CHBUF_SRC_EXT  , src_chbuf_paddr_ext );
    3130     _cma_set_register( channel, CHBUF_SRC_NBUFS, 2 );
     3143    _cma_set_register( channel, CHBUF_SRC_NBUFS, _fbf_ker_chbuf.nbufs );
    31313144    _cma_set_register( channel, CHBUF_DST_DESC , dst_chbuf_paddr_lsb );
    31323145    _cma_set_register( channel, CHBUF_DST_EXT  , dst_chbuf_paddr_ext );
    31333146    _cma_set_register( channel, CHBUF_DST_NBUFS, 1 );
    3134     _cma_set_register( channel, CHBUF_BUF_SIZE , length );
     3147    _cma_set_register( channel, CHBUF_BUF_SIZE , FBUF_X_SIZE*FBUF_Y_SIZE );
    31353148    _cma_set_register( channel, CHBUF_PERIOD   , 300 );
    3136     _cma_set_register( channel, CHBUF_RUN      , 1 );
     3149    _cma_set_register( channel, CHBUF_RUN      , MODE_NO_DST_SYNC );
    31373150
    31383151    return SYSCALL_OK;
     
    31403153} // end _sys_fbf_cma_start()
    31413154
    3142 /////////////////////////////////////////////////////
    3143 int _sys_fbf_cma_display( unsigned int buffer_index )
    3144 {
    3145     volatile unsigned int full = 1;
    3146 
     3155////////////////////////////////////////////
     3156int _sys_fbf_cma_check( unsigned int index )
     3157{
    31473158    // get calling thread scheduler, ltid and trdid
    31483159    static_scheduler_t*  psched = _get_sched();
     
    31533164    if ( (psched->context[ltid].slot[CTX_LOCKS_ID] & LOCKS_MASK_FBF) == 0 )
    31543165    {
    3155         _printf("\n[GIET ERROR] in _sys_fbf_release() : "
     3166        _printf("\n[GIET ERROR] in _sys_fbf_cma_check() : "
    31563167                "FBF not allocated to thread %x\n", trdid );
    31573168
     
    31643175    if ( channel >= NB_CMA_CHANNELS )
    31653176    {
    3166         _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : "
    3167                 "CMA channel non allocated\n");
     3177        _printf("\n[GIET ERROR] in _sys_fbf_cma_check() : "
     3178                "CMA channel non allocated to thread %x\n", trdid );
    31683179
    31693180        return SYSCALL_CHANNEL_NON_ALLOCATED;
    31703181    }
    31713182
    3172     // get fbf_chbuf descriptor pointer
    3173     fbf_chbuf_t* pdesc = &_fbf_chbuf[channel];     
     3183    // check buffer index
     3184    if ( index >= _fbf_ker_chbuf.nbufs )
     3185    {
     3186        _printf("\n[GIET ERROR] in _sys_fbf_cma_check() : "
     3187                "buffer index too large for thread %x\n", trdid );
     3188
     3189        return SYSCALL_CHANNEL_NON_ALLOCATED;
     3190    }
     3191
     3192    // compute user buffer status physical addresses
     3193    unsigned long long usr_sts_paddr;
     3194    fbf_chbuf_t* pdesc = &_fbf_ker_chbuf;     
     3195    usr_sts_paddr = ((pdesc->usr_desc[index] & 0xFFF0000000000000ULL) >> 20) + 
     3196                    ((pdesc->usr_desc[index] & 0x3FFFFFFULL) << 6);         
    31743197
    31753198#if GIET_DEBUG_FBF_CMA
    3176 _printf("\n[FBF_CMA DEBUG] enters _sys_fb_cma_display()\n"
     3199_printf("\n[FBF_CMA DEBUG] enters _sys_fbf_cma_check()\n"
    31773200        " - cma channel      = %d\n"
    31783201        " - buffer index     = %d\n"
    3179         " - buf0_desc value  = %l\n"
    3180         " - buf1_desc value  = %l\n"
    3181         " - fbf_desc  value  = %l\n",
    3182         channel , buffer_index,
    3183         _fbf_chbuf[channel].buf0_desc,
    3184         _fbf_chbuf[channel].buf1_desc,
    3185         _fbf_chbuf[channel].fbf_desc );
    3186 #endif
    3187 
    3188     unsigned long long buf_sts_paddr;
    3189     unsigned long long buf_paddr;
    3190     unsigned long long fbf_sts_paddr;
    3191 
    3192     if ( buffer_index == 0 )    // user buffer 0
    3193     {
    3194         buf_sts_paddr =
    3195             ((pdesc->buf0_desc & 0xFFF0000000000000ULL) >> 20) + // compute address extension
    3196             ((pdesc->buf0_desc & 0x3FFFFFFULL) << 6);            // compute 32 LSB of the address
    3197 
    3198         buf_paddr =
    3199             (pdesc->buf0_desc & 0xFFFFFFFFFC000000ULL) >> 20;  // compute the entire address
    3200     }
    3201     else                        // user buffer 1
    3202     {
    3203         buf_sts_paddr =
    3204             ((pdesc->buf1_desc & 0xFFF0000000000000ULL) >> 20) +
    3205             ((pdesc->buf1_desc & 0x3FFFFFFULL) << 6);
    3206 
    3207         buf_paddr =
    3208             (pdesc->buf1_desc & 0xFFFFFFFFFC000000ULL) >> 20;
    3209     }
    3210 
    3211     fbf_sts_paddr =
    3212         ((pdesc->fbf_desc & 0xFFF0000000000000ULL) >> 20) +
    3213         ((pdesc->fbf_desc & 0x3FFFFFFULL) << 6);
    3214 
    3215 #if GIET_DEBUG_FBF_CMA
    3216 _printf(" - fbf status paddr = %l\n"
    3217         " - buf        pbase = %l\n"
    3218         " - buf status paddr = %l\n",
    3219         fbf_sts_paddr,
    3220         buf_paddr,
    3221         buf_sts_paddr );
    3222 #endif
    3223        
     3202        " - usr_desc value   = %l\n"
     3203        " - fbf_desc value   = %l\n"
     3204        " - usr status paddr = %l\n",
     3205        channel,
     3206        index,
     3207        _fbf_ker_chbuf.usr_desc[index],
     3208        _fbf_ker_chbuf.fbf_desc,
     3209        usr_sts_paddr );
     3210#endif
     3211
    32243212    // waiting user buffer released by the CMA component)
    3225     while ( full )
     3213    unsigned int full;
     3214    do
    32263215    { 
    32273216        // INVAL L2 cache copy of user buffer status     
    3228         // because it has been modified in RAM by the CMA component
    3229         _mmc_inval( buf_sts_paddr , 4 );       
    3230 
    3231         full = _physical_read( buf_sts_paddr );
    3232     }
    3233 
    3234     // SYNC request for the user buffer, because
    3235     // it will be read from XRAM by the CMA component
    3236     _mmc_sync( buf_paddr , pdesc->length );
     3217        // because it is modified in RAM by the CMA component
     3218        _mmc_inval( usr_sts_paddr , 4 );       
     3219
     3220        full = _physical_read( usr_sts_paddr );
     3221    }
     3222    while ( full );
     3223
     3224    return SYSCALL_OK;
     3225
     3226}  // end _sys_fbf_cma_check()
     3227
     3228//////////////////////////////////////////////
     3229int _sys_fbf_cma_display( unsigned int index )
     3230{
     3231    // get calling thread scheduler, ltid and trdid
     3232    static_scheduler_t*  psched = _get_sched();
     3233    unsigned int         ltid   = _get_thread_ltid();
     3234    unsigned int         trdid  = _get_thread_trdid();
     3235
     3236    // check FBF allocated
     3237    if ( (psched->context[ltid].slot[CTX_LOCKS_ID] & LOCKS_MASK_FBF) == 0 )
     3238    {
     3239        _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : "
     3240                "FBF not allocated to thread %x\n", trdid );
     3241
     3242        return SYSCALL_CHANNEL_NON_ALLOCATED;
     3243    }
     3244
     3245    // get channel index
     3246    unsigned int channel = _get_context_slot( CTX_CMA_FB_ID );
     3247
     3248    if ( channel >= NB_CMA_CHANNELS )
     3249    {
     3250        _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : "
     3251                "CMA channel non allocated to thread %x\n", trdid );
     3252
     3253        return SYSCALL_CHANNEL_NON_ALLOCATED;
     3254    }
     3255
     3256    // check buffer index
     3257    if ( index >= _fbf_ker_chbuf.nbufs )
     3258    {
     3259        _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : "
     3260                "buffer index too large for thread %x\n", trdid );
     3261
     3262        return SYSCALL_CHANNEL_NON_ALLOCATED;
     3263    }
     3264
     3265    // compute user buffer and status physical addresses
     3266    unsigned long long usr_sts_paddr;
     3267    unsigned long long usr_buf_paddr;
     3268
     3269    fbf_chbuf_t* pdesc = &_fbf_ker_chbuf;     
     3270
     3271    usr_sts_paddr = ((pdesc->usr_desc[index] & 0xFFF0000000000000ULL) >> 20) + 
     3272                    ((pdesc->usr_desc[index] & 0x3FFFFFFULL) << 6);         
     3273
     3274    usr_buf_paddr = ((pdesc->usr_desc[index] & 0xFFFFFFFFFC000000ULL) >> 20);
     3275
     3276#if GIET_DEBUG_FBF_CMA
     3277_printf("\n[FBF_CMA DEBUG] enters _sys_fbf_cma_display()\n"
     3278        " - cma channel      = %d\n"
     3279        " - buffer index     = %d\n"
     3280        " - usr buffer paddr = %l\n"
     3281        " - usr status paddr = %l\n",
     3282        channel,
     3283        index,
     3284        usr_buf_paddr,
     3285        usr_sts_paddr );
     3286#endif
     3287       
     3288    // SYNC request, because this buffer will be read from XRAM by the CMA component
     3289    _mmc_sync( usr_buf_paddr , FBUF_X_SIZE * FBUF_Y_SIZE );
    32373290
    32383291    // set user buffer status
    3239     _physical_write( buf_sts_paddr, 0x1 );
    3240 
    3241     // reset fbf buffer status
    3242     _physical_write( fbf_sts_paddr, 0x0 );
    3243    
    3244     // SYNC request, because these buffer descriptors
    3245     // will be read from XRAM by the CMA component
    3246     _mmc_sync( buf_sts_paddr, 4 );
    3247     _mmc_sync( fbf_sts_paddr, 4 );
     3292    _physical_write( usr_sts_paddr, 0x1 );
     3293
     3294    // SYNC request, because this status will be read from XRAM by the CMA component
     3295    _mmc_sync( usr_sts_paddr, 4 );
    32483296
    32493297    return SYSCALL_OK;
     
    32653313
    32663314    // Desactivate CMA channel
    3267     _cma_set_register( channel, CHBUF_RUN, 0 );
     3315    _cma_set_register( channel, CHBUF_RUN, MODE_IDLE );
    32683316
    32693317    return SYSCALL_OK;
  • soft/giet_vm/giet_kernel/sys_handler.h

    r714 r725  
    5151#define SYSCALL_NO_CHANNEL_AVAILABLE             (-18)
    5252#define SYSCALL_CHANNEL_NON_ALLOCATED            (-19)
    53 #define SYSCALL_ILLEGAL_XY_ARGUMENTS             (-20)
     53#define SYSCALL_ILLEGAL_ARGUMENT                 (-20)
    5454#define SYSCALL_OUT_OF_KERNEL_HEAP_MEMORY        (-21)
    5555#define SYSCALL_ADDRESS_NON_ALIGNED              (-22)
     
    6464
    6565///////////////////////////////////////////////////////////////////////////////
    66 // This structure is used by the CMA component to store the status of the
    67 // frame buffer (full or empty). The useful information is contained in the
    68 // "status" integer (1 for full and 0 for empty).
    69 // This structure must be aligned on a cache line (64 bytes) to simplify
    70 // the software L2/L3 cache coherence when the IO bridge is used.
    71 ///////////////////////////////////////////////////////////////////////////////
    72 
    73 typedef struct buffer_status_s
    74 {
    75     unsigned int status;
    76     unsigned int padding[15];
    77 } buffer_status_t;
    78 
    79 ///////////////////////////////////////////////////////////////////////////////
    80 // This structure is used by the CMA component to move a stream
    81 // of images from two user buffers to the frame buffer in kernel space.
     66// This structure is used by the CMA component to move a stream of images
     67// from a set of user buffers to the frame buffer in kernel space.
    8268// It contains two chbuf arrays:
    83 // - The SRC chbuf contains two buffers (buf0 & buf1), in user space.
    84 // - The DST cbuf contains one single buffer (fbf), that is the frame buffer.
     69// - The SRC chbuf contains <nbufs> buffer descriptors, in user space,
     70//   that can be distributed (one buffer per cluster) or not.
     71// - The DST cbuf contains one single buffer, that is the frame buffer.
    8572// Each buffer is described with a 64 bits buffer descriptor:
    86 // - the 26 LSB bits contain bits[6:31] of the buffer physical address
    87 // - the 26 following bits contain bits[6:31] of the physical address where the
    88 //   buffer status is located
    89 // - the 12 MSB bits contain the common address extension of the buffer and its
    90 //   status
    91 // The length field define the buffer size (bytes)
     73// - the 26 LSB bits contain bits[31:6] of the status physical address.
     74// - the 26 following bits contain bits[31:6] of the buffer physical address.
     75// - the 12 MSB bits contain the common address extension.
     76// The actual number of user buffers cannot be larger than 256 (at most
     77// one user buffer per cluster for a 16*16 mesh).
     78// NB: The user buffers are mapped in user space, but the chbuf descriptor
     79// contained in this structure is a protected kernel variable.
    9280// This structure must be 64 bytes aligned.
    9381///////////////////////////////////////////////////////////////////////////////
     
    9583typedef struct fbf_chbuf_s
    9684{
    97     unsigned long long  buf0_desc;     // first user buffer descriptor
    98     unsigned long long  buf1_desc;     // second user buffer descriptor
    99     unsigned long long  fbf_desc;      // frame buffer descriptor
    100     unsigned int        length;        // buffer length (bytes)
    101     unsigned int        padding[9];    // padding for 64 bytes alignment
     85    unsigned long long  fbf_desc;                    // frame buffer descriptor
     86    unsigned long long  usr_desc[256];               // user chbuf descriptor
     87    unsigned int        nbufs;                       // number of user buffers
    10288} fbf_chbuf_t;   
    10389
     
    11096// The actual number of buffers used in the chbuf is defined by (xmax * ymax).
    11197// Each buffer is described with a 64 bits buffer descriptor:
    112 // - the 26 LSB bits contain bits[6:31] of the buffer physical address
    113 // - the 26 following bits contain bits[6:31] of the physical address where the
    114 //   buffer status is located
    115 // - the 12 MSB bits contain the common address extension of the buffer and its
    116 //   status
     98// - the 26 LSB bits contain bits[31:6] of the status physical address.
     99// - the 26 following bits contain bits[31:6] of the buffer physical address.
     100// - the 12 MSB bits contain the common address extension.
     101// The <xmax> and <ymax> fields define the actual mesh size.
    117102// This structure must be 64 bytes aligned.
    118103///////////////////////////////////////////////////////////////////////////////
    119104
    120 typedef struct ker_chbuf_s
     105typedef struct nic_chbuf_s
    121106{
    122     unsigned long long   buf_desc[X_SIZE*Y_SIZE]; // kernel chbuf descriptor
     107    unsigned long long   buf_desc[X_SIZE*Y_SIZE];     // kernel chbuf descriptor
    123108    unsigned int         xmax;                        // nb clusters in a row
    124109    unsigned int         ymax;                        // nb clusters in a column
    125 } ker_chbuf_t;
     110} nic_chbuf_t;
    126111
    127112
     
    236221
    237222extern int _sys_fbf_sync_write( unsigned int offset,
    238                          void*        buffer,
    239                          unsigned int length );
     223                                void*        buffer,
     224                                unsigned int length );
    240225
    241226extern int _sys_fbf_sync_read(  unsigned int offset,
    242                          void*        buffer,
    243                          unsigned int length );
    244 
    245 extern int _sys_fbf_cma_alloc();
     227                                void*        buffer,
     228                                unsigned int length );
     229
     230extern int _sys_fbf_cma_alloc( unsigned int nbufs );
    246231
    247232extern int _sys_fbf_cma_release();
    248233
    249 extern int _sys_fbf_cma_init_buf(void*        buf0_vbase,
    250                                  void*        buf1_vbase,
    251                                  void*        sts0_vaddr,
    252                                  void*        sts1_vaddr );
    253 
    254 extern int _sys_fbf_cma_start( unsigned int length );
    255 
    256 extern int _sys_fbf_cma_display( unsigned int buffer_index );
     234extern int _sys_fbf_cma_init_buf( unsigned int index,
     235                                  void*        buf_vaddr,
     236                                  void*        sts_vaddr );
     237
     238extern int _sys_fbf_cma_start();
     239
     240extern int _sys_fbf_cma_display( unsigned int index );
     241
     242extern int _sys_fbf_cma_check( unsigned int index );
    257243
    258244extern int _sys_fbf_cma_stop();
     
    265251
    266252extern int _sys_proc_xyp( unsigned int* x,
    267                    unsigned int* y,
    268                    unsigned int* p );
     253                          unsigned int* y,
     254                          unsigned int* p );
    269255
    270256extern int _sys_procs_number( unsigned int* x_size,
    271                        unsigned int* y_size,
    272                        unsigned int* nprocs );
     257                              unsigned int* y_size,
     258                              unsigned int* nprocs );
    273259
    274260extern int _sys_vseg_get_vbase( char*         vspace_name,
    275                          char*         vseg_name,
    276                          unsigned int* vbase );
     261                                char*         vseg_name,
     262                                unsigned int* vbase );
    277263
    278264extern int _sys_vseg_get_length( char*         vspace_name,
    279                           char*         vseg_name,
    280                           unsigned int* length );
     265                                 char*         vseg_name,
     266                                 unsigned int* length );
    281267
    282268extern int _sys_xy_from_ptr( void*          ptr,
    283                       unsigned int*  x,
    284                       unsigned int*  y );
     269                             unsigned int*  x,
     270                             unsigned int*  y );
    285271
    286272extern int _sys_heap_info( unsigned int* vaddr,
    287                     unsigned int* length,
    288                     unsigned int  x,
    289                     unsigned int  y );
     273                           unsigned int* length,
     274                           unsigned int  x,
     275                           unsigned int  y );
    290276
    291277#endif
Note: See TracChangeset for help on using the changeset viewer.