Program Listing for File device.hpp

Return to documentation for file (device.hpp)

#ifndef DEVICE_H_
#define DEVICE_H_

#include <cstdint>
#include <sys/types.h>
#include <string>

#include "flxcard/FlxCard.h"
#include "cmem_buffer.hpp"
#include "config/config.hpp"
#include "elink.hpp"

#define MAX_BROADCAST_CHANNELS (32)
#define MAX_BROADCAST_ELINKS (1 + 32 + 64)

#define TOFLX_EOM_MASK_RM4 0x0001
#define TOFLX_EOM_SHIFT_RM4 0
#define TOFLX_LENGTH_MASK_RM4 0x001E
#define TOFLX_LENGTH_SHIFT_RM4 1
#define TOFLX_ELINK_MASK_RM4 0xFFE0
#define TOFLX_ELINK_SHIFT_RM4 5
#define TOFLX_LENGTH_MASK 0x001F
#define TOFLX_ELINK_SHIFT 5
#define TOFLX_LENGTH_MASK_HDR32 0x003F
#define TOFLX_ELINK_SHIFT_HDR32 6
#define TOFLX_LENGTH_MASK_HDR32_8B 0x000000FF
#define TOFLX_ELINK_SHIFT_HDR32_8B 8


enum flx_fromhost_format {
    FROMHOST_FORMAT_REGMAP4,
    FROMHOST_FORMAT_5BIT_LENGTH,
    FROMHOST_FORMAT_HDR32_PACKET32,
    FROMHOST_FORMAT_HDR32_PACKET64,
    // Header with 8-bit fields (see FLX-2294):
    FROMHOST_FORMAT_HDR32_PACKET32_8B,
    FROMHOST_FORMAT_HDR32_PACKET64_8B,
    FROMHOST_FORMAT_HDR32_PACKET128_8B,
    UN_INITIALIZED
};

enum flx_tohost_format {
    TOHOST_SUBCHUNK_TRAILER,
    TOHOST_SUBCHUNK_HEADER
};

class Device
{
    protected:
        unsigned                m_device_number;
        uint8_t                 m_vid;
        uint16_t                m_did, m_cid;
        u_int                   m_firmware_type;
        flx_fromhost_format     m_fromHostDataFormat    {UN_INITIALIZED};
        flx_tohost_format       m_toHostDataFormat      {TOHOST_SUBCHUNK_TRAILER};

        virtual uint64_t get_broadcast_enable_gen(u_int channel) = 0;

        virtual bool elink_has_stream_id(u_int channel, u_int egroup, u_int epath) = 0;

    public:

        Device(unsigned dev_no, uint8_t vid, uint16_t did, uint16_t cid);

        virtual int open_device(u_int lock_mask) = 0;

        virtual void close_device()              = 0;

        virtual bool is_primary() = 0;

        virtual unsigned int get_card_model() = 0;

        virtual unsigned int get_card_endpoints() = 0;

        virtual u_int get_regmap_version()       = 0;

        virtual u_int get_firmware_type(){return m_firmware_type;}

        virtual u_int get_number_of_channels()   = 0;

        virtual bool  get_wide_mode()            = 0;

        virtual u_int get_block_size()           = 0;

        virtual u_int get_trailer_size()         = 0;

        virtual flx_fromhost_format get_fromhost_data_format() = 0;

        virtual flx_tohost_format get_tohost_data_format() = 0;

        virtual int   get_fromhost_dmaid()       = 0;

        virtual int   get_trickle_dmaid()        = 0;

        virtual int   dma_max_tlp_bytes()        = 0;

        virtual void set_register(const char *key, uint64_t value) = 0;

        virtual uint64_t get_register(const char *key)             = 0;

        virtual bool check_register(const char *key)               = 0;
        virtual void cancel_irq(int i)  = 0;

        virtual void irq_wait(int i)    = 0;

        virtual void irq_enable(int i)  = 0;

        virtual void irq_disable(int i) = 0;
        virtual std::vector<Elink> read_enabled_elinks(int dmaid) = 0;

        std::vector<Elink> get_enabled_elinks_of_type(int dmaid, elink_type_t t);

        unsigned get_device_number(){return m_device_number;}

        unsigned int make_dma_lock_mask(const std::vector<int>& dmaids);

        u_int get_broadcast_elinks(uint64_t broadcast_elinks[], uint32_t num_of_channels);

