gem5  v22.1.0.0
scmi_protocols.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
39 
40 #include "debug/SCMI.hh"
42 
43 namespace gem5
44 {
45 
46 using namespace scmi;
47 
48 const std::string
50 {
51  return platform.name();
52 }
53 
55  : Protocol(_platform),
56  vendor(platform.params().base_vendor),
57  subvendor(platform.params().base_subvendor),
58  implementationVersion(platform.params().base_impl_version)
59 {
60  fatal_if(vendor.length() > MAX_STRING_SIZE,
61  "Invalid BASE_PROTOCOL VENDOR size\n");
63  "Invalid BASE_PROTOCOL SUBVENDOR size\n");
64 }
65 
66 void
68 {
69  auto message_id = Platform::messageID(msg);
70 
71  DPRINTF(SCMI, "Handling SCMI message:\n");
72  DPRINTF(SCMI, "# Message Protocol = BASE_PROTOCOL\n");
73  DPRINTF(SCMI, "# Message ID = %u\n", message_id);
74 
75  switch (static_cast<Commands>(message_id)) {
76  case Commands::VERSION:
77  version(msg);
78  break;
80  attributes(msg);
81  break;
83  messageAttributes(msg);
84  break;
86  discoverVendor(msg);
87  break;
89  discoverSubVendor(msg);
90  break;
93  break;
96  break;
98  discoverAgent(msg);
99  break;
104  default:
105  invalidCommand(msg);
106  warn("Unimplemented SCMI command: %u\n", message_id);
107  }
108 }
109 
110 void
112 {
113  auto& payload = msg.payload.baseProtocolVersion;
114  payload.status = SUCCESS;
115  payload.version = PROTOCOL_VERSION;
116 
117  // header + status + return
118  msg.length = sizeof(uint32_t) * 3;
119 }
120 
121 void
123 {
124  uint32_t _attributes = 0;
125 
126  replaceBits(_attributes, 15, 8, platform.numAgents());
127  replaceBits(_attributes, 7, 0, platform.numProtocols());
128 
129  auto& payload = msg.payload.baseProtocolAttributes;
130  payload.status = SUCCESS;
131  payload.attributes = _attributes;
132 
133  // header + status + return
134  msg.length = sizeof(uint32_t) * 3;
135 }
136 
137 bool
139 {
140  switch (message_id) {
141  case Commands::VERSION:
149  return true;
150  default:
151  return false;
152  }
153 }
154 
155 void
157 {
158  auto& payload = msg.payload.baseProtocolMessageAttributes;
159  const auto message_id = static_cast<Commands>(
160  payload.messageId);
161 
162  if (!implementedProtocol(message_id)) {
163  payload.status = NOT_FOUND;
164  } else {
165  payload.status = SUCCESS;
166  }
167 
168  // For all messages in the Base protocol, 0 must be returned
169  payload.attributes = 0;
170 
171  // header + status + return
172  msg.length = sizeof(uint32_t) * 3;
173 }
174 
175 void
177 {
178  auto& payload = msg.payload.baseDiscoverVendor;
179  payload.status = SUCCESS;
180 
181  auto vendor_size = vendor.copy(
182  (char*)&payload.vendorIdentifier, MAX_STRING_SIZE);
183 
184  // header + status + payload
185  msg.length = sizeof(uint32_t) * 2 + vendor_size;
186 }
187 
188 void
190 {
191  auto& payload = msg.payload.baseDiscoverSubVendor;
192  payload.status = SUCCESS;
193 
194  auto subvendor_size = subvendor.copy(
195  (char*)&payload.vendorIdentifier, MAX_STRING_SIZE);
196 
197  // header + status + payload
198  msg.length = sizeof(uint32_t) * 2 + subvendor_size;
199 }
200 
201 void
203 {
204  auto& payload = msg.payload.baseDiscoverImplementationVersion;
205  payload.status = SUCCESS;
206  payload.implementationVersion = implementationVersion;
207 
208  // header + status + return
209  msg.length = sizeof(uint32_t) * 3;
210 }
211 
212 void
214 {
215  auto& payload = msg.payload.baseDiscoverListProtocols;
216  const uint32_t skip = payload.skip;
217  const auto num_protocols = platform.numProtocols();
218 
219  if (skip > num_protocols) {
220  payload.status = INVALID_PARAMETERS;
221  msg.length = sizeof(uint32_t) * 2;
222 
223  } else {
224  const auto& protocol_list = platform.protocolList();
225  auto *protocols = (uint8_t*)payload.protocols;
226  uint32_t num_implemented = 0;
227 
228  for (auto protoc_id = START + skip; protoc_id <= END; protoc_id++) {
229  auto it = protocol_list.find(protoc_id);
230  if (it != protocol_list.end()) {
231  num_implemented++;
232 
233  *protocols = it->first;
234  protocols++;
235  }
236  }
237 
238  payload.status = SUCCESS;
239  payload.numProtocols = num_implemented;
240 
241  // header + status + return
242  msg.length = sizeof(uint32_t) * 3;
243  }
244 }
245 
246 void
248 {
249  auto& payload = msg.payload.baseDiscoverAgent;
250  const uint32_t agent_id = payload.agentId;
251 
252  if (agent_id > platform.numAgents()) {
253  payload.status = NOT_FOUND;
254  msg.length = sizeof(uint32_t) * 2;
255 
256  } else {
257  auto agent_size = 0;
258  auto agent_name = std::string();
259 
260  if (agent_id) {
261  // Subtracting one to the agent_id, since agent_id 0 is reserved
262  // for the platform.
263  agent_name = platform.getAgent(agent_id - 1);
264  } else {
265  agent_name = "platform";
266  }
267 
268  agent_size = agent_name.length();
269 
270  strncpy((char *)&payload.name,
271  agent_name.c_str(), agent_size);
272 
273  payload.status = SUCCESS;
274  // header + status + payload
275  msg.length = sizeof(uint32_t) * 2 + agent_size;
276  }
277 }
278 
279 void
281 {
282  auto& payload = msg.payload.invalidCommand;
283  payload.status = NOT_FOUND;
284  msg.length = sizeof(uint32_t) * 2;
285 }
286 
287 } // namespace gem5
#define DPRINTF(x,...)
Definition: trace.hh:186
virtual std::string name() const
Definition: named.hh:47
const std::string vendor
void discoverImplVersion(Message &msg)
void version(Message &msg) override
void discoverVendor(Message &msg)
void messageAttributes(Message &msg) override
bool implementedProtocol(Commands message_id) const
void discoverListProtocols(Message &msg)
static const uint32_t PROTOCOL_VERSION
void discoverSubVendor(Message &msg)
void invalidCommand(Message &msg)
void discoverAgent(Message &msg)
BaseProtocol(Platform &_platform)
void handleMessage(Message &msg) override
const uint32_t implementationVersion
void attributes(Message &msg) override
const std::string subvendor
static uint32_t messageID(const Message &msg)
const char * getAgent(unsigned index) const
Returns the name of an agent given an index.
const ProtocolList & protocolList() const
uint32_t numAgents() const
Returns the number of agents in the system.
uint32_t numProtocols() const
Returns the number of protocols implemented, except for the base protocol.
const std::string name() const
static const uint32_t MAX_STRING_SIZE
constexpr void replaceBits(T &val, unsigned first, unsigned last, B bit_val)
A convenience function to replace bits first to last of val with bit_val in place.
Definition: bitfield.hh:197
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:226
#define warn(...)
Definition: logging.hh:246
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....

Generated on Wed Dec 21 2022 10:22:32 for gem5 by doxygen 1.9.1