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