This design provides an efficient method to transfer MCTP packets between the host and BMC over the LPC bus on ASPEED BMC platforms.
The basic components used for the transfer are:
In order to transfer a packet, either side of the channel (BMC or host) will:
On this indication, the remote side will:
The window of BMC-memory-backed LPC FW address space has a predefined format, consisting of:
The control descriptor contains a version, and offset and size data for the transmit and receive areas. These offsets are relative to the start of the LPC FW window.
Full definition of the control area is defined below, and it will be the base for all future versions.
struct mctp_lpcmap_hdr { uint32_t magic; uint16_t bmc_ver_min; uint16_t bmc_ver_cur; uint16_t host_ver_min; uint16_t host_ver_cur; uint16_t negotiated_ver; uint16_t pad0; uint32_t rx_offset; uint32_t rx_size; uint32_t tx_offset; uint32_t tx_size; } __attribute__((packed));
Where the magic value marking the beginning of the control area is the ASCII encoding of "MCTP":
#define LPC_MAGIC 0x4d435450
The transmit and receive areas contain a length field, followed by the actual MCTP packet to be transferred. At version 1, only a single MCTP packet is present in the Rx and Tx areas. This may change for future versions of the protocol.
All control data is in big-endian format. MCTP packet data is transferred exactly as is presented, and no data escaping is performed.
The KCS hardware on the ASPEED BMCs is used as a method of indicating, to the remote side, that a packet is ready to be transferred through the LPC FW mapping.
The KCS hardware consists of two single-byte buffers: the Output Data Register (ODR) and the Input Data Register (IDR). The ODR is written by the BMC and read by the host. The IDR is the obverse.
The KCS unit also contains a status register, allowing both host and BMC to determine if there is data in the ODR or IDR. These are single-bit flags, designated Input/Output Buffer Full (IBF/OBF), and are automatically set by hardware when data has been written to the corresponding ODR/IDR buffer (and cleared when data has been read).
We use these flags to determine whether data in the LPC window is available to be consumed.
Bit | Managed By | Description |
---|---|---|
7 | Software | (MSB) BMC Active |
6 | Software | Channel active, version negotiated |
5 | Software | Unused |
4 | Software | Unused |
3 | Hardware | Command / Data |
2 | Software | Unused |
1 | Hardware | Input Buffer Full |
0 | Hardware | (LSB) Output Buffer Full |
Command | Description |
---|---|
0x00 | Initialise |
0x01 | Tx Begin |
0x02 | Rx Complete |
0xff | Dummy Value |
0xff
dummy value allows either side of the KCS interface to trigger a data-register interrupt by performing a dummy writeBecause the LPC FW window is shared between the host and the BMC we need strict rules on which entity is allowed to access it at specific times.
Firstly, we have rules for modification:
During packet transmission, the follow sequence occurs:
Tx Begin
message, indicating that the buffer ownership is transferredRx Complete
once done, indicating that the buffer ownership is transferred back to the Tx side.The binding operation is not symmetric as the BMC is the only side that can drive the status register. Each side's initialisation sequence is outlined below.
Step | Description |
---|---|
1 | The BMC initialises the control area: magic value, BMC versions and buffer parameters |
2 | The BMC sets the BMC active bit and triggers the host interrupt |
Step | Description |
---|---|
1 | Wait for the BMC to indicate active via the KCS status register |
2 | Populate the host version fields |
3 | Send the Initialise message via KCS |
4 | The hardware sets the IBF flag in the status register |
5 | The KCS interrupt is triggered on the BMC |
6 | The BMC reads the KCS status and data registers |
7 | The hardware clears IBF and de-asserts the KCS IRQ |
8 | The BMC calculates the negotiated version |
9 | The BMC sets the Channel Active bit in the KCS status register |
10 | The KCS interrupt is triggered on the host |
11 | The host reads the KCS status and data registers |
12 | The hardware clears OBF and de-asserts the host KCS IRQ |
13 | The host observes that Channel Active is set in the KCS status register |
14 | The host reads the negotiated version |
Step | Description |
---|---|
1 | The host waits on the previous Rx Complete message |
2 | The host waits on BMC Active and Channel Active in the KCS status register |
3 | The host writes the packet to its Tx area (BMC Rx area) |
4 | The host sends the Tx Begin command via the KCS interface, transferring ownership of its Tx buffer to the BMC |
5 | The hardware sets the IBF flag in the KCS status register |
6 | The KCS interrupt is triggered on the BMC |
7 | The BMC reads the KCS status and data registers |
8 | The hardware clears IBF and de-asserts the KCS IRQ |
9 | The BMC observes IBF is set and the command is Tx Begin |
10 | The BMC reads the packet from the BMC Rx area (host Tx area) |
11 | The BMC sends the Rx Complete command via the KCS interface |
12 | The hardware sets the OBF flag in the KCS status register |
13 | The KCS interrupt is triggered on the host |
14 | The host reads the KCS status and data registers |
15 | The hardware clears OBF and de-asserts the host KCS IRQ |
16 | The host observes OBF is set and the command is Rx Complete |
17 | The host regains ownership of its Tx buffer |
Step | Description |
---|---|
1 | The BMC waits on the previous Rx Complete message |
2 | The BMC writes the packet to its Tx area (host Rx area) |
3 | The BMC sends the Tx Begin command via the KCS interface, transferring ownership of its Tx buffer to the host |
4 | The hardware sets the OBF flag in the KCS status register |
5 | The KCS interrupt is triggered on the host |
6 | The host reads the KCS status and data registers |
7 | The hardware clears OBF and de-asserts the KCS IRQ |
8 | The host observes OBF is set and the command is Tx Begin |
9 | The host reads the packet from the host Rx area (BMC Tx area) |
10 | The host sends the Rx Complete command via the KCS interface |
11 | The hardware sets the IBF flag in the KCS status register |
12 | The KCS interrupt is triggered on the BMC |
13 | The BMC reads the KCS status and data registers |
14 | The hardware clears IBF and de-asserts the BMC KCS IRQ |
15 | The BMC observes IBF is set and the command is Rx Complete . |
16 | The BMC regains ownership of its Tx buffer |
The KCS hardware (used as the full transfer channel) can be used to transfer arbitrarily-sized MCTP messages. However, there are much larger overheads in synchronisation between host and BMC for every byte transferred.
We could use the VUART hardware to transfer the MCTP packets according to the existing MCTP Serial Binding. However, the VUART device is already used for console data. Multiplexing both MCTP and console would be an alternative, but the complexity introduced would make low-level debugging both more difficult and less reliable.
The BT interface allows for block-at-time transfers. However, the BT buffer size is only 64 bytes on the AST2500 hardware, which does not allow us to comply with the MCTP Base Specification (DSP0236) that requires a 64-byte payload size as the minimum. The 64-byte BT buffer does not allow for MCTP and transport headers.
Additionally, we would like to develop the MCTP channel alongside the existing IPMI interfaces, to allow a gradual transition from IPMI to MCTP. As the BT channel is already used on OpenPOWER systems for IPMI transfers, we would not be able to support both in parallel.
This would require enabling the SuperIO interface, which allows the host to access the entire BMC address space, and so introduces security vulnerabilities.