From: "Chang, Abner" <abner.chang@amd.com>
To: <devel@edk2.groups.io>
Cc: Liming Gao <gaoliming@byosoft.com.cn>,
Isaac Oram <isaac.w.oram@intel.com>,
Nate DeSimone <nathaniel.l.desimone@intel.com>,
Abdul Lateef Attar <abdattar@amd.com>,
Nickle Wang <nicklew@nvidia.com>,
"Igor Kulchytskyy" <igork@ami.com>
Subject: [PATCH v4 6/9] ManageabilityPkg/ManageabilityTransportKcsLib
Date: Wed, 22 Mar 2023 10:48:37 +0800 [thread overview]
Message-ID: <20230322024840.1629-6-abner.chang@amd.com> (raw)
In-Reply-To: <20230322024840.1629-1-abner.chang@amd.com>
From: Abner Chang <abner.chang@amd.com>
This is the KCS manageability transport library
instance follows the design guidance described
in Readme file under ManageabilityPkg.
Signed-off-by: Abner Chang <abner.chang@amd.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Isaac Oram <isaac.w.oram@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Abdul Lateef Attar <abdattar@amd.com>
Cc: Nickle Wang <nicklew@nvidia.com>
Cc: Igor Kulchytskyy <igork@ami.com>
---
.../ManageabilityPkg/ManageabilityPkg.dsc | 3 +
.../Dxe/DxeManageabilityTransportKcs.inf | 44 ++
.../Library/ManageabilityTransportIpmiLib.h | 24 +
.../Common/ManageabilityTransportKcs.h | 105 ++++
.../Common/KcsCommon.c | 502 ++++++++++++++++++
.../Dxe/ManageabilityTransportKcs.c | 389 ++++++++++++++
.../Dxe/ManageabilityTransportKcs.uni | 13 +
7 files changed, 1080 insertions(+)
create mode 100644 Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/DxeManageabilityTransportKcs.inf
create mode 100644 Features/ManageabilityPkg/Include/Library/ManageabilityTransportIpmiLib.h
create mode 100644 Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Common/ManageabilityTransportKcs.h
create mode 100644 Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Common/KcsCommon.c
create mode 100644 Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/ManageabilityTransportKcs.c
create mode 100644 Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/ManageabilityTransportKcs.uni
diff --git a/Features/ManageabilityPkg/ManageabilityPkg.dsc b/Features/ManageabilityPkg/ManageabilityPkg.dsc
index f5b8c550e8..6a083385fd 100644
--- a/Features/ManageabilityPkg/ManageabilityPkg.dsc
+++ b/Features/ManageabilityPkg/ManageabilityPkg.dsc
@@ -35,6 +35,9 @@
!include MinPlatformPkg/Include/Dsc/CorePeiLib.dsc
!include MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc
+[Components]
+ ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/DxeManageabilityTransportKcs.inf
+
[LibraryClasses]
ManageabilityTransportLib|ManageabilityPkg/Library/BaseManageabilityTransportNullLib/BaseManageabilityTransportNull.inf
diff --git a/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/DxeManageabilityTransportKcs.inf b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/DxeManageabilityTransportKcs.inf
new file mode 100644
index 0000000000..f0a6afa074
--- /dev/null
+++ b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/DxeManageabilityTransportKcs.inf
@@ -0,0 +1,44 @@
+## @file
+# KCS instance of Manageability Transport Library
+#
+# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = DxeManageabilityTransportKcs
+ MODULE_UNI_FILE = ManageabilityTransportKcs.uni
+ FILE_GUID = FCCC8B34-145A-4927-9F08-553ADC579AF7
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ManageabilityTransportLib
+
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ ManageabilityTransportKcs.c
+ ../Common/KcsCommon.c
+ ../Common/ManageabilityTransportKcs.h
+
+[Packages]
+ ManageabilityPkg/ManageabilityPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ DebugLib
+ IoLib
+ TimerLib
+ MemoryAllocationLib
+
+[Guids]
+ gManageabilityTransportKcsGuid
+ gManageabilityProtocolMctpGuid
+ gManageabilityProtocolIpmiGuid
+
+[FixedPcd]
+ gEfiMdePkgTokenSpaceGuid.PcdIpmiKcsBaseAddress # Used as default KCS I/O base adddress
+
diff --git a/Features/ManageabilityPkg/Include/Library/ManageabilityTransportIpmiLib.h b/Features/ManageabilityPkg/Include/Library/ManageabilityTransportIpmiLib.h
new file mode 100644
index 0000000000..7ca6acf6ef
--- /dev/null
+++ b/Features/ManageabilityPkg/Include/Library/ManageabilityTransportIpmiLib.h
@@ -0,0 +1,24 @@
+/** @file
+
+ This file defines the manageability IPMI protocol specific transport data.
+
+ Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef MANAGEABILITY_TRANSPORT_IPMI_LIB_H_
+#define MANAGEABILITY_TRANSPORT_IPMI_LIB_H_
+
+#include <Library/ManageabilityTransportLib.h>
+
+///
+/// The IPMI command header which is apart from
+/// the payload.
+///
+typedef struct {
+ UINT8 NetFn;
+ UINT8 Lun;
+ UINT8 Command;
+} MANAGEABILITY_IPMI_TRANSPORT_HEADER;
+
+#endif
diff --git a/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Common/ManageabilityTransportKcs.h b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Common/ManageabilityTransportKcs.h
new file mode 100644
index 0000000000..f1758ffd8f
--- /dev/null
+++ b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Common/ManageabilityTransportKcs.h
@@ -0,0 +1,105 @@
+/** @file
+
+ Manageability transport KCS internal used definitions.
+
+ Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef MANAGEABILITY_TRANSPORT_KCS_LIB_H_
+#define MANAGEABILITY_TRANSPORT_KCS_LIB_H_
+
+#include <Library/ManageabilityTransportLib.h>
+
+#define MANAGEABILITY_TRANSPORT_KCS_SIGNATURE SIGNATURE_32 ('M', 'T', 'K', 'C')
+
+#define KCS_BASE_ADDRESS mKcsHardwareInfo.IoBaseAddress
+#define KCS_REG_DATA_IN mKcsHardwareInfo.IoDataInAddress
+#define KCS_REG_DATA_OUT mKcsHardwareInfo.IoDataOutAddress
+#define KCS_REG_COMMAND mKcsHardwareInfo.IoCommandAddress
+#define KCS_REG_STATUS mKcsHardwareInfo.IoStatusAddress
+
+///
+/// Manageability transport KCS internal data structure.
+///
+typedef struct {
+ UINTN Signature;
+ MANAGEABILITY_TRANSPORT_TOKEN Token;
+} MANAGEABILITY_TRANSPORT_KCS;
+
+#define MANAGEABILITY_TRANSPORT_KCS_FROM_LINK(a) CR (a, MANAGEABILITY_TRANSPORT_KCS, Token, MANAGEABILITY_TRANSPORT_KCS_SIGNATURE)
+
+#define IPMI_KCS_GET_STATE(s) (s >> 6)
+#define IPMI_KCS_SET_STATE(s) (s << 6)
+
+/// 5 sec, according to IPMI spec
+#define IPMI_KCS_TIMEOUT_5_SEC 5000*1000
+#define IPMI_KCS_TIMEOUT_1MS 1000
+
+/**
+ This service communicates with BMC using KCS protocol.
+
+ @param[in] NetFunction Net function of the command.
+ @param[in] Command IPMI Command.
+ @param[in] RequestData Command Request Data.
+ @param[in] RequestDataSize Size of Command Request Data.
+ @param[out] ResponseData Command Response Data. The completion
+ code is the first byte of response
+ data.
+ @param[in, out] ResponseDataSize Size of Command Response Data.
+
+ @retval EFI_SUCCESS The command byte stream was
+ successfully submit to the device and a
+ response was successfully received.
+ @retval EFI_NOT_FOUND The command was not successfully sent
+ to the device or a response was not
+ successfully received from the device.
+ @retval EFI_NOT_READY Ipmi Device is not ready for Ipmi
+ command access.
+ @retval EFI_DEVICE_ERROR Ipmi Device hardware error.
+ @retval EFI_TIMEOUT The command time out.
+ @retval EFI_UNSUPPORTED The command was not successfully sent to
+ the device.
+ @retval EFI_OUT_OF_RESOURCES The resource allocation is out of
+ resource or data size error.
+**/
+
+EFI_STATUS
+EFIAPI
+KcsTransportSendCommand (
+ IN UINT8 NetFunction,
+ IN UINT8 Command,
+ IN UINT8 *RequestData OPTIONAL,
+ IN UINT32 RequestDataSize,
+ OUT UINT8 *ResponseData OPTIONAL,
+ IN OUT UINT32 *ResponseDataSize OPTIONAL
+ );
+
+/**
+ This function reads 8-bit value from register address.
+
+ @param[in] Address This represents either 16-bit IO address
+ or 32-bit memory mapped address.
+
+ @retval UINT8 8-bit value.
+**/
+UINT8
+KcsRegisterRead8 (
+ MANAGEABILITY_TRANSPORT_HARDWARE_IO Address
+ );
+
+/**
+ This function writes 8-bit value to register address.
+
+ @param[in] Address This represents either 16-bit IO address
+ or 32-bit memory mapped address.
+ @param[in] Value 8-bit value write to register address
+
+**/
+VOID
+KcsRegisterWrite8 (
+ MANAGEABILITY_TRANSPORT_HARDWARE_IO Address,
+ UINT8 Value
+ );
+
+#endif
diff --git a/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Common/KcsCommon.c b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Common/KcsCommon.c
new file mode 100644
index 0000000000..b141c65381
--- /dev/null
+++ b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Common/KcsCommon.c
@@ -0,0 +1,502 @@
+/** @file
+
+ KCS instance of Manageability Transport Library
+
+ Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <Uefi.h>
+#include <IndustryStandard/IpmiKcs.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/TimerLib.h>
+
+#include "ManageabilityTransportKcs.h"
+
+extern MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO mKcsHardwareInfo;
+
+/**
+ This function waits for parameter Flag to set.
+ Checks status flag in every 1ms internal till 5 seconds elapses.
+
+ @param[in] Flag KCS Flag to test.
+ @retval EFI_SUCCESS The KCS flag under test is set.
+ @retval EFI_TIMEOUT The KCS flag didn't set in 5 second windows.
+**/
+EFI_STATUS
+WaitStatusSet (
+ IN UINT8 Flag
+ )
+{
+ UINT64 Timeout = 0;
+
+ while (!(KcsRegisterRead8 (KCS_REG_STATUS) & Flag)) {
+ MicroSecondDelay (IPMI_KCS_TIMEOUT_1MS);
+ Timeout = Timeout + IPMI_KCS_TIMEOUT_1MS;
+ if (Timeout >= IPMI_KCS_TIMEOUT_5_SEC) {
+ return EFI_TIMEOUT;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function waits for parameter Flag to get cleared.
+ Checks status flag in every 1ms internal till 5 seconds elapses.
+
+ @param[in] Flag KCS Flag to test.
+
+ @retval EFI_SUCCESS The KCS flag under test is clear.
+ @retval EFI_TIMEOUT The KCS flag didn't cleared in 5 second windows.
+**/
+EFI_STATUS
+WaitStatusClear (
+ IN UINT8 Flag
+ )
+{
+ UINT64 Timeout = 0;
+
+ while (KcsRegisterRead8 (KCS_REG_STATUS) & Flag) {
+ MicroSecondDelay (IPMI_KCS_TIMEOUT_1MS);
+ Timeout = Timeout + IPMI_KCS_TIMEOUT_1MS;
+ if (Timeout >= IPMI_KCS_TIMEOUT_5_SEC) {
+ return EFI_TIMEOUT;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function validates KCS OBF bit.
+ Checks whether OBF bit is set or not.
+
+ @retval EFI_SUCCESS OBF bit is set.
+ @retval EFI_NOT_READY OBF bit is not set.
+**/
+EFI_STATUS
+ClearOBF (
+ VOID
+ )
+{
+ if (KcsRegisterRead8 (KCS_REG_STATUS) & IPMI_KCS_OBF) {
+ KcsRegisterRead8 (KCS_REG_DATA_IN); // read the data to clear the OBF
+ if (KcsRegisterRead8 (KCS_REG_STATUS) & IPMI_KCS_OBF) {
+ return EFI_NOT_READY;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function writes/sends data to the KCS port.
+ Algorithm is based on flow chart provided in IPMI spec 2.0
+ Figure 9-6, KCS Interface BMC to SMS Write Transfer Flow Chart
+
+ @param[in] NetFunction Net function of the command.
+ @param[in] Command IPMI Command.
+ @param[in] RequestData Command Request Data, could be NULL.
+ RequestDataSize must be zero, if RequestData
+ is NULL.
+ @param[in] RequestDataSize Size of Command Request Data.
+
+ @retval EFI_SUCCESS The command byte stream was successfully
+ submit to the device and a response was
+ successfully received.
+ @retval EFI_NOT_FOUND The command was not successfully sent to the
+ device or a response was not successfully
+ received from the device.
+ @retval EFI_NOT_READY Ipmi Device is not ready for Ipmi command
+ access.
+ @retval EFI_DEVICE_ERROR Ipmi Device hardware error.
+ @retval EFI_TIMEOUT The command time out.
+ @retval EFI_UNSUPPORTED The command was not successfully sent to
+ the device.
+ @retval EFI_OUT_OF_RESOURCES The resource allocation is out of resource or
+ data size error.
+**/
+EFI_STATUS
+KcsTransportWrite (
+ IN UINT8 NetFunction,
+ IN UINT8 Command,
+ IN UINT8 *RequestData OPTIONAL,
+ IN UINT32 RequestDataSize
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Length;
+ UINT8 *Buffer;
+ UINT8 *BufferPtr;
+
+ // Validation on RequestData and RequestDataSize.
+ if ((RequestData == NULL && RequestDataSize != 0) ||
+ (RequestData != NULL && RequestDataSize == 0)
+ ) {
+ DEBUG ((DEBUG_ERROR, "%a: Mismatched values of RequestData or RequestDataSize.\n", __FUNCTION__));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Length = sizeof (NetFunction) + sizeof (Command);
+ if (RequestData != NULL) {
+ Length = Length + RequestDataSize;
+ }
+
+ Buffer = AllocateZeroPool (Length);
+ if (Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Buffer[0] = NetFunction
+ // Buffer[1] = Command
+ // Buffer [2..RequestDataSize] = RequestData
+ //
+ BufferPtr = Buffer;
+ CopyMem (BufferPtr, &NetFunction, sizeof (NetFunction));
+ BufferPtr += sizeof (NetFunction);
+ CopyMem (BufferPtr, &Command, sizeof (Command));
+ BufferPtr += sizeof (Command);
+ if (Length > (sizeof (NetFunction) + sizeof (Command))) {
+ CopyMem (BufferPtr, RequestData, RequestDataSize);
+ }
+
+ BufferPtr = Buffer;
+
+ // Step 1. wait for IBF to get clear
+ Status = WaitStatusClear (IPMI_KCS_IBF);
+ if (EFI_ERROR (Status)) {
+ FreePool (Buffer);
+ return Status;
+ }
+
+ // Step 2. clear OBF
+ if (EFI_ERROR (ClearOBF ())) {
+ FreePool (Buffer);
+ return EFI_NOT_READY;
+ }
+
+ // Step 3. WR_START to CMD, phase=wr_start
+ KcsRegisterWrite8 (KCS_REG_COMMAND, IPMI_KCS_CONTROL_CODE_WRITE_START);
+
+ // Step 4. wait for IBF to get clear
+ Status = WaitStatusClear (IPMI_KCS_IBF);
+ if (EFI_ERROR (Status)) {
+ FreePool (Buffer);
+ return Status;
+ }
+
+ // Step 5. check state it should be WRITE_STATE, else exit with error
+ if (IPMI_KCS_GET_STATE (KcsRegisterRead8 (KCS_REG_STATUS)) != IPMI_KCS_WRITE_STATE) {
+ FreePool (Buffer);
+ return EFI_NOT_READY;
+ }
+
+ // Step 6, Clear OBF
+ if (EFI_ERROR (ClearOBF ())) {
+ FreePool (Buffer);
+ return EFI_NOT_READY;
+ }
+
+ while (Length > 1) {
+ // Step 7, phase wr_data, write one byte of Data
+ KcsRegisterWrite8 (KCS_REG_DATA_OUT, *BufferPtr);
+ Length--;
+ BufferPtr++;
+
+ // Step 8. wait for IBF clear
+ Status = WaitStatusClear (IPMI_KCS_IBF);
+ if (EFI_ERROR (Status)) {
+ FreePool (Buffer);
+ return Status;
+ }
+
+ // Step 9. check state it should be WRITE_STATE, else exit with error
+ if (IPMI_KCS_GET_STATE (KcsRegisterRead8 (KCS_REG_STATUS)) != IPMI_KCS_WRITE_STATE) {
+ FreePool (Buffer);
+ return EFI_NOT_READY;
+ }
+
+ // Step 10
+ if (EFI_ERROR (ClearOBF ())) {
+ FreePool (Buffer);
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Step 11, check for DATA completion if more than one byte;
+ // if still need to be transferred then go to step 7 and repeat
+ //
+ }
+
+ // Step 12, WR_END to CMD
+ KcsRegisterWrite8 (KCS_REG_COMMAND, IPMI_KCS_CONTROL_CODE_WRITE_END);
+
+ // Step 13. wait for IBF to get clear
+ Status = WaitStatusClear (IPMI_KCS_IBF);
+ if (EFI_ERROR (Status)) {
+ FreePool (Buffer);
+ return Status;
+ }
+
+ // Step 14. check state it should be WRITE_STATE, else exit with error
+ if (IPMI_KCS_GET_STATE (KcsRegisterRead8 (KCS_REG_STATUS)) != IPMI_KCS_WRITE_STATE) {
+ FreePool (Buffer);
+ return EFI_NOT_READY;
+ }
+
+ // Step 15
+ if (EFI_ERROR (ClearOBF ())) {
+ FreePool (Buffer);
+ return EFI_NOT_READY;
+ }
+
+ // Step 16, write the last byte
+ KcsRegisterWrite8 (KCS_REG_DATA_OUT, *BufferPtr);
+ FreePool (Buffer);
+ return EFI_SUCCESS;
+}
+
+/**
+ This function sends/receives data from KCS port.
+ Algorithm is based on flow chart provided in IPMI spec 2.0
+ Figure 9-7, KCS Interface BMC to SMS Read Transfer Flow Chart
+
+ @param [in] DataBytes Buffer to hold the read Data.
+ @param [in, out] Length Number of Bytes read from KCS port.
+ @retval EFI_SUCCESS The command byte stream was
+ successfully submit to the device and
+ a response was successfully received.
+ @retval EFI_NOT_FOUND The command was not successfully sent
+ to the device or a response was not
+ successfully received from the
+ device.
+ @retval EFI_NOT_READY Ipmi Device is not ready for Ipmi
+ command access.
+ @retval EFI_DEVICE_ERROR Ipmi Device hardware error.
+ @retval EFI_TIMEOUT The command time out.
+ @retval EFI_UNSUPPORTED The command was not successfully set
+ to the device.
+ @retval EFI_OUT_OF_RESOURCES The resource allocation is out of
+ resource or data size error.
+**/
+EFI_STATUS
+KcsTransportRead (
+ OUT UINT8 *DataByte,
+ IN OUT UINT32 *Length
+ )
+{
+ EFI_STATUS Status;
+ UINT32 ReadLength;
+
+ if (DataByte == NULL || *Length == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: Either DataByte is NULL or Length is 0.\n", __FUNCTION__));
+ return EFI_INVALID_PARAMETER;
+ }
+ ReadLength = 0;
+ while (ReadLength < *Length) {
+ // Step 1. wait for IBF to get clear
+ Status = WaitStatusClear (IPMI_KCS_IBF);
+ if (EFI_ERROR (Status)) {
+ *Length = ReadLength;
+ return Status;
+ }
+
+ // Step 2. check state it should be READ_STATE, else exit with error
+ if (IPMI_KCS_GET_STATE (KcsRegisterRead8 (KCS_REG_STATUS)) == IPMI_KCS_READ_STATE) {
+ // Step 2.1.1 check of OBF to get clear
+ Status = WaitStatusSet (IPMI_KCS_OBF);
+ if (EFI_ERROR (Status)) {
+ *Length = ReadLength;
+ return Status;
+ }
+
+ // Step 2.1.2 read data from data out
+ DataByte[ReadLength++] = KcsRegisterRead8 (KCS_REG_DATA_IN);
+ Status = WaitStatusClear (IPMI_KCS_IBF);
+ if (EFI_ERROR (Status)) {
+ *Length = ReadLength;
+ return Status;
+ }
+
+ // Step 2.1.3 Write READ byte to data in register.
+ KcsRegisterWrite8 (KCS_REG_DATA_OUT, IPMI_KCS_CONTROL_CODE_READ);
+ } else if (IPMI_KCS_GET_STATE (KcsRegisterRead8 (KCS_REG_STATUS)) == IPMI_KCS_IDLE_STATE) {
+ // Step 2.2.1
+ Status = WaitStatusSet (IPMI_KCS_OBF);
+ if (EFI_ERROR (Status)) {
+ *Length = ReadLength;
+ return Status;
+ }
+
+ // Step 2.2.2 read dummy data
+ KcsRegisterRead8 (KCS_REG_DATA_IN); // Dummy read as per IPMI spec
+ *Length = ReadLength;
+ return EFI_SUCCESS;
+ } else {
+ *Length = ReadLength;
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ *Length = ReadLength;
+ return EFI_SUCCESS;
+}
+
+/**
+ This service communicates with BMC using KCS protocol.
+
+ @param[in] NetFunction Net function of the command.
+ @param[in] Command IPMI Command.
+ @param[in] RequestData Command Request Data.
+ @param[in] RequestDataSize Size of Command Request Data.
+ @param[out] ResponseData Command Response Data. The completion
+ code is the first byte of response
+ data.
+ @param[in, out] ResponseDataSize Size of Command Response Data.
+ When IN, it is the expected data size
+ of response data.
+ When OUT, it is the data size of response
+ exactly returned.
+ @retval EFI_SUCCESS The command byte stream was
+ successfully submit to the device and a
+ response was successfully received.
+ @retval EFI_NOT_FOUND The command was not successfully sent
+ to the device or a response was not
+ successfully received from the device.
+ @retval EFI_NOT_READY Ipmi Device is not ready for Ipmi
+ command access.
+ @retval EFI_DEVICE_ERROR Ipmi Device hardware error.
+ @retval EFI_TIMEOUT The command time out.
+ @retval EFI_UNSUPPORTED The command was not successfully sent to
+ the device.
+ @retval EFI_OUT_OF_RESOURCES The resource allocation is out of
+ resource or data size error.
+**/
+EFI_STATUS
+EFIAPI
+KcsTransportSendCommand (
+ IN UINT8 NetFunction,
+ IN UINT8 Command,
+ IN UINT8 *RequestData OPTIONAL,
+ IN UINT32 RequestDataSize,
+ OUT UINT8 *ResponseData OPTIONAL,
+ IN OUT UINT32 *ResponseDataSize OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ UINT32 RspHeaderSize;
+ IPMI_KCS_RESPONSE_HEADER RspHeader;
+
+ if ((RequestData != NULL) && (RequestDataSize == 0)) {
+ DEBUG((DEBUG_ERROR, "%a: Mismatched values of RequestData and RequestDataSize\n", __FUNCTION__));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((ResponseData != NULL) && ((ResponseDataSize != NULL) && (*ResponseDataSize == 0))) {
+ DEBUG((DEBUG_ERROR, "%a: Mismatched values of ResponseData and ResponseDataSize\n", __FUNCTION__));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = KcsTransportWrite (
+ (NetFunction << 2),
+ Command,
+ RequestData,
+ RequestDataSize
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "IPMI KCS Write Failed with Status(%r) for NetFunction(0x%x)," \
+ " Command(0x%x).\n",
+ Status,
+ NetFunction,
+ Command
+ ));
+ return Status;
+ }
+
+ //
+ // Read the response header
+ RspHeaderSize = sizeof (IPMI_KCS_RESPONSE_HEADER);
+ Status = KcsTransportRead ((UINT8 *)&RspHeader, &RspHeaderSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "IPMI KCS read response header failed Status(%r), " \
+ "RspNetFunctionLun = 0x%x, " \
+ "Comamnd = 0x%x \n",
+ Status,
+ RspHeader.NetFunc,
+ RspHeader.Command
+ ));
+ return (Status);
+ }
+
+ Status = KcsTransportRead ((UINT8 *)ResponseData, ResponseDataSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "IPMI KCS response read Failed with Status(%r) for NetFunction(0x%x)," \
+ " Command(0x%x).\n",
+ Status,
+ NetFunction,
+ Command
+ ));
+ }
+
+ return Status;
+}
+
+/**
+ This function reads 8-bit value from register address.
+
+ @param[in] Address This represents either 16-bit IO address
+ or 32-bit memory mapped address.
+
+ @retval UINT8 8-bit value.
+**/
+UINT8
+KcsRegisterRead8 (
+ MANAGEABILITY_TRANSPORT_HARDWARE_IO Address
+ )
+{
+ UINT8 Value;
+
+ if (mKcsHardwareInfo.MemoryMap == MANAGEABILITY_TRANSPORT_KCS_MEMORY_MAP_IO) {
+ // Read 8-bit value from 32-bit Memory mapped address.
+ Value = MmioRead8 ((UINTN)Address.IoAddress32);
+ } else {
+ // Read 8-bit value from 16-bit I/O address
+ Value = IoRead8 ((UINTN)Address.IoAddress16);
+ }
+
+ return Value;
+}
+
+/**
+ This function writes 8-bit value to register address.
+
+ @param[in] Address This represents either 16-bit IO address
+ or 32-bit memory mapped address.
+ @param[in] Value 8-bit value write to register address
+
+**/
+VOID
+KcsRegisterWrite8 (
+ MANAGEABILITY_TRANSPORT_HARDWARE_IO Address,
+ UINT8 Value
+ )
+{
+ if (mKcsHardwareInfo.MemoryMap == MANAGEABILITY_TRANSPORT_KCS_MEMORY_MAP_IO) {
+ // Write 8-bit value to 32-bit Memory mapped address.
+ MmioWrite8 ((UINTN)Address.IoAddress32, Value);
+ } else {
+ // Write 8-bit value to 16-bit I/O address
+ IoWrite8 ((UINTN)Address.IoAddress16, Value);
+ }
+}
diff --git a/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/ManageabilityTransportKcs.c b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/ManageabilityTransportKcs.c
new file mode 100644
index 0000000000..8101e63c22
--- /dev/null
+++ b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/ManageabilityTransportKcs.c
@@ -0,0 +1,389 @@
+/** @file
+
+ KCS instance of Manageability Transport Library
+
+ Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+*/
+
+#include <Uefi.h>
+#include <IndustryStandard/IpmiKcs.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/ManageabilityTransportLib.h>
+#include <Library/ManageabilityTransportIpmiLib.h>
+#include <Library/ManageabilityTransportHelperLib.h>
+
+#include "ManageabilityTransportKcs.h"
+
+MANAGEABILITY_TRANSPORT_KCS *mSingleSessionToken = NULL;
+
+EFI_GUID *SupportedManageabilityProtocol[] = {
+ &gManageabilityProtocolIpmiGuid,
+ &gManageabilityProtocolMctpGuid
+};
+
+UINT8 NumberOfSupportedProtocol = (sizeof (SupportedManageabilityProtocol)/sizeof (EFI_GUID *));
+
+MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO mKcsHardwareInfo;
+
+/**
+ This function initializes the transport interface.
+
+ @param [in] TransportToken The transport token acquired through
+ AcquireTransportSession function.
+ @param [in] HardwareInfo The hardware information
+ assigned to KCS transport interface.
+
+ @retval EFI_SUCCESS Transport interface is initialized
+ successfully.
+ @retval EFI_INVALID_PARAMETER The invalid transport token.
+ @retval EFI_NOT_READY The transport interface works fine but
+ @retval is not ready.
+ @retval EFI_DEVICE_ERROR The transport interface has problems.
+ @retval EFI_ALREADY_STARTED Teh protocol interface has already initialized.
+ @retval Otherwise Other errors.
+
+**/
+EFI_STATUS
+EFIAPI
+KcsTransportInit (
+ IN MANAGEABILITY_TRANSPORT_TOKEN *TransportToken,
+ IN MANAGEABILITY_TRANSPORT_HARDWARE_INFORMATION HardwareInfo OPTIONAL
+ )
+{
+ CHAR16 *ManageabilityProtocolName;
+
+ if (TransportToken == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Invalid transport token.\n", __FUNCTION__));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (HardwareInfo.Kcs == NULL) {
+ DEBUG ((DEBUG_INFO, "%a: Hardware information is not provided, use dfault settings.\n", __FUNCTION__));
+ mKcsHardwareInfo.MemoryMap = MANAGEABILITY_TRANSPORT_KCS_IO_MAP_IO;
+ mKcsHardwareInfo.IoBaseAddress.IoAddress16 = PcdGet16 (PcdIpmiKcsBaseAddress);
+ mKcsHardwareInfo.IoDataInAddress.IoAddress16 = mKcsHardwareInfo.IoBaseAddress.IoAddress16 + IPMI_KCS_DATA_IN_REGISTER_OFFSET;
+ mKcsHardwareInfo.IoDataOutAddress.IoAddress16 = mKcsHardwareInfo.IoBaseAddress.IoAddress16 + IPMI_KCS_DATA_OUT_REGISTER_OFFSET;
+ mKcsHardwareInfo.IoCommandAddress.IoAddress16 = mKcsHardwareInfo.IoBaseAddress.IoAddress16 + IPMI_KCS_COMMAND_REGISTER_OFFSET;
+ mKcsHardwareInfo.IoStatusAddress.IoAddress16 = mKcsHardwareInfo.IoBaseAddress.IoAddress16 + IPMI_KCS_STATUS_REGISTER_OFFSET;
+ } else {
+ mKcsHardwareInfo.MemoryMap = ((MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO *)HardwareInfo.Kcs)->MemoryMap;
+ mKcsHardwareInfo.IoBaseAddress = ((MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO *)HardwareInfo.Kcs)->IoBaseAddress;
+ mKcsHardwareInfo.IoDataInAddress = ((MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO *)HardwareInfo.Kcs)->IoDataInAddress;
+ mKcsHardwareInfo.IoDataOutAddress = ((MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO *)HardwareInfo.Kcs)->IoDataOutAddress;
+ mKcsHardwareInfo.IoCommandAddress = ((MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO *)HardwareInfo.Kcs)->IoCommandAddress;
+ mKcsHardwareInfo.IoStatusAddress = ((MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO *)HardwareInfo.Kcs)->IoStatusAddress;
+ }
+
+ // Get protocol specification name.
+ ManageabilityProtocolName = HelperManageabilitySpecName (TransportToken->ManageabilityProtocolSpecification);
+
+ DEBUG ((DEBUG_INFO, "%a: KCS transport hardware for %s is:\n", __FUNCTION__, ManageabilityProtocolName));
+ if (mKcsHardwareInfo.MemoryMap) {
+ DEBUG ((DEBUG_INFO, "Memory Map I/O\n", __FUNCTION__));
+ DEBUG ((DEBUG_INFO, "Base Memory Address : 0x%08x\n", mKcsHardwareInfo.IoBaseAddress.IoAddress32));
+ DEBUG ((DEBUG_INFO, "Data in Address : 0x%08x\n", mKcsHardwareInfo.IoDataInAddress.IoAddress32));
+ DEBUG ((DEBUG_INFO, "Data out Address : 0x%08x\n", mKcsHardwareInfo.IoDataOutAddress.IoAddress32));
+ DEBUG ((DEBUG_INFO, "Command Address : 0x%08x\n", mKcsHardwareInfo.IoCommandAddress.IoAddress32));
+ DEBUG ((DEBUG_INFO, "Status Address : 0x%08x\n", mKcsHardwareInfo.IoStatusAddress.IoAddress32));
+ } else {
+ DEBUG ((DEBUG_INFO, "I/O Map I/O\n"));
+ DEBUG ((DEBUG_INFO, "Base I/O port : 0x%04x\n", mKcsHardwareInfo.IoBaseAddress.IoAddress16));
+ DEBUG ((DEBUG_INFO, "Data in I/O port : 0x%04x\n", mKcsHardwareInfo.IoDataInAddress.IoAddress16));
+ DEBUG ((DEBUG_INFO, "Data out I/O port: 0x%04x\n", mKcsHardwareInfo.IoDataOutAddress.IoAddress16));
+ DEBUG ((DEBUG_INFO, "Command I/O port : 0x%04x\n", mKcsHardwareInfo.IoCommandAddress.IoAddress16));
+ DEBUG ((DEBUG_INFO, "Status I/O port : 0x%04x\n", mKcsHardwareInfo.IoStatusAddress.IoAddress16));
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function returns the transport interface status.
+ The generic EFI_STATUS is returned to caller directly, The additional
+ information of transport interface could be optionally returned in
+ TransportAdditionalStatus to describes the status that can't be
+ described obviously through EFI_STATUS.
+ See the definition of MANAGEABILITY_TRANSPORT_STATUS.
+
+ @param [in] TransportToken The transport token acquired through
+ AcquireTransportSession function.
+ @param [out] TransportAdditionalStatus The additional status of transport
+ interface.
+ NULL means no additional status of this
+ transport interface.
+
+ @retval EFI_SUCCESS Transport interface status is returned.
+ @retval EFI_INVALID_PARAMETER The invalid transport token.
+ @retval EFI_DEVICE_ERROR The transport interface has problems to return
+ @retval EFI_UNSUPPORTED The transport interface doesn't have status report.
+ Otherwise Other errors.
+
+**/
+EFI_STATUS
+EFIAPI
+KcsTransportStatus (
+ IN MANAGEABILITY_TRANSPORT_TOKEN *TransportToken,
+ OUT MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS *TransportAdditionalStatus OPTIONAL
+ )
+{
+ UINT8 TransportStatus;
+
+ if (TransportToken == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Invalid transport token.\n", __FUNCTION__));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (TransportAdditionalStatus == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ TransportStatus = IPMI_KCS_GET_STATE (KcsRegisterRead8 (KCS_REG_STATUS));
+ *TransportAdditionalStatus = MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS_NO_ERRORS;
+ if (TransportStatus != IPMI_KCS_IDLE_STATE) {
+ if (TransportStatus == IPMI_KCS_READ_STATE) {
+ //
+ // Transport is in read state.
+ *TransportAdditionalStatus |= MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS_BUSY_IN_READ;
+ return EFI_NOT_READY;
+ } else if (TransportStatus == IPMI_KCS_WRITE_STATE) {
+ //
+ // Transport is in read state.
+ *TransportAdditionalStatus |= MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS_BUSY_IN_WRITE;
+ return EFI_NOT_READY;
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function resets the transport interface.
+ The generic EFI_STATUS is returned to caller directly after reseting transport
+ interface. The additional information of transport interface could be optionally
+ returned in TransportAdditionalStatus to describes the status that can't be
+ described obviously through EFI_STATUS.
+ See the definition of MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS.
+
+ @param [in] TransportToken The transport token acquired through
+ AcquireTransportSession function.
+ @param [out] TransportAdditionalStatus The additional status of specific transport
+ interface after the reset.
+ NULL means no additional status of this
+ transport interface.
+
+ @retval EFI_SUCCESS Transport interface status is returned.
+ @retval EFI_INVALID_PARAMETER The invalid transport token.
+ @retval EFI_TIMEOUT The reset process is time out.
+ @retval EFI_DEVICE_ERROR The transport interface has problems to return
+ status.
+ Otherwise Other errors.
+
+**/
+EFI_STATUS
+EFIAPI
+KcsTransportReset (
+ IN MANAGEABILITY_TRANSPORT_TOKEN *TransportToken,
+ OUT MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS *TransportAdditionalStatus OPTIONAL
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ This function transmit the request over target transport interface.
+ The generic EFI_STATUS is returned to caller directly after reseting transport
+ interface. The additional information of transport interface could be optionally
+ returned in TransportAdditionalStatus to describes the status that can't be
+ described obviously through EFI_STATUS.
+ See the definition of MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS.
+
+ @param [in] TransportToken The transport token acquired through
+ AcquireTransportSession function.
+ @param [in] TransferToken The transfer token, see the definition of
+ MANAGEABILITY_TRANSFER_TOKEN.
+
+ @retval The EFI status is returned in MANAGEABILITY_TRANSFER_TOKEN.
+
+**/
+VOID
+EFIAPI
+KcsTransportTransmitReceive (
+ IN MANAGEABILITY_TRANSPORT_TOKEN *TransportToken,
+ IN MANAGEABILITY_TRANSFER_TOKEN *TransferToken
+ )
+{
+ EFI_STATUS Status;
+ MANAGEABILITY_IPMI_TRANSPORT_HEADER *TransmitHeader;
+
+ if (TransportToken == NULL || TransferToken == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Invalid transport token or transfer token.\n", __FUNCTION__));
+ return;
+ }
+
+ TransmitHeader = (MANAGEABILITY_IPMI_TRANSPORT_HEADER *)TransferToken->TransmitHeader;
+ if (TransmitHeader == NULL) {
+ TransferToken->TransferStatus = EFI_INVALID_PARAMETER;
+ return;
+ }
+
+ Status = KcsTransportSendCommand (
+ TransmitHeader->NetFn,
+ TransmitHeader->Command,
+ TransferToken->TransmitPackage.TransmitPayload,
+ TransferToken->TransmitPackage.TransmitSizeInByte,
+ TransferToken->ReceivePackage.ReceiveBuffer,
+ &TransferToken->ReceivePackage.ReceiveSizeInByte
+ );
+
+ TransferToken->TransferStatus = Status;
+ KcsTransportStatus (TransportToken, &TransferToken->TransportAdditionalStatus);
+}
+
+/**
+ This function acquires to create a transport session to transmit manageability
+ packet. A transport token is returned to caller for the follow up operations.
+
+ @param [in] ManageabilityProtocolSpec The protocol spec the transport interface is acquired.
+ @param [out] TransportToken The pointer to receive the transport token created by
+ the target transport interface library.
+ @retval EFI_SUCCESS Token is created successfully.
+ @retval EFI_OUT_OF_RESOURCES Out of resource to create a new transport session.
+ @retval EFI_UNSUPPORTED Protocol is not supported on this transport interface.
+ @retval Otherwise Other errors.
+
+**/
+EFI_STATUS
+AcquireTransportSession (
+ IN EFI_GUID *ManageabilityProtocolSpec,
+ OUT MANAGEABILITY_TRANSPORT_TOKEN **TransportToken
+ )
+{
+ EFI_STATUS Status;
+ MANAGEABILITY_TRANSPORT_KCS *KcsTransportToken;
+
+ if (ManageabilityProtocolSpec == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: No Manageability protocol specification specified.\n", __FUNCTION__));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (TransportToken == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: TransportToken is NULL.\n", __FUNCTION__));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = HelperManageabilityCheckSupportedSpec (
+ &gManageabilityTransportKcsGuid,
+ SupportedManageabilityProtocol,
+ NumberOfSupportedProtocol,
+ ManageabilityProtocolSpec
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Protocol is not supported on this transport interface.\n", __FUNCTION__));
+ return EFI_UNSUPPORTED;
+ }
+
+ if (mSingleSessionToken != NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: This manageability transport library only supports one session transport token.\n", __FUNCTION__));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ KcsTransportToken = AllocateZeroPool (sizeof (MANAGEABILITY_TRANSPORT_KCS));
+ if (KcsTransportToken == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Fail to allocate memory for MANAGEABILITY_TRANSPORT_KCS\n", __FUNCTION__));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ KcsTransportToken->Token.Transport = AllocateZeroPool (sizeof (MANAGEABILITY_TRANSPORT));
+ if (KcsTransportToken->Token.Transport == NULL) {
+ FreePool (KcsTransportToken);
+ DEBUG ((DEBUG_ERROR, "%a: Fail to allocate memory for MANAGEABILITY_TRANSPORT\n", __FUNCTION__));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ KcsTransportToken->Signature = MANAGEABILITY_TRANSPORT_KCS_SIGNATURE;
+ KcsTransportToken->Token.ManageabilityProtocolSpecification = ManageabilityProtocolSpec;
+ KcsTransportToken->Token.Transport->TransportVersion = MANAGEABILITY_TRANSPORT_TOKEN_VERSION;
+ KcsTransportToken->Token.Transport->ManageabilityTransportSpecification = &gManageabilityTransportKcsGuid;
+ KcsTransportToken->Token.Transport->TransportName = L"KCS";
+ KcsTransportToken->Token.Transport->Function.Version1_0 = AllocateZeroPool (sizeof (MANAGEABILITY_TRANSPORT_FUNCTION_V1_0));
+ if (KcsTransportToken->Token.Transport->Function.Version1_0 == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Fail to allocate memory for MANAGEABILITY_TRANSPORT_FUNCTION_V1_0\n", __FUNCTION__));
+ FreePool (KcsTransportToken);
+ FreePool (KcsTransportToken->Token.Transport);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ KcsTransportToken->Token.Transport->Function.Version1_0->TransportInit = KcsTransportInit;
+ KcsTransportToken->Token.Transport->Function.Version1_0->TransportReset = KcsTransportReset;
+ KcsTransportToken->Token.Transport->Function.Version1_0->TransportStatus = KcsTransportStatus;
+ KcsTransportToken->Token.Transport->Function.Version1_0->TransportTransmitReceive = KcsTransportTransmitReceive;
+
+ mSingleSessionToken = KcsTransportToken;
+ *TransportToken = &KcsTransportToken->Token;
+ return EFI_SUCCESS;
+}
+
+/**
+ This function returns the transport capabilities.
+
+ @param [out] TransportFeature Pointer to receive transport capabilities.
+ See the definitions of
+ MANAGEABILITY_TRANSPORT_CAPABILITY.
+
+**/
+VOID
+GetTransportCapability (
+ OUT MANAGEABILITY_TRANSPORT_CAPABILITY *TransportCapability
+ )
+{
+ if (TransportCapability != NULL) {
+ *TransportCapability = 0;
+ }
+}
+
+/**
+ This function releases the manageability session.
+
+ @param [in] TransportToken The transport token acquired through
+ AcquireTransportSession.
+ @retval EFI_SUCCESS Token is released successfully.
+ @retval EFI_INVALID_PARAMETER Invalid TransportToken.
+ @retval Otherwise Other errors.
+
+**/
+EFI_STATUS
+ReleaseTransportSession (
+ IN MANAGEABILITY_TRANSPORT_TOKEN *TransportToken
+ )
+{
+ EFI_STATUS Status;
+ MANAGEABILITY_TRANSPORT_KCS *KcsTransportToken;
+
+ if (TransportToken == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ KcsTransportToken = MANAGEABILITY_TRANSPORT_KCS_FROM_LINK (TransportToken);
+ if (mSingleSessionToken != KcsTransportToken) {
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ if (KcsTransportToken != NULL) {
+ FreePool (KcsTransportToken->Token.Transport->Function.Version1_0);
+ FreePool (KcsTransportToken->Token.Transport);
+ FreePool (KcsTransportToken);
+ mSingleSessionToken = NULL;
+ Status = EFI_SUCCESS;
+ }
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Fail to release KCS transport token (%r).\n", __FUNCTION__, Status));
+ }
+
+ return Status;
+}
diff --git a/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/ManageabilityTransportKcs.uni b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/ManageabilityTransportKcs.uni
new file mode 100644
index 0000000000..61a3e8b588
--- /dev/null
+++ b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/ManageabilityTransportKcs.uni
@@ -0,0 +1,13 @@
+// /** @file
+// KCS instance of Manageability Transport Library
+//
+// Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "KCS instance of Manageability Transport Library"
+
+#string STR_MODULE_DESCRIPTION #language en-US "KCS Manageability Transport library implementation."
+
--
2.37.1.windows.1
next prev parent reply other threads:[~2023-03-22 2:49 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-22 2:48 [PATCH v4 1/9] ManageabilityPkg: Add Readme file Chang, Abner
2023-03-22 2:48 ` [PATCH v4 2/9] ManageabilityPkg: Initial package Chang, Abner
2023-03-23 18:02 ` [edk2-devel] " Isaac Oram
2023-03-28 12:37 ` Tinh Nguyen
2023-03-29 1:32 ` Chang, Abner
2023-03-30 8:52 ` Tinh Nguyen
2023-03-22 2:48 ` [PATCH v4 3/9] ManageabilityPkg: Add ManageabilityTransportLib header file Chang, Abner
2023-03-24 9:18 ` Nickle Wang
2023-03-24 11:18 ` Attar, AbdulLateef (Abdul Lateef)
2023-03-22 2:48 ` [PATCH v4 4/9] ManageabilityPkg: Add NULL ManageabilityTransportLib Chang, Abner
2023-03-24 9:19 ` Nickle Wang
2023-03-22 2:48 ` [PATCH v4 5/9] ManageabilityPkg: Add ManageabilityTransportHelperLib Chang, Abner
2023-03-23 18:30 ` [edk2-devel] " Tinh Nguyen
2023-04-15 6:12 ` Chang, Abner
2023-03-24 9:20 ` Nickle Wang
2023-03-22 2:48 ` Chang, Abner [this message]
2023-03-24 9:23 ` [PATCH v4 6/9] ManageabilityPkg/ManageabilityTransportKcsLib Nickle Wang
2023-03-22 2:48 ` [PATCH v4 7/9] ManageabilityPkg: Implement Ipmi Protocol/Ppi Chang, Abner
2023-03-23 19:40 ` [edk2-devel] " Tinh Nguyen
2023-04-15 8:38 ` Chang, Abner
2023-04-15 12:07 ` Chang, Abner
2023-03-24 9:25 ` Nickle Wang
2023-03-22 2:48 ` [PATCH v4 8/9] ManageabilityPkg: Add IpmiProtocol to Manageability Package Chang, Abner
2023-03-28 12:22 ` [edk2-devel] " Tinh Nguyen
2023-04-15 3:38 ` Chang, Abner
2023-03-22 2:48 ` [PATCH v4 9/9] edk2-platforms: Maintainers.txt Chang, Abner
2023-03-23 14:45 ` Leif Lindholm
2023-03-23 17:37 ` Isaac Oram
2023-03-24 3:06 ` Attar, AbdulLateef (Abdul Lateef)
2023-03-23 17:55 ` [edk2-devel] [PATCH v4 1/9] ManageabilityPkg: Add Readme file Isaac Oram
2023-03-24 9:17 ` Attar, AbdulLateef (Abdul Lateef)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230322024840.1629-6-abner.chang@amd.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox