Ignore:
Timestamp:
Mar 10, 2015, 2:58:59 PM (9 years ago)
Author:
alain
Message:

Redefinition of the driver for the vci_mwmr_dma component.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_drivers/mwr_driver.c

    r456 r518  
    11///////////////////////////////////////////////////////////////////////////////////
    22// File     : mwr_driver.c
    3 // Date     : 23/05/2013
     3// Date     : 27/02/2015
    44// Author   : alain greiner
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The mwmr_driver.c and mwmr_driver.h files are part ot the GIET-VM nano-kernel.
    8 // This driver supports the SoClib vci_mwmr_controller component.
    9 //
    10 // This peripheral can be replicated (at most one component per cluster).
    11 //
    12 // The (virtual) base address of the associated segment is:
    13 //       SEG_MWR_BASE + cluster_xy * PERI_CLUSTER_INCREMENT
    14 //
    15 // SEG_MWR_BASE and PERI_CLUSTER_INCREMENT must be defined in hard_config.h
    16 ////////////////////////////////////////////////////////////////////////////////
    177
    188#include <giet_config.h>
    199#include <hard_config.h>
     10#include <mapping_info.h>
    2011#include <mwr_driver.h>
    2112#include <utils.h>
    2213#include <tty0.h>
     14#include <io.h>
    2315
    2416#if !defined(X_SIZE)
     
    4638#endif
    4739
    48 //////////////////////////////////////////////////////////////////////////////////
    49 //    _mwr_hw_init()
    50 // This function initializes one MWMR controller channel (i.e. one coprocessor
    51 // port) in a given cluster.
    52 // - cluster_xy    : cluster index
    53 // _ port_id       : port index
    54 // - way           : direction (to_coproc/from_coproc)
    55 // - channel_pbase : physical base address of the MWMR channel
    56 // TODO : The MWMR controler should be modified to support 40 bits addresses...
    57 //        Introduce a MWMR_CONFIG_PADDR_EXT register in the MWMR coprocessor
    58 //////////////////////////////////////////////////////////////////////////////////
    59 // Returns 0 if success, returns > 0 if error.
    60 //////////////////////////////////////////////////////////////////////////////////
    61 unsigned int _mwr_hw_init( unsigned int           cluster_xy,
    62                            unsigned int           port_id,
    63                            unsigned int           from_coproc,
    64                            paddr_t                channel_pbase )
     40extern unsigned int _coproc_done[X_SIZE*Y_SIZE];
     41
     42/////////////////////////////////////////////////////////////////////////////
     43// This function returns the value contained in a private register
     44// of the coprocessor contained in cluster "cluster_xy".
     45/////////////////////////////////////////////////////////////////////////////
     46unsigned int _mwr_get_coproc_register( unsigned int cluster_xy, // cluster
     47                                       unsigned int index )     // register
    6548{
    66     _puts(" [GIET_ERROR] _mwr_hw_init() function not supported yet\n");
    67     _exit();
     49    unsigned int vaddr =
     50        SEG_MWR_BASE +
     51        (cluster_xy * PERI_CLUSTER_INCREMENT) +
     52        (index << 2);
    6853
    69 /*
    70     // parameters checking
    71     unsigned int x = cluster_xy >> Y_WIDTH;
    72     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    73     if (x >= X_SIZE)                    return 1;
    74     if (y >= Y_SIZE)                    return 1;
     54    return ioread32( (void*)vaddr );
     55}
    7556
    76     // compute base address
    77     unsigned int* mwr_address = (unsigned int*) ( SEG_MWR_BASE +
    78                                  (cluster_xy * PERI_CLUSTER_INCREMENT) );
     57/////////////////////////////////////////////////////////////////////////////
     58// This function sets a new value in a private register
     59// of the coprocessor contained in cluster "clustenr_xy".
     60/////////////////////////////////////////////////////////////////////////////
     61void _mwr_set_coproc_register( unsigned int cluster_xy,   // cluster index
     62                               unsigned int index,        // register index
     63                               unsigned int value )       // writte value
     64{
     65    unsigned int vaddr =
     66        SEG_MWR_BASE +
     67        (cluster_xy * PERI_CLUSTER_INCREMENT) +
     68        (index << 2);
     69       
     70    iowrite32( (void*)vaddr, value );
     71}
    7972
    80     unsigned int lsb = (unsigned int)channel_pbase;
    81     unsigned int msb = (unsigned int)(channel_pbase>>32);
     73/////////////////////////////////////////////////////////////////////////////
     74// This function returns the value contained in a channel register
     75// defined by the "index" and "channel" arguments, in the MWMR_DMA component
     76// contained in cluster "cluster_xy".
     77/////////////////////////////////////////////////////////////////////////////
     78unsigned int _mwr_get_channel_register( unsigned int cluster_xy, // cluster
     79                                        unsigned int channel,    // channel
     80                                        unsigned int index )     // register
     81{
     82    unsigned int vaddr =
     83        SEG_MWR_BASE +
     84        (cluster_xy * PERI_CLUSTER_INCREMENT) +
     85        ((channel + 1) * (CHANNEL_SPAN << 2)) +
     86        (index << 2);
    8287
    83     // get depth and width from channel itself
    84     unsigned int depth = _physical_read( channel_pbase + 16 );
    85     unsigned int width = _physical_read( channel_pbase + 20 );
     88    return ioread32( (void*)vaddr );
     89}
    8690
    87     // initializes and launches mwmr controler
    88     mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_FIFO_WAY]  = from_coproc;
    89     mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_FIFO_NO]   = port_id;
    90     mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_WIDTH]     = width;
    91     mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_DEPTH]     = depth;
    92     mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_STATUS]    = lsb;
    93     mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_DATA]      = lsb + 24;
    94     mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_EXT]       = msb;
    95     mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_RUNNING]   = 1;
    96 */
    97     return 0;
     91/////////////////////////////////////////////////////////////////////////////
     92// This function sets a new value in a channel register
     93// defined by the "index" and "channel") arguments, in the MWMR_DMA component
     94// contained in cluster "cluster_xy".
     95/////////////////////////////////////////////////////////////////////////////
     96void _mwr_set_channel_register( unsigned int cluster_xy,  // cluster index
     97                                unsigned int channel,     // channel index
     98                                unsigned int index,       // register index
     99                                unsigned int value )      // written value
     100{
     101    unsigned int vaddr =
     102        SEG_MWR_BASE +
     103        (cluster_xy * PERI_CLUSTER_INCREMENT) +
     104        ((channel + 1) * (CHANNEL_SPAN << 2)) +
     105        (index << 2);
     106       
     107    iowrite32( (void*)vaddr, value );
    98108}
     109
     110///////////////////////////////////////////////////////
     111void _mwr_isr( unsigned int irq_type,  // should be HWI
     112               unsigned int irq_id,    // index returned by XCU
     113               unsigned int channel )  // MWMR_DMA channel
     114{
     115    unsigned int gpid       = _get_procid();
     116    unsigned int cluster_xy = gpid >> P_WIDTH;
     117    unsigned int x          = cluster_xy >> Y_WIDTH;
     118    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
     119
     120    // acknowledge IRQ
     121    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_RUNNING, 0 );
     122
     123    // compute coproc_id from cluster coordinates
     124    unsigned int coproc_id = x * Y_SIZE + y;
     125
     126    // set synchronisation variable
     127    _coproc_done[coproc_id] = 1;
     128}
     129
    99130
    100131
Note: See TracChangeset for help on using the changeset viewer.