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_ */