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