-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathocc_command.hpp
188 lines (161 loc) · 4.88 KB
/
occ_command.hpp
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
177
178
179
180
181
182
183
184
185
186
187
188
#pragma once
#include "occ_errors.hpp"
#include "utils.hpp"
#include <org/open_power/OCC/PassThrough/server.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/server/object.hpp>
#include <format>
#include <string>
#include <utility>
namespace open_power
{
namespace occ
{
// For waiting on signals
namespace sdbusRule = sdbusplus::bus::match::rules;
enum class CmdType
{
POLL = 0x00,
CLEAR_ERROR_LOG = 0x12,
SET_MODE_AND_STATE = 0x20,
SET_CONFIG_DATA = 0x21,
SET_USER_PCAP = 0x22,
RESET_PREP = 0x25,
SEND_AMBIENT = 0x30,
DEBUG_PASS_THROUGH = 0x40,
AME_PASS_THROUGH = 0x41,
GET_FIELD_DEBUG_DATA = 0x42,
MFG_TEST = 0x53
};
enum class OccState
{
NO_CHANGE = 0x00,
STANDBY = 0x01,
OBSERVATION = 0x02,
ACTIVE = 0x03,
SAFE = 0x04,
CHARACTERIZATION = 0x05
};
enum class SysPwrMode
{
NO_CHANGE = 0,
STATIC = 0x01, // Static Base Frequencey
NON_DETERMINISTIC = 0x02, // Non-Deterministic
SFP = 0x03, // Static Frequency Point (requires freqPt)
SAFE = 0x04, // reported when system is in SAFE mode (not settable)
POWER_SAVING = 0x05, // Static Power Saving
EFF_FAVOR_POWER = 0x06, // Efficiency - Favor Power
EFF_FAVOR_PERF = 0x07, // Efficiency - Favor Performance
MAX_FREQ = 0x09, // Maximum Frequency (per chip)
BALANCED_PERF = 0x0A, // Balanced Performance
FFO = 0x0B, // Fixed Frequency Override (requires freqPt)
MAX_PERF = 0x0C // Maximum Performance
};
enum class RspStatus
{
SUCCESS = 0x00,
CONDITIONAL_SUCCESS = 0x01,
INVALID_COMMAND = 0x11,
INVALID_COMMAND_LENGTH = 0x12,
INVALID_DATA_FIELD = 0x13,
CHECKSUM_FAILURE = 0x14,
INTERNAL_ERROR = 0x15,
PRESENT_STATE_PROHIBITS = 0x16,
COMMAND_IN_PROGRESS = 0xFF
};
enum class CmdStatus
{
SUCCESS = 0x00,
FAILURE = 0x02,
COMM_FAILURE = 0x03
};
/** @brief Trace block of data in hex with lg2:info()
*
* @param[in] data - vector containing data to trace
* @param[in] data_len - optional number of bytes to trace
* If 0, entire vector will be traced.
*/
void dump_hex(const std::vector<std::uint8_t>& data,
const unsigned int data_len = 0);
/** @class OccCommand
* @brief Send commands and process respsonses from the OCC
*/
class OccCommand
{
public:
OccCommand() = delete;
OccCommand(const OccCommand&) = delete;
OccCommand& operator=(const OccCommand&) = delete;
OccCommand(OccCommand&&) = default;
OccCommand& operator=(OccCommand&&) = default;
/** @brief Ctor to set up which OCC the command will go to
*
* @param[in] instance - OCC instance
* @param[in] path - Path to attach at
*/
OccCommand(uint8_t instance, const char* path);
/** @brief Dtor to clean up and close device */
~OccCommand()
{
closeDevice();
}
/** @brief Send the command to the OCC and collect the response.
* The checksum will be validated and removed from the response.
*
* @param[in] command - command to pass-through
* @param[out] response - response
* returns SUCCESS if response was received
*/
CmdStatus send(const std::vector<std::uint8_t>& command,
std::vector<std::uint8_t>& response);
private:
/** @brief Instance number of the target OCC */
uint8_t occInstance;
/** @brief OCC path on the bus */
std::string path;
/** @brief OCC device path
* For now, here is the hard-coded mapping until
* the udev rule is in.
* occ0 --> /dev/occ1
* occ1 --> /dev/occ2
* ...
*/
std::string devicePath;
/** @brief Indicates whether or not the OCC is currently active */
bool occActive = false;
/** brief file descriptor associated with occ device */
int fd = -1;
/** @brief Subscribe to OCC Status signal
*
* Once the OCC status gets to active, only then we will get /dev/occ2
* populated and hence need to wait on that before opening that
*/
sdbusplus::bus::match_t activeStatusSignal;
/** Opens devicePath and populates file descriptor */
void openDevice();
/** Closed the fd associated with opened device */
void closeDevice();
/** @brief Callback function on OCC Status change signals
*
* @param[in] msg - Data associated with subscribed signal
*/
void activeStatusEvent(sdbusplus::message_t& msg);
};
} // namespace occ
} // namespace open_power
template <>
struct std::formatter<open_power::occ::SysPwrMode> : formatter<int>
{
auto format(open_power::occ::SysPwrMode f, format_context& ctx) const
{
return formatter<int>::format(std::to_underlying(f), ctx);
}
};
template <>
struct std::formatter<open_power::occ::CmdStatus> : formatter<int>
{
auto format(open_power::occ::CmdStatus f, format_context& ctx) const
{
return formatter<int>::format(std::to_underlying(f), ctx);
}
};