xref: /openbmc/openpower-proc-control/targeting.cpp (revision 8316b77b67aac9dea3e7281e2455ad80f509a5b3)
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  */
16*8316b77bSEdward A. James 
17*8316b77bSEdward A. James #include <endian.h>
182c05aa76SMatt Spinler #include <experimental/filesystem>
192c05aa76SMatt Spinler #include <phosphor-logging/log.hpp>
202c05aa76SMatt Spinler #include <regex>
212c05aa76SMatt Spinler #include "targeting.hpp"
222c05aa76SMatt Spinler 
232c05aa76SMatt Spinler namespace openpower
242c05aa76SMatt Spinler {
252c05aa76SMatt Spinler namespace targeting
262c05aa76SMatt Spinler {
272c05aa76SMatt Spinler 
282c05aa76SMatt Spinler using namespace phosphor::logging;
292c05aa76SMatt Spinler namespace fs = std::experimental::filesystem;
302c05aa76SMatt Spinler 
31c3bffed7SMatt Spinler int Target::getCFAMFD()
32c3bffed7SMatt Spinler {
33c3bffed7SMatt Spinler     if (cfamFD.get() == nullptr)
34c3bffed7SMatt Spinler     {
35c3bffed7SMatt Spinler         cfamFD = std::make_unique<
36c3bffed7SMatt Spinler             openpower::util::FileDescriptor>(getCFAMPath());
37c3bffed7SMatt Spinler     }
38c3bffed7SMatt Spinler 
39c3bffed7SMatt Spinler     return cfamFD->get();
40c3bffed7SMatt Spinler }
41c3bffed7SMatt Spinler 
42be407166SMichael Tritz std::unique_ptr<Target>& Targeting::getTarget(size_t pos)
43be407166SMichael Tritz {
44be407166SMichael Tritz     auto search = [pos](const auto& t)
45be407166SMichael Tritz     {
46be407166SMichael Tritz         return t->getPos() == pos;
47be407166SMichael Tritz     };
48be407166SMichael Tritz 
49be407166SMichael Tritz     auto target = find_if(targets.begin(), targets.end(), search);
50be407166SMichael Tritz     if (target == targets.end())
51be407166SMichael Tritz     {
52be407166SMichael Tritz         throw std::runtime_error("Target not found: " + std::to_string(pos));
53be407166SMichael Tritz     }
54be407166SMichael Tritz     else
55be407166SMichael Tritz     {
56be407166SMichael Tritz         return *target;
57be407166SMichael Tritz     }
58be407166SMichael Tritz }
59be407166SMichael Tritz 
60c3bffed7SMatt Spinler 
61*8316b77bSEdward A. James static uint32_t noEndianSwap(uint32_t data)
62*8316b77bSEdward A. James {
63*8316b77bSEdward A. James     return data;
64*8316b77bSEdward A. James }
65*8316b77bSEdward A. James 
66*8316b77bSEdward A. James static uint32_t endianSwap(uint32_t data)
67*8316b77bSEdward A. James {
68*8316b77bSEdward A. James     return htobe32(data);
69*8316b77bSEdward A. James }
70*8316b77bSEdward A. James 
712c05aa76SMatt Spinler Targeting::Targeting(const std::string& fsiMasterDev,
722c05aa76SMatt Spinler                      const std::string& fsiSlaveDir) :
732c05aa76SMatt Spinler     fsiMasterPath(fsiMasterDev),
742c05aa76SMatt Spinler     fsiSlaveBasePath(fsiSlaveDir)
752c05aa76SMatt Spinler {
76*8316b77bSEdward A. James     swap_endian_t swapper = endianSwap;
77*8316b77bSEdward A. James     std::regex exp{"fsi1/slave@([0-9]{2}):00", std::regex::extended};
78*8316b77bSEdward A. James 
79*8316b77bSEdward A. James     if (!fs::exists(fsiMasterPath))
80*8316b77bSEdward A. James     {
81*8316b77bSEdward A. James         std::regex expOld{"hub@00/slave@([0-9]{2}):00", std::regex::extended};
82*8316b77bSEdward A. James 
83*8316b77bSEdward A. James         //Fall back to old (4.7) path
84*8316b77bSEdward A. James         exp = expOld;
85*8316b77bSEdward A. James         fsiMasterPath = fsiMasterDevPathOld;
86*8316b77bSEdward A. James         fsiSlaveBasePath = fsiSlaveBaseDirOld;
87*8316b77bSEdward A. James 
88*8316b77bSEdward A. James         //And don't swap the endianness of CFAM data
89*8316b77bSEdward A. James         swapper = noEndianSwap;
90*8316b77bSEdward A. James     }
91*8316b77bSEdward A. James 
922c05aa76SMatt Spinler     //Always create P0, the FSI master.
93*8316b77bSEdward A. James     targets.push_back(std::make_unique<Target>(0, fsiMasterPath, swapper));
942c05aa76SMatt Spinler 
952c05aa76SMatt Spinler     //Find the the remaining P9s dynamically based on which files show up
962c05aa76SMatt Spinler     for (auto& file : fs::directory_iterator(fsiSlaveBasePath))
972c05aa76SMatt Spinler     {
982c05aa76SMatt Spinler         std::smatch match;
992c05aa76SMatt Spinler         std::string path = file.path();
1002c05aa76SMatt Spinler         if (std::regex_search(path, match, exp))
1012c05aa76SMatt Spinler         {
1022c05aa76SMatt Spinler             auto pos = atoi(match[1].str().c_str());
1032c05aa76SMatt Spinler             if (pos == 0)
1042c05aa76SMatt Spinler             {
1052c05aa76SMatt Spinler                 log<level::ERR>("Unexpected FSI slave device name found",
106fabe92e8SMatt Spinler                                 entry("DEVICE_NAME=%s", path.c_str()));
1072c05aa76SMatt Spinler                 continue;
1082c05aa76SMatt Spinler             }
1092c05aa76SMatt Spinler 
1102c05aa76SMatt Spinler             path += "/raw";
1112c05aa76SMatt Spinler 
112*8316b77bSEdward A. James             targets.push_back(std::make_unique<Target>(pos, path, swapper));
1132c05aa76SMatt Spinler         }
1142c05aa76SMatt Spinler     }
1152c05aa76SMatt Spinler 
1162c05aa76SMatt Spinler     auto sortTargets = [](const std::unique_ptr<Target>& left,
1172c05aa76SMatt Spinler                           const std::unique_ptr<Target>& right)
1182c05aa76SMatt Spinler     {
1192c05aa76SMatt Spinler         return left->getPos() < right->getPos();
1202c05aa76SMatt Spinler     };
1212c05aa76SMatt Spinler     std::sort(targets.begin(), targets.end(), sortTargets);
1222c05aa76SMatt Spinler }
1232c05aa76SMatt Spinler 
1242c05aa76SMatt Spinler }
1252c05aa76SMatt Spinler }
126