xref: /openbmc/openpower-sbe-interface/sbe_chipOp_handler.cpp (revision 1adec02240baace29d41f9881e76f5089cfec6a0)
1 #include <stdexcept>
2 #include <array>
3 #include <sbe_chipOp_handler.hpp>
4 namespace openpower
5 {
6 namespace sbe
7 {
8 namespace internal
9 {
10 /*! \union sbeRespHeader_t
11  *  Defines the breakup of the SBE FIFO chip operation response header.
12  */
13 union sbeRespHeader_t
14 {
15     uint32_t commandWord; /**<Entire 32 bit command word */
16     struct
17     {
18         uint8_t command: 8; /**<command value for which response is obtained */
19         uint8_t commandClass: 8; /**< Class of the command */
20         uint16_t magic: 16; /**< Magic code obtained in the response */
21     };
22 } __attribute__((packed));
23 
24 
25 constexpr uint16_t MAGIC_CODE = 0xC0DE;
26 constexpr auto SBE_OPERATION_SUCCESSFUL = 0;
27 constexpr auto LENGTH_OF_DISTANCE_HEADER_IN_WORDS = 0x1;
28 constexpr auto LENGTH_OF_RESP_HEADER_IN_WORDS = 0x2;
29 constexpr auto SBEI_SBE_RESPONSE_SIZE_IN_WORDS = ((sizeof(sbeRespHeader_t) + \
30         sizeof(sbe_word_t)) / 4);
31 constexpr auto DISTANCE_TO_RESP_CODE = 0x1;
32 
33 std::vector<sbe_word_t> write(const char* devPath,
34                               const sbe_word_t* cmdBuffer,
35                               size_t cmdBufLen,
36                               size_t respBufLen)
37 {
38     //TODO: Add support for reading and writing from the FIFO device
39     std::vector<sbe_word_t> response(respBufLen);
40     return response;
41 }
42 
43 std::vector<sbe_word_t> parseResponse(
44     const std::vector<sbe_word_t>& sbeDataBuf)
45 {
46 
47     //Number of 32-bit words obtained from the SBE
48     size_t lengthObtained = sbeDataBuf.size();
49 
50     //Fetch the SBE header and SBE chiop primary and secondary status
51     //Last value in the buffer will have the offset for the SBE header
52     size_t distanceToStatusHeader =  sbeDataBuf[sbeDataBuf.size() - 1];
53 
54     if (lengthObtained < distanceToStatusHeader)
55     {
56         //TODO:use elog infrastructure
57         std::ostringstream errMsg;
58         errMsg << "Distance to SBE status header value " <<
59                distanceToStatusHeader << " is greater then total lenght of "
60                "response buffer " << lengthObtained;
61         throw std::runtime_error(errMsg.str().c_str());
62     }
63 
64     //Fetch the response header contents
65     sbeRespHeader_t l_respHeader{};
66     auto iter = sbeDataBuf.begin();
67     std::advance(iter, (lengthObtained - distanceToStatusHeader));
68     l_respHeader.commandWord = *iter;
69 
70     //Fetch the primary and secondary response code
71     std::advance(iter, DISTANCE_TO_RESP_CODE);
72     auto l_priSecResp = *iter;
73 
74     //Validate the magic code obtained in the response
75     if (l_respHeader.magic != MAGIC_CODE)
76     {
77         //TODO:use elog infrastructure
78         std::ostringstream errMsg;
79         errMsg << "Invalid MAGIC keyword in the response header (" <<
80                l_respHeader.magic << "),expected keyword " << MAGIC_CODE;
81         throw std::runtime_error(errMsg.str().c_str());
82     }
83 
84     //Validate the Primary and Secondary response value
85     if (l_priSecResp != SBE_OPERATION_SUCCESSFUL)
86     {
87         //Extract the SBE FFDC and throw it to the caller
88         size_t ffdcLen = (distanceToStatusHeader -
89                           SBEI_SBE_RESPONSE_SIZE_IN_WORDS -
90                           LENGTH_OF_DISTANCE_HEADER_IN_WORDS);
91         if (ffdcLen)
92         {
93             std::vector<sbe_word_t> ffdcData(ffdcLen);
94             //Fetch the offset of FFDC data
95             auto ffdcOffset = (lengthObtained - distanceToStatusHeader) +
96                               LENGTH_OF_RESP_HEADER_IN_WORDS;
97             std::copy_n((sbeDataBuf.begin() + ffdcOffset), ffdcLen,
98                         ffdcData.begin());
99         }
100 
101         //TODO:use elog infrastructure to return the SBE and Hardware procedure
102         //FFDC container back to the caller.
103         std::ostringstream errMsg;
104         errMsg << "Chip operation failed with SBE response code:" << l_priSecResp
105                << ".Length of FFDC data of obtained:" << ffdcLen;
106         throw std::runtime_error(errMsg.str().c_str());
107     }
108     return sbeDataBuf;
109 
110 }
111 
112 }
113 }
114 }
115 
116 
117