1207bed41SMurulidhar Nataraju #include <iostream> 2207bed41SMurulidhar Nataraju #include <stdexcept> 3207bed41SMurulidhar Nataraju #include <array> 406a0c2c4SMurulidhar Nataraju #include <endian.h> 5207bed41SMurulidhar Nataraju #include "sbe_interfaces.hpp" 61adec022SMurulidhar Nataraju #include "sbe_chipOp_handler.hpp" 7207bed41SMurulidhar Nataraju 8207bed41SMurulidhar Nataraju namespace openpower 9207bed41SMurulidhar Nataraju { 10207bed41SMurulidhar Nataraju namespace sbe 11207bed41SMurulidhar Nataraju { 12207bed41SMurulidhar Nataraju 131adec022SMurulidhar Nataraju constexpr size_t RESP_HEADER_LEN = 0x3; 141adec022SMurulidhar Nataraju 15207bed41SMurulidhar Nataraju //Helper interfaces 16207bed41SMurulidhar Nataraju static inline uint32_t upper(uint64_t value) 17207bed41SMurulidhar Nataraju { 18207bed41SMurulidhar Nataraju return ((value & 0xFFFFFFFF00000000ull) >> 32); 19207bed41SMurulidhar Nataraju } 20207bed41SMurulidhar Nataraju 21207bed41SMurulidhar Nataraju static inline uint32_t lower(uint64_t value) 22207bed41SMurulidhar Nataraju { 23207bed41SMurulidhar Nataraju return (value & 0xFFFFFFFF); 24207bed41SMurulidhar Nataraju } 25207bed41SMurulidhar Nataraju 26207bed41SMurulidhar Nataraju using sbe_word_t = uint32_t; 27207bed41SMurulidhar Nataraju 28207bed41SMurulidhar Nataraju namespace scom 29207bed41SMurulidhar Nataraju { 30207bed41SMurulidhar Nataraju 31207bed41SMurulidhar Nataraju //Constants specific to SCOM operations 32207bed41SMurulidhar Nataraju static constexpr sbe_word_t READ_OPCODE = 0x0000A201; 33207bed41SMurulidhar Nataraju static constexpr sbe_word_t WRITE_OPCODE = 0x0000A202; 34207bed41SMurulidhar Nataraju static constexpr size_t READ_CMD_LENGTH = 0x4; 35207bed41SMurulidhar Nataraju static constexpr size_t WRITE_CMD_LENGTH = 0x6; 361adec022SMurulidhar Nataraju static constexpr size_t READ_RESP_LENGTH = 0x2; 37207bed41SMurulidhar Nataraju 38207bed41SMurulidhar Nataraju //Reading SCOM Registers 39207bed41SMurulidhar Nataraju uint64_t read(const char* devPath, 40207bed41SMurulidhar Nataraju uint64_t address) 41207bed41SMurulidhar Nataraju { 42207bed41SMurulidhar Nataraju uint64_t value = 0; 43207bed41SMurulidhar Nataraju 44207bed41SMurulidhar Nataraju //Validate input device path 45207bed41SMurulidhar Nataraju if (devPath == nullptr) 46207bed41SMurulidhar Nataraju { 47207bed41SMurulidhar Nataraju throw std::runtime_error("NULL FIFO device path"); 48207bed41SMurulidhar Nataraju } 49207bed41SMurulidhar Nataraju 5006a0c2c4SMurulidhar Nataraju //Build SCOM read request command. 5106a0c2c4SMurulidhar Nataraju //Handle byte order mismatch ,SBE is big endian and BMC is 5206a0c2c4SMurulidhar Nataraju //little endian. 53207bed41SMurulidhar Nataraju std::array<sbe_word_t, READ_CMD_LENGTH> command = 54207bed41SMurulidhar Nataraju { 55*7a6479ffSBenjamin Herrenschmidt static_cast<sbe_word_t>(htobe32(READ_CMD_LENGTH)), 5606a0c2c4SMurulidhar Nataraju htobe32(READ_OPCODE), 5706a0c2c4SMurulidhar Nataraju htobe32(upper(address)), 5806a0c2c4SMurulidhar Nataraju htobe32(lower(address)) 59207bed41SMurulidhar Nataraju }; 60207bed41SMurulidhar Nataraju 611adec022SMurulidhar Nataraju //Buffer to hold the response data along with the SBE header 621adec022SMurulidhar Nataraju const size_t respLength = RESP_HEADER_LEN + READ_RESP_LENGTH ; 631adec022SMurulidhar Nataraju std::array<sbe_word_t, respLength> response = {}; 64207bed41SMurulidhar Nataraju 651adec022SMurulidhar Nataraju //Write the command buffer to the SBE FIFO and obtain the response from the 661adec022SMurulidhar Nataraju //SBE FIFO device.This interface will parse the obtained SBE response and 671adec022SMurulidhar Nataraju //any internal SBE failures will be communicated via exceptions 681adec022SMurulidhar Nataraju invokeSBEChipOperation(devPath, command, response); 69207bed41SMurulidhar Nataraju 701adec022SMurulidhar Nataraju value = (((static_cast<uint64_t>(response[0])) << 32) | response[1]); 71207bed41SMurulidhar Nataraju return value; 72207bed41SMurulidhar Nataraju } 73207bed41SMurulidhar Nataraju 74207bed41SMurulidhar Nataraju void write(const char* devPath, 75207bed41SMurulidhar Nataraju uint64_t address, 76207bed41SMurulidhar Nataraju uint64_t data) 77207bed41SMurulidhar Nataraju { 78207bed41SMurulidhar Nataraju //Validate input device path 79207bed41SMurulidhar Nataraju if (devPath == nullptr) 80207bed41SMurulidhar Nataraju { 81207bed41SMurulidhar Nataraju throw std::runtime_error("NULL FIFO device path"); 82207bed41SMurulidhar Nataraju } 83207bed41SMurulidhar Nataraju 84207bed41SMurulidhar Nataraju //Build SCOM write request command 8506a0c2c4SMurulidhar Nataraju //Handle byte order mismatch, SBE is big endian and BMC is 8606a0c2c4SMurulidhar Nataraju //little endian. 87207bed41SMurulidhar Nataraju std::array<sbe_word_t, WRITE_CMD_LENGTH> command = 88207bed41SMurulidhar Nataraju { 89*7a6479ffSBenjamin Herrenschmidt static_cast<sbe_word_t>(htobe32(WRITE_CMD_LENGTH)), 9006a0c2c4SMurulidhar Nataraju htobe32(WRITE_OPCODE), 9106a0c2c4SMurulidhar Nataraju htobe32(upper(address)), 9206a0c2c4SMurulidhar Nataraju htobe32(lower(address)), 9306a0c2c4SMurulidhar Nataraju htobe32(upper(data)), 9406a0c2c4SMurulidhar Nataraju htobe32(lower(data)) 95207bed41SMurulidhar Nataraju }; 96207bed41SMurulidhar Nataraju 971adec022SMurulidhar Nataraju //Buffer to hold the SBE response status 981adec022SMurulidhar Nataraju const size_t respLength = RESP_HEADER_LEN; 991adec022SMurulidhar Nataraju std::array<sbe_word_t, respLength> response = {}; 100207bed41SMurulidhar Nataraju 1011adec022SMurulidhar Nataraju //Write the command buffer to the SBE FIFO and obtain the response from the 1021adec022SMurulidhar Nataraju //SBE FIFO device.This interface will parse the obtained SBE response and 1031adec022SMurulidhar Nataraju //any internal SBE failures will be communicated via exceptions 1041adec022SMurulidhar Nataraju invokeSBEChipOperation(devPath, command, response); 105207bed41SMurulidhar Nataraju } 106207bed41SMurulidhar Nataraju 107207bed41SMurulidhar Nataraju } // namespace scom 108207bed41SMurulidhar Nataraju } // namespace sbe 109207bed41SMurulidhar Nataraju } // namespace openpower 110