From: "Nickle Wang" <nicklew@nvidia.com>
To: "abner.chang@amd.com" <abner.chang@amd.com>,
"devel@edk2.groups.io" <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>,
Igor Kulchytskyy <igork@ami.com>
Subject: Re: [PATCH v4 6/9] ManageabilityPkg/ManageabilityTransportKcsLib
Date: Fri, 24 Mar 2023 09:23:36 +0000 [thread overview]
Message-ID: <MW4PR12MB70310F887ABC684AAF25D8BCD9849@MW4PR12MB7031.namprd12.prod.outlook.com> (raw)
In-Reply-To: <20230322024840.1629-6-abner.chang@amd.com>
Reviewed-by: Nickle Wang <nicklew@nvidia.com>
Regards,
Nickle
> -----Original Message-----
> From: abner.chang@amd.com <abner.chang@amd.com>
> Sent: Wednesday, March 22, 2023 10:49 AM
> 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
>
> External email: Use caution opening links or attachments
>
>
> 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/DxeMan
> ageabilityTransportKcs.inf
> create mode 100644
> Features/ManageabilityPkg/Include/Library/ManageabilityTransportIpmiLib.h
> create mode 100644
> Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Common/M
> anageabilityTransportKcs.h
> create mode 100644
> Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Common/Kc
> sCommon.c
> create mode 100644
> Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/Manage
> abilityTransportKcs.c
> create mode 100644
> Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/Manage
> abilityTransportKcs.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/DxeManageability
> TransportKcs.inf
> +
> [LibraryClasses]
>
> ManageabilityTransportLib|ManageabilityPkg/Library/BaseManageabilityTransp
> ortNullLib/BaseManageabilityTransportNull.inf
>
> diff --git
> a/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/DxeM
> anageabilityTransportKcs.inf
> b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/DxeM
> anageabilityTransportKcs.inf
> new file mode 100644
> index 0000000000..f0a6afa074
> --- /dev/null
> +++
> b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/DxeM
> anageabilityTransportKcs.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/Mana
> geabilityTransportKcs.c
> b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/Mana
> geabilityTransportKcs.c
> new file mode 100644
> index 0000000000..8101e63c22
> --- /dev/null
> +++
> b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/Mana
> geabilityTransportKcs.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/Mana
> geabilityTransportKcs.uni
> b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/Mana
> geabilityTransportKcs.uni
> new file mode 100644
> index 0000000000..61a3e8b588
> --- /dev/null
> +++
> b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/Mana
> geabilityTransportKcs.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-24 9:23 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 ` [PATCH v4 6/9] ManageabilityPkg/ManageabilityTransportKcsLib Chang, Abner
2023-03-24 9:23 ` Nickle Wang [this message]
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=MW4PR12MB70310F887ABC684AAF25D8BCD9849@MW4PR12MB7031.namprd12.prod.outlook.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