blob: bf777b261c3d31ffeeacd70c04f371c784f163c7 [file] [log] [blame]
Patrick Ventureda79c9c2018-11-01 15:35:52 -07001#include "sbe_interfaces.hpp"
2
3#include "sbe_chipOp_handler.hpp"
4
5#include <endian.h>
6
7#include <array>
Murulidhar Nataraju207bed42017-03-31 07:38:55 -05008#include <iostream>
9#include <stdexcept>
Murulidhar Nataraju207bed42017-03-31 07:38:55 -050010
11namespace openpower
12{
13namespace sbe
14{
15
Murulidhar Nataraju1adec022017-04-20 12:05:51 -050016constexpr size_t RESP_HEADER_LEN = 0x3;
17
Patrick Ventureda79c9c2018-11-01 15:35:52 -070018// Helper interfaces
Murulidhar Nataraju207bed42017-03-31 07:38:55 -050019static inline uint32_t upper(uint64_t value)
20{
21 return ((value & 0xFFFFFFFF00000000ull) >> 32);
22}
23
24static inline uint32_t lower(uint64_t value)
25{
26 return (value & 0xFFFFFFFF);
27}
28
29using sbe_word_t = uint32_t;
30
31namespace scom
32{
33
Patrick Ventureda79c9c2018-11-01 15:35:52 -070034// Constants specific to SCOM operations
35static constexpr sbe_word_t READ_OPCODE = 0x0000A201;
Murulidhar Nataraju207bed42017-03-31 07:38:55 -050036static constexpr sbe_word_t WRITE_OPCODE = 0x0000A202;
37static constexpr size_t READ_CMD_LENGTH = 0x4;
38static constexpr size_t WRITE_CMD_LENGTH = 0x6;
Murulidhar Nataraju1adec022017-04-20 12:05:51 -050039static constexpr size_t READ_RESP_LENGTH = 0x2;
Murulidhar Nataraju207bed42017-03-31 07:38:55 -050040
Patrick Ventureda79c9c2018-11-01 15:35:52 -070041// Reading SCOM Registers
42uint64_t read(const char* devPath, uint64_t address)
Murulidhar Nataraju207bed42017-03-31 07:38:55 -050043{
44 uint64_t value = 0;
45
Patrick Ventureda79c9c2018-11-01 15:35:52 -070046 // Validate input device path
Murulidhar Nataraju207bed42017-03-31 07:38:55 -050047 if (devPath == nullptr)
48 {
49 throw std::runtime_error("NULL FIFO device path");
50 }
51
Patrick Ventureda79c9c2018-11-01 15:35:52 -070052 // Build SCOM read request command.
53 // Handle byte order mismatch ,SBE is big endian and BMC is
54 // little endian.
55 std::array<sbe_word_t, READ_CMD_LENGTH> command = {
56 static_cast<sbe_word_t>(htobe32(READ_CMD_LENGTH)), htobe32(READ_OPCODE),
57 htobe32(upper(address)), htobe32(lower(address))};
Murulidhar Nataraju207bed42017-03-31 07:38:55 -050058
Patrick Ventureda79c9c2018-11-01 15:35:52 -070059 // Buffer to hold the response data along with the SBE header
60 const size_t respLength = RESP_HEADER_LEN + READ_RESP_LENGTH;
Murulidhar Nataraju1adec022017-04-20 12:05:51 -050061 std::array<sbe_word_t, respLength> response = {};
Murulidhar Nataraju207bed42017-03-31 07:38:55 -050062
Patrick Ventureda79c9c2018-11-01 15:35:52 -070063 // Write the command buffer to the SBE FIFO and obtain the response from the
64 // SBE FIFO device.This interface will parse the obtained SBE response and
65 // any internal SBE failures will be communicated via exceptions
Murulidhar Nataraju1adec022017-04-20 12:05:51 -050066 invokeSBEChipOperation(devPath, command, response);
Murulidhar Nataraju207bed42017-03-31 07:38:55 -050067
Murulidhar Nataraju1adec022017-04-20 12:05:51 -050068 value = (((static_cast<uint64_t>(response[0])) << 32) | response[1]);
Murulidhar Nataraju207bed42017-03-31 07:38:55 -050069 return value;
70}
71
Patrick Ventureda79c9c2018-11-01 15:35:52 -070072void write(const char* devPath, uint64_t address, uint64_t data)
Murulidhar Nataraju207bed42017-03-31 07:38:55 -050073{
Patrick Ventureda79c9c2018-11-01 15:35:52 -070074 // Validate input device path
Murulidhar Nataraju207bed42017-03-31 07:38:55 -050075 if (devPath == nullptr)
76 {
77 throw std::runtime_error("NULL FIFO device path");
78 }
79
Patrick Ventureda79c9c2018-11-01 15:35:52 -070080 // Build SCOM write request command
81 // Handle byte order mismatch, SBE is big endian and BMC is
82 // little endian.
83 std::array<sbe_word_t, WRITE_CMD_LENGTH> command = {
Benjamin Herrenschmidt7a6479f2018-05-17 15:25:24 +100084 static_cast<sbe_word_t>(htobe32(WRITE_CMD_LENGTH)),
Murulidhar Nataraju06a0c2c2017-07-11 08:55:33 -050085 htobe32(WRITE_OPCODE),
86 htobe32(upper(address)),
87 htobe32(lower(address)),
88 htobe32(upper(data)),
Patrick Ventureda79c9c2018-11-01 15:35:52 -070089 htobe32(lower(data))};
Murulidhar Nataraju207bed42017-03-31 07:38:55 -050090
Patrick Ventureda79c9c2018-11-01 15:35:52 -070091 // Buffer to hold the SBE response status
Murulidhar Nataraju1adec022017-04-20 12:05:51 -050092 const size_t respLength = RESP_HEADER_LEN;
93 std::array<sbe_word_t, respLength> response = {};
Murulidhar Nataraju207bed42017-03-31 07:38:55 -050094
Patrick Ventureda79c9c2018-11-01 15:35:52 -070095 // Write the command buffer to the SBE FIFO and obtain the response from the
96 // SBE FIFO device.This interface will parse the obtained SBE response and
97 // any internal SBE failures will be communicated via exceptions
Murulidhar Nataraju1adec022017-04-20 12:05:51 -050098 invokeSBEChipOperation(devPath, command, response);
Murulidhar Nataraju207bed42017-03-31 07:38:55 -050099}
100
101} // namespace scom
102} // namespace sbe
103} // namespace openpower