1 #pragma once
2 
3 #include <stdexcept>
4 #include <array>
5 #include <sstream>
6 #include <algorithm>
7 #include <vector>
8 #include <sbe_interfaces.hpp>
9 
10 namespace openpower
11 {
12 namespace sbe
13 {
14 
15 using sbe_word_t = uint32_t;
16 
17 namespace internal
18 {
19 
20 /**
21  * @brief Helper function for invokeSBEChipOperation(),to write to the SBE FIFO
22  * device and obtain the expected response .Internal device driver failures
23  * will be conveyed via respective exceptions.
24  *
25  * Exceptions thrown for:
26  * - Device driver internal failures
27  *
28  * @param[in] FIFO device path associated with SBE.
29  * @param[in] Command buffer to be written to the SBE FIFO
30  * @param[in] Length of command buffer
31  * @param[in] Expected response buffer length
32  *
33  * @return Response buffer returned by the SBE for the input command.
34  */
35 std::vector<sbe_word_t> writeToFifo(const char* devPath,
36                                     const sbe_word_t* cmdBuffer,
37                                     size_t cmdBufLen,
38                                     size_t respBufLen);
39 
40 /**
41  * @brief Helper function for invokeSBEChipOperation(), to parse and validate
42  * the data obtained from the SBE. Input buffer will be validated and on failure
43  * the FFDC content will be extracted and returned to the caller via
44  * respective exception. On success the input buffer will be modified to have
45  * only valid response data after removing the header content.
46  *
47  * Exceptions thrown for:
48  * - SBE Internal failures
49  *
50  * @param[in/out] On input  - SBE data obtained from the SBE FIFO device.
51  *                On output - Chip operation data after removing the response
52  *                            header.
53  */
54 void parseResponse(std::vector<sbe_word_t>& sbeDataBuf);
55 
56 }//end of internal namespace
57 
58 /**
59  * @brief Interface to invoke a SBE chip operation.It calls internal API to
60  * write to the SBE FIFO and validates the data obtained by the SBE. It throws
61  * exception for any SBE internal failures.
62  *
63  * Runtime exceptions thrown for:
64  * - Device driver failures
65  * - SBE internal failures
66  *
67  * @param[in] FIFO device path associated with the SBE.
68  * @param[in] Request packet for the data to be read.
69  * @param[in] Data obtained by the SBE.
70  * @tparam S1 Length of request buffer to be send to SBE
71  * @tparam S2 Expected length of data from the SBE
72  */
73 template<size_t S1, size_t S2>
74 inline void invokeSBEChipOperation(const char* devPath,
75                                    const std::array<sbe_word_t, S1>& request,
76                                    std::array<sbe_word_t, S2>& chipOpData)
77 {
78     //Write and read from the FIFO device.
79     auto sbeFifoResp = internal::writeToFifo(devPath, request.data(),
80                        request.size(), chipOpData.size());
81 
82     //Parse the obtained data
83     internal::parseResponse(sbeFifoResp);
84     //Above interface would have stripped the SBE header content from the input
85     //response buffer.
86     if (sbeFifoResp.size() > chipOpData.size())
87     {
88         //TODO:use elog infrastructure
89         std::ostringstream errMsg;
90         errMsg << "Obtained chip operation response length (" <<
91                sbeFifoResp.size() << "from SBE is greater than maximum expected"
92                " length:" << chipOpData.size();
93 
94         throw std::runtime_error(errMsg.str().c_str());
95     }
96 
97     //Move the contents of response buffer into the output buffer.
98     std::move(sbeFifoResp.begin(), sbeFifoResp.end(), chipOpData.begin());
99 }
100 
101 }
102 }
103 
104