xref: /openbmc/google-ipmi-sys/cpld.cpp (revision 0e9aae5d)
14d49ae65SPatrick Venture /*
24d49ae65SPatrick Venture  * Copyright 2018 Google Inc.
34d49ae65SPatrick Venture  *
44d49ae65SPatrick Venture  * Licensed under the Apache License, Version 2.0 (the "License");
54d49ae65SPatrick Venture  * you may not use this file except in compliance with the License.
64d49ae65SPatrick Venture  * You may obtain a copy of the License at
74d49ae65SPatrick Venture  *
84d49ae65SPatrick Venture  *     http://www.apache.org/licenses/LICENSE-2.0
94d49ae65SPatrick Venture  *
104d49ae65SPatrick Venture  * Unless required by applicable law or agreed to in writing, software
114d49ae65SPatrick Venture  * distributed under the License is distributed on an "AS IS" BASIS,
124d49ae65SPatrick Venture  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134d49ae65SPatrick Venture  * See the License for the specific language governing permissions and
144d49ae65SPatrick Venture  * limitations under the License.
154d49ae65SPatrick Venture  */
164d49ae65SPatrick Venture 
174d49ae65SPatrick Venture #include "cpld.hpp"
184d49ae65SPatrick Venture 
19*0e9aae5dSPatrick Venture #include "commands.hpp"
20bb90d4fdSPatrick Venture #include "errors.hpp"
21bb90d4fdSPatrick Venture #include "handler.hpp"
224d49ae65SPatrick Venture 
23ce07ee0aSPatrick Venture #include <cstring>
244d49ae65SPatrick Venture 
254d49ae65SPatrick Venture namespace google
264d49ae65SPatrick Venture {
274d49ae65SPatrick Venture namespace ipmi
284d49ae65SPatrick Venture {
294d49ae65SPatrick Venture 
304d49ae65SPatrick Venture struct CpldRequest
314d49ae65SPatrick Venture {
324d49ae65SPatrick Venture     uint8_t subcommand;
334d49ae65SPatrick Venture     uint8_t id;
344d49ae65SPatrick Venture } __attribute__((packed));
354d49ae65SPatrick Venture 
364d49ae65SPatrick Venture struct CpldReply
374d49ae65SPatrick Venture {
384d49ae65SPatrick Venture     uint8_t subcommand;
394d49ae65SPatrick Venture     uint8_t major;
404d49ae65SPatrick Venture     uint8_t minor;
414d49ae65SPatrick Venture     uint8_t point;
424d49ae65SPatrick Venture     uint8_t subpoint;
434d49ae65SPatrick Venture } __attribute__((packed));
444d49ae65SPatrick Venture 
454d49ae65SPatrick Venture //
464d49ae65SPatrick Venture // Handle reading the cpld version from the tmpfs.
474d49ae65SPatrick Venture //
4845fad1bbSPatrick Venture ipmi_ret_t cpldVersion(const uint8_t* reqBuf, uint8_t* replyBuf,
49bb90d4fdSPatrick Venture                        size_t* dataLen, const HandlerInterface* handler)
504d49ae65SPatrick Venture {
51acd5423aSPatrick Venture     struct CpldRequest request;
52acd5423aSPatrick Venture 
53acd5423aSPatrick Venture     if ((*dataLen) < sizeof(request))
544d49ae65SPatrick Venture     {
55ce07ee0aSPatrick Venture         std::fprintf(stderr, "Invalid command length: %u\n",
560dede335SPatrick Venture                      static_cast<uint32_t>(*dataLen));
57fff98617SPatrick Venture         return IPMI_CC_REQ_DATA_LEN_INVALID;
584d49ae65SPatrick Venture     }
594d49ae65SPatrick Venture 
604d49ae65SPatrick Venture     // reqBuf[0] is the subcommand.
614d49ae65SPatrick Venture     // reqBuf[1] is the CPLD id. "/run/cpld{id}.version" is what we read.
624d49ae65SPatrick Venture     // Verified that this cast actually returns the value 255 and not something
634d49ae65SPatrick Venture     // negative in the case where reqBuf[1] is 0xff.  However, it looks weird
644d49ae65SPatrick Venture     // since I would expect int(uint8(0xff)) to be -1.  So, just cast it
654d49ae65SPatrick Venture     // unsigned. we're casting to an int width to avoid it thinking it's a
664d49ae65SPatrick Venture     // letter, because it does that.
67acd5423aSPatrick Venture     std::memcpy(&request, &reqBuf[0], sizeof(request));
684d49ae65SPatrick Venture 
694d49ae65SPatrick Venture     try
704d49ae65SPatrick Venture     {
71bb90d4fdSPatrick Venture         auto values =
72bb90d4fdSPatrick Venture             handler->getCpldVersion(static_cast<unsigned int>(request.id));
734d49ae65SPatrick Venture 
744d49ae65SPatrick Venture         // Truncate if the version is too high (documented).
754d49ae65SPatrick Venture         struct CpldReply reply;
764d49ae65SPatrick Venture         reply.subcommand = SysCpldVersion;
77bb90d4fdSPatrick Venture         reply.major = std::get<0>(values);
78bb90d4fdSPatrick Venture         reply.minor = std::get<1>(values);
79bb90d4fdSPatrick Venture         reply.point = std::get<2>(values);
80bb90d4fdSPatrick Venture         reply.subpoint = std::get<3>(values);
814d49ae65SPatrick Venture 
82acd5423aSPatrick Venture         std::memcpy(&replyBuf[0], &reply, sizeof(reply));
83acd5423aSPatrick Venture         (*dataLen) = sizeof(reply);
844d49ae65SPatrick Venture         return IPMI_CC_OK;
854d49ae65SPatrick Venture     }
86bb90d4fdSPatrick Venture     catch (const IpmiException& e)
87bb90d4fdSPatrick Venture     {
88bb90d4fdSPatrick Venture         return e.getIpmiError();
89bb90d4fdSPatrick Venture     }
90bb90d4fdSPatrick Venture }
914d49ae65SPatrick Venture 
924d49ae65SPatrick Venture } // namespace ipmi
934d49ae65SPatrick Venture } // namespace google
94