LCOV - code coverage report
Current view: top level - felix-star/src - register_device_interface.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 23 25 92.0 %
Date: 2025-08-12 04:15:35 Functions: 4 4 100.0 %

          Line data    Source code
       1             : #ifndef REGISTER_DEVICE_MANAGER_H_
       2             : #define REGISTER_DEVICE_MANAGER_H_
       3             : 
       4             : #include <memory>
       5             : #include <stdint.h>
       6             : #include <string>
       7             : 
       8             : #include "log.hpp"
       9             : #include "device.hpp"
      10             : #include "regmap_manager.hpp"
      11             : 
      12             : /**
      13             :  * Felix-register interface to a PCIe endpoint.
      14             :  * */
      15             : template <class DEV>
      16             : class RegisterDeviceInterface
      17             : {
      18             : public:
      19             : 
      20             :     /**
      21             :      * @brief RegisterDeviceManager class constructor
      22             :      * @param regmap the owner of the the yaml register map.
      23             :      * @param main the PCIe endpoint for this RegisterDeviceManager.
      24             :      * @param primary the primary PCIe endpoint correspoding to "main".
      25             :      */
      26           3 :     RegisterDeviceInterface(RegmapManager & regmap, std::shared_ptr<DEV> main, std::shared_ptr<DEV> primary)
      27           6 :         : m_regmap(regmap), m_main(main), m_primary(primary){}
      28             : 
      29             :     /**
      30             :      * @brief read a register.
      31             :      * @param reg_name register name.
      32             :      * @return the register value
      33             :      */
      34             :     uint64_t get_register(const std::string& reg_name);
      35             : 
      36             :     /**
      37             :      * @brief set a register.
      38             :      * @param reg_name register name.
      39             :      * @param values the value to be set.
      40             :      */
      41             :     void set_register(const std::string& reg_name, uint64_t value);
      42             : 
      43             :     /**
      44             :      * @return whether the register is readable
      45             :      */
      46             :     bool can_read(const std::string& reg_name){ return m_regmap.can_read(reg_name); };
      47             : 
      48             :     /**
      49             :      * @return whether the register is writable
      50             :      */
      51             :     bool can_write(const std::string& reg_name){ return m_regmap.can_write(reg_name); };
      52             : 
      53             : private:
      54             :     RegmapManager & m_regmap;
      55             :     std::shared_ptr<DEV> m_main;
      56             :     std::shared_ptr<DEV> m_primary;
      57             : 
      58             :     /**
      59             :      * @param reg_name the register name.
      60             :      * @return the PCIe endpoint to which the register is associated to.
      61             :      */
      62             :     DEV* select_device(const std::string& reg_name);
      63             : };
      64             : 
      65             : 
      66             : template <class DEV>
      67           7 : DEV* RegisterDeviceInterface<DEV>::select_device(const std::string& reg_name)
      68             : {
      69           7 :     DEV* device = nullptr;
      70           7 :     unsigned dev_no = m_main->get_device_number();
      71             : 
      72           7 :     if (not m_regmap.has_endpoint_1(reg_name) and not m_main->is_primary())
      73             :     {
      74           6 :         if (!m_primary.get()){
      75           0 :             LOG_ERR("Cannot access register %s. Primary endpoint for device %u not initiliazed", dev_no, reg_name.c_str());
      76             :         }
      77           6 :         else if (!m_primary->is_primary()) {
      78           3 :             unsigned primary_dev_no = m_primary->get_device_number();
      79           3 :             LOG_ERR("Cannot access register %s. Neither devices %u and %u are primary ", reg_name.c_str(), dev_no, primary_dev_no);
      80             :         } else {
      81           3 :             device = m_primary.get();
      82             :         }
      83             :     } else {
      84           1 :         device = m_main.get();
      85           1 :         if (!device){
      86           0 :             LOG_ERR("Cannot access register %s. Device %u not initialized", dev_no, reg_name.c_str());
      87             :         }
      88             :     }
      89           7 :     return device;
      90             : }
      91             : 
      92             : 
      93             : template <class DEV>
      94           5 : uint64_t RegisterDeviceInterface<DEV>::get_register(const std::string& reg_name)
      95             : {
      96           5 :     DEV* device = select_device(reg_name);
      97           5 :     if (device) {
      98           3 :         return device->get_register(reg_name.c_str());
      99             :     }
     100             :     return 0;
     101             : }
     102             : 
     103             : 
     104             : template <class DEV>
     105           2 : void RegisterDeviceInterface<DEV>::set_register(const std::string& reg_name, uint64_t value)
     106             : {
     107           2 :     DEV* device = select_device(reg_name);
     108           2 :     if (device) {
     109           1 :         device->set_register(reg_name.c_str(), value);
     110             :     }
     111           2 : }
     112             : 
     113             : #endif /* REGISTER_DEVICE_MANAGER_H_ */

Generated by: LCOV version 1.0