1 #include <iostream> 2 #include <stdexcept> 3 #include <array> 4 #include <endian.h> 5 #include "sbe_interfaces.hpp" 6 #include "sbe_chipOp_handler.hpp" 7 8 namespace openpower 9 { 10 namespace sbe 11 { 12 13 constexpr size_t RESP_HEADER_LEN = 0x3; 14 15 //Helper interfaces 16 static inline uint32_t upper(uint64_t value) 17 { 18 return ((value & 0xFFFFFFFF00000000ull) >> 32); 19 } 20 21 static inline uint32_t lower(uint64_t value) 22 { 23 return (value & 0xFFFFFFFF); 24 } 25 26 using sbe_word_t = uint32_t; 27 28 namespace scom 29 { 30 31 //Constants specific to SCOM operations 32 static constexpr sbe_word_t READ_OPCODE = 0x0000A201; 33 static constexpr sbe_word_t WRITE_OPCODE = 0x0000A202; 34 static constexpr size_t READ_CMD_LENGTH = 0x4; 35 static constexpr size_t WRITE_CMD_LENGTH = 0x6; 36 static constexpr size_t READ_RESP_LENGTH = 0x2; 37 38 //Reading SCOM Registers 39 uint64_t read(const char* devPath, 40 uint64_t address) 41 { 42 uint64_t value = 0; 43 44 //Validate input device path 45 if (devPath == nullptr) 46 { 47 throw std::runtime_error("NULL FIFO device path"); 48 } 49 50 //Build SCOM read request command. 51 //Handle byte order mismatch ,SBE is big endian and BMC is 52 //little endian. 53 std::array<sbe_word_t, READ_CMD_LENGTH> command = 54 { 55 static_cast<sbe_word_t>(READ_CMD_LENGTH), 56 htobe32(READ_OPCODE), 57 htobe32(upper(address)), 58 htobe32(lower(address)) 59 }; 60 61 //Buffer to hold the response data along with the SBE header 62 const size_t respLength = RESP_HEADER_LEN + READ_RESP_LENGTH ; 63 std::array<sbe_word_t, respLength> response = {}; 64 65 //Write the command buffer to the SBE FIFO and obtain the response from the 66 //SBE FIFO device.This interface will parse the obtained SBE response and 67 //any internal SBE failures will be communicated via exceptions 68 invokeSBEChipOperation(devPath, command, response); 69 70 value = (((static_cast<uint64_t>(response[0])) << 32) | response[1]); 71 return value; 72 } 73 74 void write(const char* devPath, 75 uint64_t address, 76 uint64_t data) 77 { 78 //Validate input device path 79 if (devPath == nullptr) 80 { 81 throw std::runtime_error("NULL FIFO device path"); 82 } 83 84 //Build SCOM write request command 85 //Handle byte order mismatch, SBE is big endian and BMC is 86 //little endian. 87 std::array<sbe_word_t, WRITE_CMD_LENGTH> command = 88 { 89 static_cast<sbe_word_t>(WRITE_CMD_LENGTH), 90 htobe32(WRITE_OPCODE), 91 htobe32(upper(address)), 92 htobe32(lower(address)), 93 htobe32(upper(data)), 94 htobe32(lower(data)) 95 }; 96 97 //Buffer to hold the SBE response status 98 const size_t respLength = RESP_HEADER_LEN; 99 std::array<sbe_word_t, respLength> response = {}; 100 101 //Write the command buffer to the SBE FIFO and obtain the response from the 102 //SBE FIFO device.This interface will parse the obtained SBE response and 103 //any internal SBE failures will be communicated via exceptions 104 invokeSBEChipOperation(devPath, command, response); 105 } 106 107 } // namespace scom 108 } // namespace sbe 109 } // namespace openpower 110