        static int64_t broadcast_for(uint64_t elink);

        static int broadcast_type(uint64_t elink);

        static const std::string broadcast_type_str(uint64_t elink);

        static u_int broadcast_elinks(uint64_t broadcast_elinks[], const uint64_t broadcast_enable_registers[], uint32_t num_of_channels);

        static const std::string get_elink_type_str(elink_type_t encoding);

        bool has_wrong_rm();

        bool is_full_mode();

        bool is_lpgbt_mode();

        uint64_t get_elink(u_int channel, u_int egroup, u_int epath);

        uint32_t get_channel(uint32_t elink);

        uint32_t get_egroup(uint32_t elink);

        uint32_t get_epath(uint32_t elink);

        u_int get_egroups_per_channel(u_int is_to_flx);

        u_int get_epaths_per_egroup(u_int is_to_flx);

        u_int get_ctrl_elinks_per_channel();
        virtual bool dma_enabled(int dmaid)                                     = 0;

        virtual void dma_to_host(DmaBuffer* buf, int dmaid)                     = 0;

        virtual void dma_from_host(DmaBuffer* buf, int dmaid)                   = 0;


        virtual void dma_from_host_trickle(DmaBuffer* buf, int dmaid, size_t config_size)   = 0;

        virtual void dma_set_oneshot(DmaBuffer* buf, int dmaid, size_t config_size)         = 0;

        virtual uint64_t dma_get_fw_ptr(int dmaid)                              = 0;

        virtual uint64_t dma_get_sw_ptr(int dmaid)                              = 0;

        virtual void     dma_set_sw_ptr(int dmaid, uint64_t p_absolute)         = 0;

        virtual bool     dma_cmp_even_bits(int dmaid)                           = 0;

        virtual void     dma_stop(unsigned int dmaid)                           = 0;
        virtual monitoring_data_t hw_get_monitoring_data( unsigned int mon_mask = 0xFFF ) = 0;
};


class FlxDevice : public Device
{
    private:
        FlxCard m_dev;
        encoding_t elink_get_encoding(u_int channel, u_int egroup, u_int epath, bool is_to_flx);
        bool elink_is_in_dma(local_elink_t elink, int dmaid);
        bool elink_is_enabled(u_int channel, u_int egroup, u_int epath, bool is_to_flx);

        local_elink_t get_ec_elink(bool is_to_flx, u_int channel);
        local_elink_t get_ic_elink(bool is_to_flx, u_int channel);
        local_elink_t get_aux_elink(bool is_to_flx, u_int channel);

        bool elink_is_ic_enabled(bool is_to_flx, u_int channel);
        bool elink_is_ec_enabled(bool is_to_flx, u_int channel);
        bool elink_is_aux_enabled(bool is_to_flx, u_int channel);

        uint64_t get_broadcast_enable_gen(u_int channel)                   override;
        bool elink_has_stream_id(u_int channel, u_int egroup, u_int epath) override;

    public:
        FlxDevice(Config& cfg, unsigned device);
        explicit FlxDevice(unsigned dev_no);

        int  open_device(u_int lock_mask) override;
        void close_device()               override;
        bool is_primary()                 override;

        unsigned int get_card_model()     override;
        unsigned int get_card_endpoints() override;
        u_int get_regmap_version()        override;
        u_int get_number_of_channels()    override;
        bool  get_wide_mode()             override;
        u_int get_block_size()            override;
        u_int get_trailer_size()          override;
        flx_fromhost_format get_fromhost_data_format()  override;
        flx_tohost_format   get_tohost_data_format()    override;
        int get_fromhost_dmaid()          override;
        int get_trickle_dmaid()           override;
        int dma_max_tlp_bytes()           override;

        //Registers
        void     set_register(const char *key, uint64_t value) override;
        uint64_t get_register(const char *key)                 override;
        bool     check_register(const char *key)               override;

        //Interrupts
        void cancel_irq(int i)  override;
        void irq_wait(int i)    override;
        void irq_enable(int i)  override;
        void irq_disable(int i) override;

        //Elinks
        std::vector<Elink> read_enabled_elinks(int dmaid) override;

