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