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