Advertisement
Guest User

Untitled

a guest
Jul 24th, 2019
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.56 KB | None | 0 0
  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 ifanModuleReader->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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement