| #pragma once |
| |
| #include <algorithm> |
| #include <array> |
| #include <sbe_interfaces.hpp> |
| #include <sstream> |
| #include <stdexcept> |
| #include <vector> |
| |
| namespace openpower |
| { |
| namespace sbe |
| { |
| |
| using sbe_word_t = uint32_t; |
| |
| namespace internal |
| { |
| |
| /** |
| * @brief Helper function for invokeSBEChipOperation(),to write to the SBE FIFO |
| * device and obtain the expected response .Internal device driver failures |
| * will be conveyed via respective exceptions. |
| * |
| * Exceptions thrown for: |
| * - Device driver internal failures |
| * |
| * @param[in] FIFO device path associated with SBE. |
| * @param[in] Command buffer to be written to the SBE FIFO |
| * @param[in] Length of command buffer |
| * @param[in] Expected response buffer length |
| * |
| * @return Response buffer returned by the SBE for the input command. |
| */ |
| std::vector<sbe_word_t> writeToFifo(const char* devPath, |
| const sbe_word_t* cmdBuffer, |
| size_t cmdBufLen, size_t respBufLen); |
| |
| /** |
| * @brief Helper function for invokeSBEChipOperation(), to parse and validate |
| * the data obtained from the SBE. Input buffer will be validated and on failure |
| * the FFDC content will be extracted and returned to the caller via |
| * respective exception. On success the input buffer will be modified to have |
| * only valid response data after removing the header content. |
| * |
| * Exceptions thrown for: |
| * - SBE Internal failures |
| * |
| * @param[in/out] On input - SBE data obtained from the SBE FIFO device. |
| * On output - Chip operation data after removing the response |
| * header. |
| */ |
| void parseResponse(std::vector<sbe_word_t>& sbeDataBuf); |
| |
| } // namespace internal |
| |
| /** |
| * @brief Interface to invoke a SBE chip operation.It calls internal API to |
| * write to the SBE FIFO and validates the data obtained by the SBE. It throws |
| * exception for any SBE internal failures. |
| * |
| * Runtime exceptions thrown for: |
| * - Device driver failures |
| * - SBE internal failures |
| * |
| * @param[in] FIFO device path associated with the SBE. |
| * @param[in] Request packet for the data to be read. |
| * @param[in] Data obtained by the SBE. |
| * @tparam S1 Length of request buffer to be send to SBE |
| * @tparam S2 Expected length of data from the SBE |
| */ |
| template <size_t S1, size_t S2> |
| inline void invokeSBEChipOperation(const char* devPath, |
| const std::array<sbe_word_t, S1>& request, |
| std::array<sbe_word_t, S2>& chipOpData) |
| { |
| // Write and read from the FIFO device. |
| auto sbeFifoResp = internal::writeToFifo(devPath, request.data(), |
| request.size(), chipOpData.size()); |
| |
| // Parse the obtained data |
| internal::parseResponse(sbeFifoResp); |
| // Above interface would have stripped the SBE header content from the input |
| // response buffer. |
| if (sbeFifoResp.size() > chipOpData.size()) |
| { |
| // TODO:use elog infrastructure |
| std::ostringstream errMsg; |
| errMsg << "Obtained chip operation response length (" |
| << sbeFifoResp.size() |
| << "from SBE is greater than maximum expected" |
| " length:" |
| << chipOpData.size(); |
| |
| throw std::runtime_error(errMsg.str().c_str()); |
| } |
| |
| // Move the contents of response buffer into the output buffer. |
| std::move(sbeFifoResp.begin(), sbeFifoResp.end(), chipOpData.begin()); |
| } |
| |
| } // namespace sbe |
| } // namespace openpower |