blob: f662690a7ac44e7b8920513ca762b7365eec4cab [file] [log] [blame]
Murulidhar Nataraju1adec022017-04-20 12:05:51 -05001#include <stdexcept>
2#include <array>
3#include <sbe_chipOp_handler.hpp>
4namespace openpower
5{
6namespace sbe
7{
8namespace internal
9{
10/*! \union sbeRespHeader_t
11 * Defines the breakup of the SBE FIFO chip operation response header.
12 */
13union 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
25constexpr uint16_t MAGIC_CODE = 0xC0DE;
26constexpr auto SBE_OPERATION_SUCCESSFUL = 0;
27constexpr auto LENGTH_OF_DISTANCE_HEADER_IN_WORDS = 0x1;
28constexpr auto LENGTH_OF_RESP_HEADER_IN_WORDS = 0x2;
29constexpr auto SBEI_SBE_RESPONSE_SIZE_IN_WORDS = ((sizeof(sbeRespHeader_t) + \
30 sizeof(sbe_word_t)) / 4);
31constexpr auto DISTANCE_TO_RESP_CODE = 0x1;
32
33std::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
43std::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