summaryrefslogtreecommitdiffstats
path: root/targeting.hpp
blob: 6d86b50b6a0e01dac409795b862476ae03d1d59f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#pragma once

#include "filedescriptor.hpp"

#include <memory>
#include <vector>

namespace openpower
{
namespace targeting
{

constexpr auto fsiMasterDevPath =
    "/sys/devices/platform/gpio-fsi/fsi0/slave@00:00/raw";
constexpr auto fsiMasterDevPathOld =
    "/sys/devices/platform/fsi-master/slave@00:00/raw";

constexpr auto fsiSlaveBaseDir =
    "/sys/devices/platform/gpio-fsi/fsi0/slave@00:00/00:00:00:0a/fsi1/";
constexpr auto fsiSlaveBaseDirOld =
    "/sys/devices/platform/fsi-master/slave@00:00/hub@00/";

typedef uint32_t (*swap_endian_t)(uint32_t);

/**
 * Represents a specific P9 processor in the system.  Used by
 * the access APIs to specify the chip to operate on.
 */
class Target
{
  public:
    /**
     * Constructor
     *
     * @param[in] - The logical position of the target
     * @param[in] - The sysfs device path
     * @param[in] - The function pointer for swapping endianness
     */
    Target(size_t position, const std::string& devPath,
           const swap_endian_t swapper) :
        pos(position),
        cfamPath(devPath), doSwapEndian(swapper)
    {
    }

    Target() = delete;
    ~Target() = default;
    Target(const Target&) = default;
    Target(Target&&) = default;
    Target& operator=(Target&&) = default;

    /**
     * Returns the position
     */
    inline auto getPos() const
    {
        return pos;
    }

    /**
     * Returns the CFAM sysfs path
     */
    inline auto getCFAMPath() const
    {
        return cfamPath;
    }

    /**
     * Returns the file descriptor to use
     * for read/writeCFAM operations.
     */
    int getCFAMFD();

    /**
     * Returns correct byte-order data. (May or may not swap it depending
     * on the function received during construction from Targeting and the
     * host endianness).
     */
    inline uint32_t swapEndian(uint32_t data) const
    {
        return doSwapEndian(data);
    }

  private:
    /**
     * The logical position of this target
     */
    size_t pos;

    /**
     * The sysfs device path for the CFAM
     */
    const std::string cfamPath;

    /**
     * The file descriptor to use for read/writeCFAMReg
     */
    std::unique_ptr<openpower::util::FileDescriptor> cfamFD;

    /**
     * The function pointer for swapping endianness
     */
    const swap_endian_t doSwapEndian;
};

/**
 * Class that manages processor targeting for FSI operations.
 */
class Targeting
{
  public:
    /**
     * Scans sysfs to find all processors and creates Target objects
     * for them.
     * @param[in] fsiMasterDev - the sysfs device for the master
     * @param[in] fsiSlaveDirectory - the base sysfs dir for slaves
     */
    Targeting(const std::string& fsiMasterDev, const std::string& fsiSlaveDir);

    Targeting() : Targeting(fsiMasterDevPath, fsiSlaveBaseDir)
    {
    }

    ~Targeting() = default;
    Targeting(const Targeting&) = default;
    Targeting(Targeting&&) = default;
    Targeting& operator=(Targeting&&) = default;

    /**
     * Returns a const iterator to the first target
     */
    inline auto begin()
    {
        return targets.cbegin();
    }

    /**
     * Returns a const iterator to the last (highest position) target.
     */
    inline auto end()
    {
        return targets.cend();
    }

    /**
     * Returns the number of targets
     */
    inline auto size()
    {
        return targets.size();
    }

    /**
     * Returns a target by position.
     */
    std::unique_ptr<Target>& getTarget(size_t pos);

  private:
    /**
     * The path to the fsi-master sysfs device to access
     */
    std::string fsiMasterPath;

    /**
     * The path to the fsi slave sysfs base directory
     */
    std::string fsiSlaveBasePath;

    /**
     * A container of Targets in the system
     */
    std::vector<std::unique_ptr<Target>> targets;
};

} // namespace targeting
} // namespace openpower
OpenPOWER on IntegriCloud