        //DMA operations
        bool dma_enabled(int dmaid)                                         override;
        void dma_to_host(DmaBuffer* buf, int dmaid)                         override; //start_circular_dma
        void dma_from_host(DmaBuffer* buf, int dmaid)                       override;
        void dma_from_host_trickle(DmaBuffer* buf, int dmaid, size_t config_size)  override;
        void dma_set_oneshot(DmaBuffer* buf, int dmaid, size_t config_size)        override;
        uint64_t dma_get_fw_ptr(int dmaid)                                  override; //dma_get_current_address
        uint64_t dma_get_sw_ptr(int dmaid)                                  override;
        void     dma_set_sw_ptr(int dmaid, uint64_t p_phys)                 override; //dma_set_ptr
        bool     dma_cmp_even_bits(int dmaid)                               override;
        void     dma_stop(unsigned int dmaid)                               override;

         //HW monitor
        monitoring_data_t hw_get_monitoring_data( unsigned int mon_mask = 0xFFF ) override;
};


class FileDevice : public Device
{
    private:
        u_int   m_locks;
        u_int   m_regmap;
        u_int   m_channels;
        u_int   m_block_size;
        u_int   m_trailer_size;  //determined in open_device
        bool    m_wide_mode;
        int     m_max_tlp_bytes;
        int     m_toflx_dmaid;
        int     m_trickle_dmaid;
        uint32_t m_status_leds;
        int     m_busy;
        std::map<int, std::vector<Elink>> m_enabled_elinks;

        uint64_t get_broadcast_enable_gen(u_int channel)                   override;
        bool elink_has_stream_id(u_int channel, u_int egroup, u_int epath) override;

    public:
        FileDevice(ConfigFile& cfg, unsigned device);
        explicit FileDevice(unsigned dev_no);
        int open_device(u_int lock_mask)        override;
        void close_device() override {return;}
        bool is_primary() override {return not (m_device_number % 2);}
        unsigned int get_card_endpoints() override {return 2;}
        unsigned int get_card_model() override {return 712;}
        u_int get_regmap_version()       override {return m_regmap;}
        u_int get_number_of_channels()   override {return m_channels;}
        bool get_wide_mode()             override {return m_wide_mode;}
        u_int get_block_size()           override {return m_block_size;}
        u_int get_trailer_size()         override {return m_trailer_size;}
        flx_fromhost_format get_fromhost_data_format() override {return m_fromHostDataFormat;}
        flx_tohost_format   get_tohost_data_format()   override {return m_toHostDataFormat;}
        int get_fromhost_dmaid()         override {return m_toflx_dmaid;}
        int get_trickle_dmaid()          override {return m_trickle_dmaid;}
        int dma_max_tlp_bytes()          override {return m_max_tlp_bytes;}

        //Used for felix-register tests
        void     set_register(const char *key, uint64_t value) override;
        uint64_t get_register(const char *key)                 override;
        bool     check_register(const char *key) override  {return true;}

        //Interrupts
        void cancel_irq(int i)  override {return;}
        void irq_wait(int i)    override {return;}
        void irq_enable(int i)  override {return;}
        void irq_disable(int i) override {return;}

        //Elinks
        std::vector<Elink> read_enabled_elinks(int dmaid) override;
        void add_enabled_elink(Elink e, int dmaid);

        //DMA operations
        bool dma_enabled(int dmaid)                     override;
        void dma_to_host(DmaBuffer* buf, int dmaid)     override; //start_circular_dma
        // Remaining functions not implemented,
        // buffer to be managed by DmaBufferReader/Writer
        void dma_from_host(DmaBuffer* buf, int dmaid)                       override {return;};
        void dma_from_host_trickle(DmaBuffer* buf, int dmaid, size_t config_size)  override {return;};
        void dma_set_oneshot(DmaBuffer* buf, int dmaid, size_t config_size)        override {return;};
        uint64_t dma_get_fw_ptr(int dmaid)                                  override {return 0;} //dma_get_current_address
        uint64_t dma_get_sw_ptr(int dmaid)                                  override {return 0;}
        void     dma_set_sw_ptr(int dmaid, uint64_t p_phys)                 override {return;}//dma_set_ptr
        bool     dma_cmp_even_bits(int dmaid)                               override {return false;}
        void     dma_stop(unsigned int dmaid)                               override {return;}

        //HW monitor
        monitoring_data_t hw_get_monitoring_data( unsigned int mon_mask = 0xFFF ) override;

};

#endif /* DEVICE_H_ */