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