xref: /openbmc/openpower-proc-control/targeting.cpp (revision 18b0786a93964c2f30ada2e5405b103d4d3b82e5)
12c05aa76SMatt Spinler /**
22c05aa76SMatt Spinler  * Copyright © 2017 IBM Corporation
32c05aa76SMatt Spinler  *
42c05aa76SMatt Spinler  * Licensed under the Apache License, Version 2.0 (the "License");
52c05aa76SMatt Spinler  * you may not use this file except in compliance with the License.
62c05aa76SMatt Spinler  * You may obtain a copy of the License at
72c05aa76SMatt Spinler  *
82c05aa76SMatt Spinler  *     http://www.apache.org/licenses/LICENSE-2.0
92c05aa76SMatt Spinler  *
102c05aa76SMatt Spinler  * Unless required by applicable law or agreed to in writing, software
112c05aa76SMatt Spinler  * distributed under the License is distributed on an "AS IS" BASIS,
122c05aa76SMatt Spinler  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132c05aa76SMatt Spinler  * See the License for the specific language governing permissions and
142c05aa76SMatt Spinler  * limitations under the License.
152c05aa76SMatt Spinler  */
168316b77bSEdward A. James 
178316b77bSEdward A. James #include <endian.h>
182c05aa76SMatt Spinler #include <experimental/filesystem>
192c05aa76SMatt Spinler #include <phosphor-logging/log.hpp>
202c05aa76SMatt Spinler #include <regex>
21*18b0786aSDhruvaraj Subhashchandran #include <phosphor-logging/elog.hpp>
22*18b0786aSDhruvaraj Subhashchandran #include "elog-errors.hpp"
232c05aa76SMatt Spinler #include "targeting.hpp"
242c05aa76SMatt Spinler 
25*18b0786aSDhruvaraj Subhashchandran 
262c05aa76SMatt Spinler namespace openpower
272c05aa76SMatt Spinler {
282c05aa76SMatt Spinler namespace targeting
292c05aa76SMatt Spinler {
302c05aa76SMatt Spinler 
312c05aa76SMatt Spinler using namespace phosphor::logging;
322c05aa76SMatt Spinler namespace fs = std::experimental::filesystem;
332c05aa76SMatt Spinler 
34c3bffed7SMatt Spinler int Target::getCFAMFD()
35c3bffed7SMatt Spinler {
36c3bffed7SMatt Spinler     if (cfamFD.get() == nullptr)
37c3bffed7SMatt Spinler     {
38c3bffed7SMatt Spinler         cfamFD = std::make_unique<
39c3bffed7SMatt Spinler             openpower::util::FileDescriptor>(getCFAMPath());
40c3bffed7SMatt Spinler     }
41c3bffed7SMatt Spinler 
42c3bffed7SMatt Spinler     return cfamFD->get();
43c3bffed7SMatt Spinler }
44c3bffed7SMatt Spinler 
45be407166SMichael Tritz std::unique_ptr<Target>& Targeting::getTarget(size_t pos)
46be407166SMichael Tritz {
47be407166SMichael Tritz     auto search = [pos](const auto& t)
48be407166SMichael Tritz     {
49be407166SMichael Tritz         return t->getPos() == pos;
50be407166SMichael Tritz     };
51be407166SMichael Tritz 
52be407166SMichael Tritz     auto target = find_if(targets.begin(), targets.end(), search);
53be407166SMichael Tritz     if (target == targets.end())
54be407166SMichael Tritz     {
55be407166SMichael Tritz         throw std::runtime_error("Target not found: " + std::to_string(pos));
56be407166SMichael Tritz     }
57be407166SMichael Tritz     else
58be407166SMichael Tritz     {
59be407166SMichael Tritz         return *target;
60be407166SMichael Tritz     }
61be407166SMichael Tritz }
62be407166SMichael Tritz 
63c3bffed7SMatt Spinler 
648316b77bSEdward A. James static uint32_t noEndianSwap(uint32_t data)
658316b77bSEdward A. James {
668316b77bSEdward A. James     return data;
678316b77bSEdward A. James }
688316b77bSEdward A. James 
698316b77bSEdward A. James static uint32_t endianSwap(uint32_t data)
708316b77bSEdward A. James {
718316b77bSEdward A. James     return htobe32(data);
728316b77bSEdward A. James }
738316b77bSEdward A. James 
742c05aa76SMatt Spinler Targeting::Targeting(const std::string& fsiMasterDev,
752c05aa76SMatt Spinler                      const std::string& fsiSlaveDir) :
762c05aa76SMatt Spinler     fsiMasterPath(fsiMasterDev),
772c05aa76SMatt Spinler     fsiSlaveBasePath(fsiSlaveDir)
782c05aa76SMatt Spinler {
798316b77bSEdward A. James     swap_endian_t swapper = endianSwap;
808316b77bSEdward A. James     std::regex exp{"fsi1/slave@([0-9]{2}):00", std::regex::extended};
818316b77bSEdward A. James 
828316b77bSEdward A. James     if (!fs::exists(fsiMasterPath))
838316b77bSEdward A. James     {
848316b77bSEdward A. James         std::regex expOld{"hub@00/slave@([0-9]{2}):00", std::regex::extended};
858316b77bSEdward A. James 
868316b77bSEdward A. James         //Fall back to old (4.7) path
878316b77bSEdward A. James         exp = expOld;
888316b77bSEdward A. James         fsiMasterPath = fsiMasterDevPathOld;
898316b77bSEdward A. James         fsiSlaveBasePath = fsiSlaveBaseDirOld;
908316b77bSEdward A. James 
918316b77bSEdward A. James         //And don't swap the endianness of CFAM data
928316b77bSEdward A. James         swapper = noEndianSwap;
938316b77bSEdward A. James     }
948316b77bSEdward A. James 
952c05aa76SMatt Spinler     //Always create P0, the FSI master.
968316b77bSEdward A. James     targets.push_back(std::make_unique<Target>(0, fsiMasterPath, swapper));
97*18b0786aSDhruvaraj Subhashchandran     try
98*18b0786aSDhruvaraj Subhashchandran     {
992c05aa76SMatt Spinler         //Find the the remaining P9s dynamically based on which files show up
1002c05aa76SMatt Spinler         for (auto& file : fs::directory_iterator(fsiSlaveBasePath))
1012c05aa76SMatt Spinler         {
1022c05aa76SMatt Spinler             std::smatch match;
1032c05aa76SMatt Spinler             std::string path = file.path();
1042c05aa76SMatt Spinler             if (std::regex_search(path, match, exp))
1052c05aa76SMatt Spinler             {
1062c05aa76SMatt Spinler                 auto pos = atoi(match[1].str().c_str());
1072c05aa76SMatt Spinler                 if (pos == 0)
1082c05aa76SMatt Spinler                 {
1092c05aa76SMatt Spinler                     log<level::ERR>("Unexpected FSI slave device name found",
110fabe92e8SMatt Spinler                                     entry("DEVICE_NAME=%s", path.c_str()));
1112c05aa76SMatt Spinler                     continue;
1122c05aa76SMatt Spinler                 }
1132c05aa76SMatt Spinler 
1142c05aa76SMatt Spinler                 path += "/raw";
1152c05aa76SMatt Spinler 
1168316b77bSEdward A. James                 targets.push_back(std::make_unique<Target>(pos, path, swapper));
1172c05aa76SMatt Spinler             }
1182c05aa76SMatt Spinler         }
119*18b0786aSDhruvaraj Subhashchandran     }
120*18b0786aSDhruvaraj Subhashchandran     catch (fs::filesystem_error& e)
121*18b0786aSDhruvaraj Subhashchandran     {
122*18b0786aSDhruvaraj Subhashchandran         elog<org::open_power::Proc::CFAM::OpenFailure>(
123*18b0786aSDhruvaraj Subhashchandran             org::open_power::Proc::CFAM::OpenFailure::ERRNO(e.code().value()),
124*18b0786aSDhruvaraj Subhashchandran             org::open_power::Proc::CFAM::OpenFailure::PATH(e.path1().c_str()));
125*18b0786aSDhruvaraj Subhashchandran     }
1262c05aa76SMatt Spinler 
1272c05aa76SMatt Spinler     auto sortTargets = [](const std::unique_ptr<Target>& left,
1282c05aa76SMatt Spinler                           const std::unique_ptr<Target>& right)
1292c05aa76SMatt Spinler     {
1302c05aa76SMatt Spinler         return left->getPos() < right->getPos();
1312c05aa76SMatt Spinler     };
1322c05aa76SMatt Spinler     std::sort(targets.begin(), targets.end(), sortTargets);
1332c05aa76SMatt Spinler }
1342c05aa76SMatt Spinler 
1352c05aa76SMatt Spinler }
1362c05aa76SMatt Spinler }
137