blob: 205bf68dfdd4817e5a8c3903ac90e700b7e00796 [file] [log] [blame]
Matt Spinler2c05aa72017-02-28 09:48:13 -06001/**
2 * Copyright © 2017 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Edward A. James8316b772017-04-24 14:20:48 -050016
17#include <endian.h>
Matt Spinler2c05aa72017-02-28 09:48:13 -060018#include <experimental/filesystem>
Matt Spinlera231ceb2017-10-04 11:26:09 -050019#include <phosphor-logging/elog.hpp>
20#include <phosphor-logging/elog-errors.hpp>
Matt Spinler2c05aa72017-02-28 09:48:13 -060021#include <phosphor-logging/log.hpp>
22#include <regex>
Matt Spinlera231ceb2017-10-04 11:26:09 -050023#include <xyz/openbmc_project/Common/File/error.hpp>
Matt Spinler2c05aa72017-02-28 09:48:13 -060024#include "targeting.hpp"
25
Dhruvaraj Subhashchandran18b07862017-04-26 07:13:35 -050026
Matt Spinler2c05aa72017-02-28 09:48:13 -060027namespace openpower
28{
29namespace targeting
30{
31
32using namespace phosphor::logging;
33namespace fs = std::experimental::filesystem;
Matt Spinlera231ceb2017-10-04 11:26:09 -050034namespace file_error = sdbusplus::xyz::openbmc_project::Common::File::Error;
Matt Spinler2c05aa72017-02-28 09:48:13 -060035
Matt Spinlerc3bffed2017-03-10 09:05:30 -060036int Target::getCFAMFD()
37{
38 if (cfamFD.get() == nullptr)
39 {
40 cfamFD = std::make_unique<
41 openpower::util::FileDescriptor>(getCFAMPath());
42 }
43
44 return cfamFD->get();
45}
46
Michael Tritzbe407162017-03-30 16:52:24 -050047std::unique_ptr<Target>& Targeting::getTarget(size_t pos)
48{
49 auto search = [pos](const auto& t)
50 {
51 return t->getPos() == pos;
52 };
53
54 auto target = find_if(targets.begin(), targets.end(), search);
55 if (target == targets.end())
56 {
57 throw std::runtime_error("Target not found: " + std::to_string(pos));
58 }
59 else
60 {
61 return *target;
62 }
63}
64
Matt Spinlerc3bffed2017-03-10 09:05:30 -060065
Edward A. James8316b772017-04-24 14:20:48 -050066static uint32_t noEndianSwap(uint32_t data)
67{
68 return data;
69}
70
71static uint32_t endianSwap(uint32_t data)
72{
73 return htobe32(data);
74}
75
Matt Spinler2c05aa72017-02-28 09:48:13 -060076Targeting::Targeting(const std::string& fsiMasterDev,
77 const std::string& fsiSlaveDir) :
78 fsiMasterPath(fsiMasterDev),
79 fsiSlaveBasePath(fsiSlaveDir)
80{
Edward A. James8316b772017-04-24 14:20:48 -050081 swap_endian_t swapper = endianSwap;
82 std::regex exp{"fsi1/slave@([0-9]{2}):00", std::regex::extended};
83
84 if (!fs::exists(fsiMasterPath))
85 {
86 std::regex expOld{"hub@00/slave@([0-9]{2}):00", std::regex::extended};
87
88 //Fall back to old (4.7) path
89 exp = expOld;
90 fsiMasterPath = fsiMasterDevPathOld;
91 fsiSlaveBasePath = fsiSlaveBaseDirOld;
92
93 //And don't swap the endianness of CFAM data
94 swapper = noEndianSwap;
95 }
96
Matt Spinler2c05aa72017-02-28 09:48:13 -060097 //Always create P0, the FSI master.
Edward A. James8316b772017-04-24 14:20:48 -050098 targets.push_back(std::make_unique<Target>(0, fsiMasterPath, swapper));
Dhruvaraj Subhashchandran18b07862017-04-26 07:13:35 -050099 try
Matt Spinler2c05aa72017-02-28 09:48:13 -0600100 {
Dhruvaraj Subhashchandran18b07862017-04-26 07:13:35 -0500101 //Find the the remaining P9s dynamically based on which files show up
102 for (auto& file : fs::directory_iterator(fsiSlaveBasePath))
Matt Spinler2c05aa72017-02-28 09:48:13 -0600103 {
Dhruvaraj Subhashchandran18b07862017-04-26 07:13:35 -0500104 std::smatch match;
105 std::string path = file.path();
106 if (std::regex_search(path, match, exp))
Matt Spinler2c05aa72017-02-28 09:48:13 -0600107 {
Dhruvaraj Subhashchandran18b07862017-04-26 07:13:35 -0500108 auto pos = atoi(match[1].str().c_str());
109 if (pos == 0)
110 {
111 log<level::ERR>("Unexpected FSI slave device name found",
112 entry("DEVICE_NAME=%s", path.c_str()));
113 continue;
114 }
115
116 path += "/raw";
117
118 targets.push_back(std::make_unique<Target>(pos, path, swapper));
Matt Spinler2c05aa72017-02-28 09:48:13 -0600119 }
Matt Spinler2c05aa72017-02-28 09:48:13 -0600120 }
121 }
Dhruvaraj Subhashchandran18b07862017-04-26 07:13:35 -0500122 catch (fs::filesystem_error& e)
123 {
Matt Spinlera231ceb2017-10-04 11:26:09 -0500124 using metadata = xyz::openbmc_project::Common::File::Open;
125
126 elog<file_error::Open>(
127 metadata::ERRNO(e.code().value()),
128 metadata::PATH(e.path1().c_str()));
Dhruvaraj Subhashchandran18b07862017-04-26 07:13:35 -0500129 }
Matt Spinler2c05aa72017-02-28 09:48:13 -0600130
131 auto sortTargets = [](const std::unique_ptr<Target>& left,
132 const std::unique_ptr<Target>& right)
133 {
134 return left->getPos() < right->getPos();
135 };
136 std::sort(targets.begin(), targets.end(), sortTargets);
137}
138
139}
140}