SHARE
TWEET

Untitled

a guest Jul 24th, 2019 68 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "GpioHelpers.hpp"
  2. #include "FansFeatureID.hpp"
  3. #include <gpio-0/gpio.hpp>
  4. #include <log/LoggingSystem.h>
  5. #include <fcntl.h>
  6. #include <sys/mman.h>
  7. #include <unistd.h>
  8. #include <iostream>
  9.  
  10. using namespace pss::gpio;
  11. namespace ho = ::hlapi::ho;
  12.  
  13. namespace memoryaccess
  14. {
  15. struct MemoryAccess
  16. {
  17.     std::uint32_t mapped_size = 0u;
  18.     int fd = 0;
  19.     void* map_base = nullptr;
  20.     void* virt_addr = nullptr;
  21. };
  22.  
  23. void openForRead(MemoryAccess& memoryAccess, std::uint32_t address)
  24. {
  25.     const std::uint32_t width          = 32u;
  26.     const std::uint32_t page_size      = static_cast<std::uint32_t>(::getpagesize());
  27.     const std::uint32_t offset_in_page = static_cast<std::uint32_t>(address) & (page_size - 1);
  28.  
  29.     memoryAccess.mapped_size      = ((offset_in_page + width) > page_size) ? page_size : page_size * 2;
  30.     memoryAccess.fd               = ::open("/dev/mem", (O_RDONLY | O_SYNC));
  31.     memoryAccess.map_base         = ::mmap(nullptr, memoryAccess.mapped_size, PROT_READ, MAP_SHARED,
  32.                                            memoryAccess.fd, address & ~static_cast<off_t>(page_size - 1));
  33.     memoryAccess.virt_addr        = static_cast<char*>(memoryAccess.map_base) + offset_in_page;
  34. }
  35.  
  36. void read(const MemoryAccess& memoryAccess, std::uint32_t& value)
  37. {
  38.     value = *static_cast<volatile std::uint32_t*>(memoryAccess.virt_addr);
  39. }
  40.  
  41. void close(const MemoryAccess& memoryAccess)
  42. {
  43.     ::munmap(memoryAccess.map_base, memoryAccess.mapped_size);
  44.     ::close(memoryAccess.fd);
  45. }
  46.  
  47. void read(std::uint32_t address, std::uint32_t& value)
  48. {
  49.     MemoryAccess memoryAccess;
  50.     openForRead(memoryAccess, address);
  51.     read(memoryAccess, value);
  52.     close(memoryAccess);
  53. }
  54. }
  55.  
  56. namespace fans
  57. {
  58.  
  59. bool FanModuleReader::gpioDefined(const gpioInfo& gpio)
  60. {
  61.     std::cout<<"gpioDefined"<<std::endl;
  62.     return gpio.id > 0 && !gpio.name.empty();
  63. }
  64.  
  65. bool FanModuleReader::registerDefined(const registerInfo&)
  66. {
  67.     //For GEN3H GPIO is not definied, so fan presence need to be checked by register.
  68.     return true;
  69. }
  70.  
  71. EReadResult FanModuleReader::readGpioValue(const gpioInfo& gpioSignal)
  72. {
  73.     std::cout<<"readGpioValue"<<std::endl;
  74.     try
  75.     {
  76.  
  77.         Gpio gpioPin(gpioSignal.id);    
  78.          gpioPin.setDirection(Direction::Input);
  79.    
  80.         gpioPin.setMux(Mux::A);
  81.         bool pinValue = gpioPin;
  82.  
  83.         if (gpioSignal.inverted) pinValue = !pinValue;
  84.         return pinValue ? EReadResult::True : EReadResult::False;
  85.     }
  86.     catch (std::runtime_error& e)
  87.     {
  88.         // invalid_content derivate after runtime_error and also will be catch
  89.         // here
  90.         inut::LoggingSystem log(EradFansServiceGpioHelpers);
  91.         log.warning("gpio %u read failure : %s", gpioSignal.id, e.what());
  92.         return EReadResult::Fail;
  93.     }
  94. }
  95.  
  96. EReadResult FanModuleReader::readRegisterValue(const registerInfo& regInfo)
  97. {
  98.         std::cout<<"readRegisterValue"<<std::endl;
  99.  
  100.     try
  101.     {
  102.         std::uint32_t registerValue{0x0};
  103.         memoryaccess::read(regInfo.offset, registerValue);
  104.         if(!regInfo.inverted)
  105.             return ((registerValue & regInfo.mask) ? EReadResult::True : EReadResult::False);
  106.         else
  107.             return ((registerValue & regInfo.mask) ? EReadResult::False : EReadResult::True);
  108.     }
  109.     catch (std::runtime_error& e)
  110.     {
  111.         inut::LoggingSystem log(EradFansServiceGpioHelpers);
  112.         log.warning("register value read failure : %s", e.what());
  113.         return EReadResult::Fail;
  114.     }
  115. }
  116.  
  117. using ReadResultPair = std::pair<EReadResult, EReadResult>;
  118.  
  119. ho::EFanModStatus FanModuleReader::findStatusForPairInTruthTable(const std::map<ReadResultPair, ho::EFanModStatus>& truthTable,
  120.                                                 ReadResultPair pair)
  121. {
  122.     auto iter = truthTable.find(pair);
  123.     if (iter != truthTable.end()) return iter->second;
  124.     return ho::EFanModStatus_NothingInstalled;
  125. }
  126.  
  127. ho::EFanModStatus FanModuleReader::getFanModuleStatusForModeSelectDefined(const FanModuleConf& fanModConf)
  128. {
  129.     static const std::map<ReadResultPair, ho::EFanModStatus> truthTable = {
  130.         // fanModInst               modeSelect               status
  131.         {{EReadResult::False, EReadResult::False}, ho::EFanModStatus_NothingInstalled},
  132.         {{EReadResult::False, EReadResult::True}, ho::EFanModStatus_NothingInstalled},
  133.         {{EReadResult::True, EReadResult::False}, ho::EFanModStatus_FanModuleInstalled},
  134.         {{EReadResult::True, EReadResult::True}, ho::EFanModStatus_NothingInstalled},
  135.         {{EReadResult::Fail, EReadResult::False}, ho::EFanModStatus_NothingInstalled},
  136.         {{EReadResult::Fail, EReadResult::True}, ho::EFanModStatus_NothingInstalled},
  137.         {{EReadResult::False, EReadResult::Fail}, ho::EFanModStatus_NothingInstalled},
  138.         {{EReadResult::True, EReadResult::Fail}, ho::EFanModStatus_NothingInstalled},
  139.         {{EReadResult::Fail, EReadResult::Fail}, ho::EFanModStatus_NothingInstalled},
  140.     };
  141.     return findStatusForPairInTruthTable(
  142.         truthTable, {readGpioValue(fanModConf.fanModInstalledGpio), readGpioValue(fanModConf.modeSelectGpio)});
  143. }
  144.  
  145. IFanModuleStatusDetector::IFanModuleStatusDetector(std::shared_ptr<IFanModuleReader> p): fanModuleReader(p){}
  146.  
  147. FanModuleStatusDetector::FanModuleStatusDetector(std::shared_ptr<IFanModuleReader> p): IFanModuleStatusDetector(p){}
  148.  
  149.  
  150. ho::EFanModStatus FanModuleStatusDetector::detectFanModuleStatus(const FanModuleConf& fanModConf) const
  151. {
  152.  
  153.     bool modInstDefined {false};
  154.     bool ipCapInstDefined {false};
  155.  
  156.     if (fanModuleReader->gpioDefined(fanModConf.modeSelectGpio))
  157.     {
  158.         return fanModuleReader->getFanModuleStatusForModeSelectDefined(fanModConf);
  159.     }
  160.  
  161.     EReadResult modInstalled {EReadResult::Fail};
  162.     EReadResult ipCapInstalled {EReadResult::Fail};
  163.  
  164.     if (fanModuleReader->gpioDefined(fanModConf.fanModInstalledGpio))
  165.     {
  166.         modInstDefined = true;
  167.         modInstalled = fanModuleReader->readGpioValue(fanModConf.fanModInstalledGpio);
  168.     }
  169.     else if(fanModuleReader->registerDefined(fanModConf.fanModInstalledRegister))
  170.     {
  171.         modInstDefined = true;
  172.         modInstalled = fanModuleReader->readRegisterValue(fanModConf.fanModInstalledRegister);
  173.     }
  174.  
  175.     if (fanModuleReader->gpioDefined(fanModConf.ipCapInstalledGpio))
  176.     {
  177.         ipCapInstDefined = true;
  178.         ipCapInstalled = fanModuleReader->readGpioValue(fanModConf.ipCapInstalledGpio);
  179.     }
  180.     else if(fanModuleReader->registerDefined(fanModConf.ipCapInstalledRegister))
  181.     {
  182.         ipCapInstDefined = true;
  183.         ipCapInstalled = fanModuleReader->readRegisterValue(fanModConf.ipCapInstalledRegister);
  184.     }
  185.  
  186.     if (!modInstDefined && !ipCapInstDefined)
  187.     {
  188.         return ho::EFanModStatus_NothingInstalled;
  189.     }
  190.     else if (modInstDefined && ipCapInstDefined)
  191.     {
  192.         static const std::map<ReadResultPair, ho::EFanModStatus> truthTable = {
  193.             // fanModInst               IpCapInst                status
  194.             {{EReadResult::True, EReadResult::True}, ho::EFanModStatus_HwError},
  195.             {{EReadResult::True, EReadResult::False}, ho::EFanModStatus_FanModuleInstalled},
  196.             {{EReadResult::False, EReadResult::True}, ho::EFanModStatus_IpCapInstalled},
  197.             {{EReadResult::False, EReadResult::False}, ho::EFanModStatus_NothingInstalled},
  198.             {{EReadResult::Fail, EReadResult::True}, ho::EFanModStatus_IpCapInstalled},
  199.             {{EReadResult::Fail, EReadResult::False}, ho::EFanModStatus_NothingInstalled},
  200.             {{EReadResult::True, EReadResult::Fail}, ho::EFanModStatus_FanModuleInstalled},
  201.             {{EReadResult::False, EReadResult::Fail}, ho::EFanModStatus_NothingInstalled},
  202.             {{EReadResult::Fail, EReadResult::Fail}, ho::EFanModStatus_NothingInstalled},
  203.         };
  204.         return fanModuleReader->findStatusForPairInTruthTable(
  205.             truthTable, {modInstalled, ipCapInstalled});
  206.     }
  207.     else if (modInstDefined)
  208.     {
  209.         if (modInstalled == EReadResult::False)
  210.             return ho::EFanModStatus_NothingInstalled;
  211.         else if (modInstalled == EReadResult::True)
  212.             return ho::EFanModStatus_FanModuleInstalled;
  213.         else
  214.             return ho::EFanModStatus_HwError;
  215.     }
  216.     else
  217.     {
  218.         if (ipCapInstalled == EReadResult::False)
  219.             return ho::EFanModStatus_NothingInstalled;
  220.         else if (ipCapInstalled == EReadResult::True)
  221.             return ho::EFanModStatus_IpCapInstalled;
  222.         else
  223.             return ho::EFanModStatus_HwError;
  224.     }
  225. }
  226.  
  227. FsFansDetector::FsFansDetector(const Config& config) : config(config)
  228. {
  229. }
  230.  
  231. void FsFansDetector::detectFixedSpeedFan(fsFan& fan)
  232. {
  233.     FanModuleReader fanModuleReader;
  234.     auto getFromCacheOrReadTheValue = [this](auto& gpio) {
  235.         auto iter = gpioMemoizer.find(gpio.id);
  236.         if (iter != gpioMemoizer.end())
  237.         {
  238.             return iter->second;
  239.         }
  240.         else
  241.         {
  242.             FanModuleReader fanModuleReader;
  243.             auto value = fanModuleReader.readGpioValue(gpio);
  244.             gpioMemoizer.emplace(gpio.id, value);
  245.             return value;
  246.         }
  247.     };
  248.  
  249.     const auto& fanConf = config.getFanConfig(fan.fanId);
  250.     auto fanStatExt = fan.statusObj.MutableExtension(ho::FanStatus::object);
  251.  
  252.     if (!fanModuleReader.gpioDefined(fanConf.fanStatusGpio) ||
  253.         getFromCacheOrReadTheValue(fanConf.fanStatusGpio) != EReadResult::True)
  254.     {
  255.         fanStatExt->set_detected(false);
  256.         fanStatExt->set_working(false);
  257.         return;
  258.     }
  259.  
  260.     fanStatExt->set_detected(true);
  261.  
  262.     if (fanModuleReader.gpioDefined(fanConf.fanBrokenGpio))
  263.     {
  264.         auto fanBroken = getFromCacheOrReadTheValue(fanConf.fanBrokenGpio);
  265.         if (fanBroken == EReadResult::Fail)
  266.             fanStatExt->set_working(true);  // assuming working by default
  267.         else
  268.             fanStatExt->set_working(fanBroken == EReadResult::True);
  269.     }
  270.     else
  271.     {
  272.         fanStatExt->set_working(true);  // assuming working by default
  273.     }
  274. }
  275.  
  276. unsigned int VendorIdGpioReader::detectVendorBasedOnGpio(const FanModuleConf& fanModConf)
  277. {
  278.     FanModuleReader fanModuleReader;
  279.     unsigned int vendorId = 0;
  280.     for (const auto& vendGpio : fanModConf.vendorIdGpio)
  281.     {
  282.         vendorId = vendorId << 1;
  283.         if (fanModuleReader.gpioDefined(vendGpio))
  284.         {
  285.             auto result = fanModuleReader.readGpioValue(vendGpio);
  286.             if (result == EReadResult::Fail) return VendorDetectionNotPossible;
  287.             vendorId += (result == EReadResult::True) ? 1 : 0;
  288.         }
  289.         else
  290.         {
  291.             return VendorDetectionNotPossible;
  292.         }
  293.     }
  294.     return vendorId;
  295. }
  296. }  // namespace fans
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top