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