1*da79c9caSPatrick Venture #include "sbe_interfaces.hpp"
2*da79c9caSPatrick Venture
3*da79c9caSPatrick Venture #include "sbe_chipOp_handler.hpp"
4*da79c9caSPatrick Venture
5*da79c9caSPatrick Venture #include <endian.h>
6*da79c9caSPatrick Venture
7*da79c9caSPatrick Venture #include <array>
8207bed41SMurulidhar Nataraju #include <iostream>
9207bed41SMurulidhar Nataraju #include <stdexcept>
10207bed41SMurulidhar Nataraju
11207bed41SMurulidhar Nataraju namespace openpower
12207bed41SMurulidhar Nataraju {
13207bed41SMurulidhar Nataraju namespace sbe
14207bed41SMurulidhar Nataraju {
15207bed41SMurulidhar Nataraju
161adec022SMurulidhar Nataraju constexpr size_t RESP_HEADER_LEN = 0x3;
171adec022SMurulidhar Nataraju
18207bed41SMurulidhar Nataraju // Helper interfaces
upper(uint64_t value)19207bed41SMurulidhar Nataraju static inline uint32_t upper(uint64_t value)
20207bed41SMurulidhar Nataraju {
21207bed41SMurulidhar Nataraju return ((value & 0xFFFFFFFF00000000ull) >> 32);
22207bed41SMurulidhar Nataraju }
23207bed41SMurulidhar Nataraju
lower(uint64_t value)24207bed41SMurulidhar Nataraju static inline uint32_t lower(uint64_t value)
25207bed41SMurulidhar Nataraju {
26207bed41SMurulidhar Nataraju return (value & 0xFFFFFFFF);
27207bed41SMurulidhar Nataraju }
28207bed41SMurulidhar Nataraju
29207bed41SMurulidhar Nataraju using sbe_word_t = uint32_t;
30207bed41SMurulidhar Nataraju
31207bed41SMurulidhar Nataraju namespace scom
32207bed41SMurulidhar Nataraju {
33207bed41SMurulidhar Nataraju
34207bed41SMurulidhar Nataraju // Constants specific to SCOM operations
35207bed41SMurulidhar Nataraju static constexpr sbe_word_t READ_OPCODE = 0x0000A201;
36207bed41SMurulidhar Nataraju static constexpr sbe_word_t WRITE_OPCODE = 0x0000A202;
37207bed41SMurulidhar Nataraju static constexpr size_t READ_CMD_LENGTH = 0x4;
38207bed41SMurulidhar Nataraju static constexpr size_t WRITE_CMD_LENGTH = 0x6;
391adec022SMurulidhar Nataraju static constexpr size_t READ_RESP_LENGTH = 0x2;
40207bed41SMurulidhar Nataraju
41207bed41SMurulidhar Nataraju // Reading SCOM Registers
read(const char * devPath,uint64_t address)42*da79c9caSPatrick Venture uint64_t read(const char* devPath, uint64_t address)
43207bed41SMurulidhar Nataraju {
44207bed41SMurulidhar Nataraju uint64_t value = 0;
45207bed41SMurulidhar Nataraju
46207bed41SMurulidhar Nataraju // Validate input device path
47207bed41SMurulidhar Nataraju if (devPath == nullptr)
48207bed41SMurulidhar Nataraju {
49207bed41SMurulidhar Nataraju throw std::runtime_error("NULL FIFO device path");
50207bed41SMurulidhar Nataraju }
51207bed41SMurulidhar Nataraju
5206a0c2c4SMurulidhar Nataraju // Build SCOM read request command.
5306a0c2c4SMurulidhar Nataraju // Handle byte order mismatch ,SBE is big endian and BMC is
5406a0c2c4SMurulidhar Nataraju // little endian.
55*da79c9caSPatrick Venture std::array<sbe_word_t, READ_CMD_LENGTH> command = {
56*da79c9caSPatrick Venture static_cast<sbe_word_t>(htobe32(READ_CMD_LENGTH)), htobe32(READ_OPCODE),
57*da79c9caSPatrick Venture htobe32(upper(address)), htobe32(lower(address))};
58207bed41SMurulidhar Nataraju
591adec022SMurulidhar Nataraju // Buffer to hold the response data along with the SBE header
601adec022SMurulidhar Nataraju const size_t respLength = RESP_HEADER_LEN + READ_RESP_LENGTH;
611adec022SMurulidhar Nataraju std::array<sbe_word_t, respLength> response = {};
62207bed41SMurulidhar Nataraju
631adec022SMurulidhar Nataraju // Write the command buffer to the SBE FIFO and obtain the response from the
641adec022SMurulidhar Nataraju // SBE FIFO device.This interface will parse the obtained SBE response and
651adec022SMurulidhar Nataraju // any internal SBE failures will be communicated via exceptions
661adec022SMurulidhar Nataraju invokeSBEChipOperation(devPath, command, response);
67207bed41SMurulidhar Nataraju
681adec022SMurulidhar Nataraju value = (((static_cast<uint64_t>(response[0])) << 32) | response[1]);
69207bed41SMurulidhar Nataraju return value;
70207bed41SMurulidhar Nataraju }
71207bed41SMurulidhar Nataraju
write(const char * devPath,uint64_t address,uint64_t data)72*da79c9caSPatrick Venture void write(const char* devPath, uint64_t address, uint64_t data)
73207bed41SMurulidhar Nataraju {
74207bed41SMurulidhar Nataraju // Validate input device path
75207bed41SMurulidhar Nataraju if (devPath == nullptr)
76207bed41SMurulidhar Nataraju {
77207bed41SMurulidhar Nataraju throw std::runtime_error("NULL FIFO device path");
78207bed41SMurulidhar Nataraju }
79207bed41SMurulidhar Nataraju
80207bed41SMurulidhar Nataraju // Build SCOM write request command
8106a0c2c4SMurulidhar Nataraju // Handle byte order mismatch, SBE is big endian and BMC is
8206a0c2c4SMurulidhar Nataraju // little endian.
83*da79c9caSPatrick Venture std::array<sbe_word_t, WRITE_CMD_LENGTH> command = {
847a6479ffSBenjamin Herrenschmidt static_cast<sbe_word_t>(htobe32(WRITE_CMD_LENGTH)),
8506a0c2c4SMurulidhar Nataraju htobe32(WRITE_OPCODE),
8606a0c2c4SMurulidhar Nataraju htobe32(upper(address)),
8706a0c2c4SMurulidhar Nataraju htobe32(lower(address)),
8806a0c2c4SMurulidhar Nataraju htobe32(upper(data)),
89*da79c9caSPatrick Venture htobe32(lower(data))};
90207bed41SMurulidhar Nataraju
911adec022SMurulidhar Nataraju // Buffer to hold the SBE response status
921adec022SMurulidhar Nataraju const size_t respLength = RESP_HEADER_LEN;
931adec022SMurulidhar Nataraju std::array<sbe_word_t, respLength> response = {};
94207bed41SMurulidhar Nataraju
951adec022SMurulidhar Nataraju // Write the command buffer to the SBE FIFO and obtain the response from the
961adec022SMurulidhar Nataraju // SBE FIFO device.This interface will parse the obtained SBE response and
971adec022SMurulidhar Nataraju // any internal SBE failures will be communicated via exceptions
981adec022SMurulidhar Nataraju invokeSBEChipOperation(devPath, command, response);
99207bed41SMurulidhar Nataraju }
100207bed41SMurulidhar Nataraju
101207bed41SMurulidhar Nataraju } // namespace scom
102207bed41SMurulidhar Nataraju } // namespace sbe
103207bed41SMurulidhar Nataraju } // namespace openpower
104