Support IPMI Serial Transport
Support IPMI Serial interface (basic mode) based on Sec 14,
IPMI 2.0 spec. Serial transport tested with meta-evb-arm
platform with socat and ipmitool.
HW transport can be selected by meson configure flasg.
Tested:
1. socat -x pty,raw,echo=0,link=/tmp/ttyHOST2BMC tcp:localhost:5066
2. ipmitool -I serial-basic -D /tmp/ttyHOST2BMC:115200 mc info
Device ID : 0
Device Revision : 0
Firmware Revision : 2.17
IPMI Version : 2.0
Manufacturer ID : 0
Manufacturer Name : Unknown
Product ID : 0 (0x0000)
Product Name : Unknown (0x0)
Device Available : no
Provides Device SDRs : no
Additional Device Support :
Aux Firmware Rev Info :
0x00
0x00
0x00
0x00
Change-Id: I2a56390022fce7a974ed75ed6a72ad3fffed9bb6
Signed-off-by: John Chung <john.chung@arm.com>
diff --git a/transport/serialbridge/serialcmd.hpp b/transport/serialbridge/serialcmd.hpp
new file mode 100644
index 0000000..985921c
--- /dev/null
+++ b/transport/serialbridge/serialcmd.hpp
@@ -0,0 +1,64 @@
+#pragma once
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/message.hpp>
+#include <sdbusplus/slot.hpp>
+#include <stdplus/fd/intf.hpp>
+
+namespace serialbridge
+{
+
+static constexpr auto bmStart = 0xA0;
+static constexpr auto bmStop = 0xA5;
+static constexpr auto bmHandshake = 0xA6;
+static constexpr auto bmEscape = 0xAA;
+
+static constexpr auto ipmiSerialConnectionHeaderLength = 3;
+static constexpr auto ipmiSerialChecksumSize = 1;
+static constexpr auto ipmiSerialMaxBufferSize = 256;
+
+/**
+ * @brief IPMI Serial Message Structure
+ */
+struct IpmiSerialHeader
+{
+ uint8_t rsAddr;
+ uint8_t rsNetFnLUN;
+ uint8_t checksum1;
+ uint8_t rqAddr;
+ uint8_t rqSeqLUN;
+ uint8_t cmd;
+} __attribute__((packed));
+
+class SerialChannel
+{
+ public:
+ static constexpr uint8_t netFnShift = 2;
+ static constexpr uint8_t lunMask = (1 << netFnShift) - 1;
+
+ SerialChannel(bool debug) : verbose(debug), msgState(MsgState::msgIdle) {};
+
+ int write(stdplus::Fd& uart, uint8_t rsAddr, uint8_t rqAddr, uint8_t seq,
+ sdbusplus::message_t&& m);
+ void read(stdplus::Fd& serial, sdbusplus::bus_t& bus,
+ sdbusplus::slot_t& outstanding);
+ uint8_t calculateChecksum(std::span<uint8_t> data);
+ uint8_t getUnescapedCharacter(uint8_t c);
+ int consumeIpmiSerialPacket(std::span<uint8_t>& escapedDataBytes,
+ std::vector<uint8_t>& unescapedDataBytes);
+ uint8_t processEscapedCharacter(std::vector<uint8_t>& buffer,
+ const std::vector<uint8_t>& data);
+
+ private:
+ bool verbose;
+ enum class MsgState
+ {
+ msgIdle = 0,
+ msgInProgress,
+ msgInEscape,
+ };
+ MsgState msgState;
+ std::vector<uint8_t> requestBuffer;
+ std::vector<uint8_t> responseBuffer;
+};
+
+} // namespace serialbridge