blob: 3e29c1e83372f1f99646dee2a4ff876f2dd36e1d [file] [log] [blame]
#pragma once
#include <stdexcept>
#include <array>
#include <sstream>
#include <algorithm>
#include <vector>
#include <sbe_interfaces.hpp>
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);
}//end of internal namespace
/**
* @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());
}
}
}