From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM12-MW2-obe.outbound.protection.outlook.com (NAM12-MW2-obe.outbound.protection.outlook.com [40.107.244.68]) by mx.groups.io with SMTP id smtpd.web11.2918.1679362503787307684 for ; Mon, 20 Mar 2023 18:35:04 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@amd.com header.s=selector1 header.b=tvBI2KNr; spf=permerror, err=parse error for token &{10 18 %{i}._ip.%{h}._ehlo.%{d}._spf.vali.email}: invalid domain name (domain: amd.com, ip: 40.107.244.68, mailfrom: abner.chang@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=myJqB4IntJlMjg5Ak48Gmh8cSj9CMEUj7nAV5D1rdVVP8hsszWLs38fDlj9mpFATTyXK0ctJR73q2gmkzRA30tNVxWJQuj1/1YnBvqqc7qHup/9iz3VVb0/PWR1027k6S7nrL/fQ6ibdaPauu1LZcHRF2e5qIIue4B5+GoQgqWDoUiuSHxPgR0DyabkfH3r8LFQbMWYzL614F0mUmXTirrUhUx1zUNqJVhrk1MyPEqanu2L4DYmgOi28siLSotFpjL+Ad511u/VBdheJQ9qwrgmN/0dUTP1+k7WNj8emXqRz1Ey5M1gRT6FiuuJckjopUPJ6E9DmCxQ4AJjaTxaJrw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=LQ2idvrZM3QSbdWvQxybWJaNXAvEVY9AzRK0uhVmXsI=; b=OwizGRkeUHagi+J9V7Nd4fQi07pqw/rip1UOQEU3rytKhXLJePFuacFsQFhoL8pRYtggYdd2zV4rDHvP2yGbswSVEkRBhAY7XIXg+gsJT449sh4keI35SAQjvmoW816XpFJRgV+FiD1idGBR4nA4iaMGO1lJBEjAsebRvsY73lIDoH+HPtaQj1p9Iy0iAx1/LNs+XWPanHFXQ3CG2p1E38BByW8TvNvC5a5I+D969lYmtnftXA0K3CfPwcmOtU+eey/vQMvYYm9b9XZa4zJMEGelJrlmI0me/3FGBdyoe4+1MsPc2S1MhRjCaTTiwScAJlwAV87xU+bV9mAJo81L8w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=LQ2idvrZM3QSbdWvQxybWJaNXAvEVY9AzRK0uhVmXsI=; b=tvBI2KNr0MBw8CfPnep6kLLPvh4bZHX9fXTIIV1OiBnhVskvlY87mM2Od83WveNNC59b4sJ79WQPV6eD2+eKtlE7RlKkLPNeIoPCsS5Ko9FDsnwvcAwXO9FgQzJfQOgV/8Ag5h0D4Tyr+fvhkYrEmlwjbvJZ8UMMAfgQ9o6sMtI= Received: from MN2PR12MB3966.namprd12.prod.outlook.com (2603:10b6:208:165::18) by PH7PR12MB7379.namprd12.prod.outlook.com (2603:10b6:510:20e::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6178.37; Tue, 21 Mar 2023 01:34:59 +0000 Received: from MN2PR12MB3966.namprd12.prod.outlook.com ([fe80::8136:1f56:53e5:6fe]) by MN2PR12MB3966.namprd12.prod.outlook.com ([fe80::8136:1f56:53e5:6fe%3]) with mapi id 15.20.6178.037; Tue, 21 Mar 2023 01:34:58 +0000 From: "Chang, Abner" To: Nickle Wang , "devel@edk2.groups.io" CC: Liming Gao , Isaac Oram , Nate DeSimone , "Attar, AbdulLateef (Abdul Lateef)" , Igor Kulchytskyy Subject: Re: [edk2-platforms][PATCH V2 5/8] ManageabilityPkg/ManageabilityTransportKcsLib Thread-Topic: [edk2-platforms][PATCH V2 5/8] ManageabilityPkg/ManageabilityTransportKcsLib Thread-Index: AQHZUci2A1ldg5SekEChp1U6hYv7xa8DunHQgADI69A= Date: Tue, 21 Mar 2023 01:34:58 +0000 Message-ID: References: <20230308141647.1318-1-abner.chang@amd.com> <20230308141647.1318-6-abner.chang@amd.com> In-Reply-To: Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: msip_labels: MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_Enabled=true; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_SetDate=2023-03-21T01:34:55Z; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_Method=Standard; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_Name=General; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_SiteId=3dd8961f-e488-4e60-8e11-a82d994e183d; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_ActionId=731347c9-2a49-4c06-aaaa-6ccf2b09e28b; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_ContentBits=1 authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=amd.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: MN2PR12MB3966:EE_|PH7PR12MB7379:EE_ x-ms-office365-filtering-correlation-id: d8bd654c-a469-42fa-213e-08db29ac7b47 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: KKIx5KjncdIP96jDi7M0pPV0BMljHuwvhRsdcW2vOBuPdIwdLJNgttGaRw2RxKlDmAGD7vCGugXuR1h3DAudLYCh2gSomjTCx+p6d4g8sbS46CbWPNwPxV27df9qsFcobdYQRlcg2FFrb3/4g6XBG+ofcA7JD/x1WVmOXAItFs+seKtcnRmGDXX6SKpsmEZ8A2ictpIgesOHgScdUo31IMLDuFI39BrwMQ5BIc9SfPLjg/Ge4IBrqxZQ1lcbXATOzV7Z+praacJKO4d/ez7DBhc/ENW3MavUzD2yZ7bIvMEBybCFQgjTZdEo/b6o0V5AOCYkS7DowuRCUu0Y/xMm7ZQw4nAxlJpLwx2Xq3JaNQ+aiZR2szWgAVdhY6nJhG1c1GLi/PXMiJETyZQwj8Sz8MNQY6XeWg/8j3q+AFREYH7jN5UI1fkgmcP668GBJn3ujq57c3IxCKWo4lyDfye7dXu7P7iEuhcSyi5QTehnwtr8bUqx2pMpH5QDK1CBVmXpaDxUn28mKaPqe6MU9B6epxHdHtUJgdT1bFDt4fO+aVgKzcpDUtz+zyh/JHd6NjVeXtzfYsHLiznrNkn3q3W41QukQELVHPQoQZuYUvKaWEiYSt5k44ELlmnke5fXhL4qsrFUH56Y+OEzxE0HIncxhJBfN3dkMvkz/82ze4ATP4F4Rf6/JAQ5QKIJ1rNlKw+HTDn6x6g0uq8kX9CcHu47vcBvCBg6TMumVxJ4NaqAiGk= x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MN2PR12MB3966.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230025)(4636009)(396003)(376002)(136003)(346002)(39860400002)(366004)(451199018)(38070700005)(4326008)(41300700001)(19627235002)(76116006)(66946007)(66556008)(66446008)(64756008)(66476007)(8676002)(38100700002)(2906002)(55016003)(122000001)(52536014)(30864003)(8936002)(86362001)(6506007)(5660300002)(26005)(53546011)(71200400001)(7696005)(33656002)(9686003)(186003)(54906003)(110136005)(83380400001)(478600001)(316002)(559001)(579004)(44824005);DIR:OUT;SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?oHy//TqNIU1pO0tdE+Len1cQYBg91d26v9XjLbC6OILV0/FUlJuCA7PuGtIp?= =?us-ascii?Q?FRFRAN5oMxcyg86fAN3/OFS5JZD7lIcIItuSVBhFkv4Xdn/GtcvoMIfcaiJx?= =?us-ascii?Q?cj3PwfvIXxUrfYL3HM6P+wdwEoS3jG5X3dP3hrTIUpWPQkg3TTOauLG3Bgvk?= =?us-ascii?Q?FylPX9SHHACMQiQurNfoRJRRf58BgmSnR5o0fnPZG2vufERIVZrGDf932TlT?= =?us-ascii?Q?PzRjrFRhDvIgBxHq8dwIfkVZditz4yUIMlHTtyd9+yMhcTwzpTRht6whEKa7?= =?us-ascii?Q?3TLZJKh2ZbEukt2X+34RjWS6oEHVhqj3p7s46UQfmWY+pYMGapm9OUtsfZZi?= =?us-ascii?Q?utSVzlJtEO5qiX06Jap9sNbCZQ/RAZNnggZ9neD/DKk8MGbB4eRorshPL9dh?= =?us-ascii?Q?vKObQaZGQ2weFOBz/aJZ3wCHoU0+rGiWn/GdxbHNacBT9/BP9e1bElKdZiZu?= =?us-ascii?Q?Ik/oEWPC0Nmke5wpT/V7Cg3ayldfd1En96COL+9P36ODXIaZw1OwgZkoB6YF?= =?us-ascii?Q?KnPu/kwkx82G9kzIuoOHsz2k9IPBqPW2pUDBUeOj9m+3aqqTi78YcLYzMpDW?= =?us-ascii?Q?g3vvoERmgPi4vFlnEn4L74+4KAkZJ/SVmqvCctLJtA6IWr71Ve3g5IwcDhCc?= =?us-ascii?Q?YGSo7jXrUbj7PqDLm+01j0OV41E20y3fh8qMfd+DNL/Y+BYmzrbRInywZnJc?= =?us-ascii?Q?XlKUyVC1ItdKhHSaIEyP+e2qUGDEzFkOv14wt9vekkx6jQEmV6o/JSe53GPM?= =?us-ascii?Q?BLW7KE8Na0uI5RUmEMtpDZkYPNeNlimbryMKFK5qiibrxZ/SDfshcromZXWs?= =?us-ascii?Q?qmwMEIuThoO8iAVfTehgIx6x8bkFiguuewimHgLrQvAHFsjGVJIJTTty3wpW?= =?us-ascii?Q?WionNqdbGgPjXsiQ7hZRBIUBWU0J81mV7VOEPcOV8aOswVrc3bhxb+Wg4uwd?= =?us-ascii?Q?N+nLiCHNMCfB674qkYbi5yw3R9wld4r0W6vKDkPif+yhRGeisWl+8iBeiScG?= =?us-ascii?Q?2UH0C7xuvXJ2turRM/L3x2lPJlVPjFLt5RQ+Pw7kUbamYEGIAbbLDpKqsxjG?= =?us-ascii?Q?L46bjfV3MTcNOck+pudtoyarkpAmea+5Xp1uRLBeC2sIQIfnWqdHaV1JDTij?= =?us-ascii?Q?MKMzyOp6JTGNUGm4PhgWTHAW/fSFmdp43RIkIg43HsmgUuz6mRX/G4NEsx5z?= =?us-ascii?Q?qOeSPE2kA3VOLGk3cz20nwcH8zAjWCd9smgm2cq+Mnyg2sHMecpLx6VrzjmT?= =?us-ascii?Q?DnxVkfKcjuCIxdKLzWrJqdsLWHHh/Se7mwyTSvgsckrcQDp43cwZyUMWfnSz?= =?us-ascii?Q?5hW6MDox7uQsMZa/j8F6IS++glKm+AVeq5z2E5jfSoFKJxNGtoHv9yf/zr87?= =?us-ascii?Q?6IM2w7jnET5LXwAwOsyDBHlANFnEl8DkLG9rxdqibD2JP1nNSr2GKuG5f0eu?= =?us-ascii?Q?bfX9LeluMEfsvdlkqElwqdMNhMPWXo5MGoYtIywJIopFLZUgfmMRn80TjHDq?= =?us-ascii?Q?pkhO280Ity68A0UoBTAEHtTARwTDqM0QOQt8s4F/fzBiTC+t7zipVZE5saiw?= =?us-ascii?Q?uDCWfRgGzXn4cs6YuJY=3D?= MIME-Version: 1.0 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: MN2PR12MB3966.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: d8bd654c-a469-42fa-213e-08db29ac7b47 X-MS-Exchange-CrossTenant-originalarrivaltime: 21 Mar 2023 01:34:58.1961 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: fnknt7q46Jbg7qGeFPMGttOw4a366Mnc+DvMUCL+m9WGV0iH4lUWNTURXjuJyKI47wQNP8i155HG43tH0RjdKQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR12MB7379 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable [AMD Official Use Only - General] Hi Nickle, Thanks for catching those issue. I am fixing it now. There is few feedbacks below, > -----Original Message----- > From: Nickle Wang > Sent: Monday, March 20, 2023 9:32 PM > To: Chang, Abner ; devel@edk2.groups.io > Cc: Liming Gao ; Isaac Oram > ; Nate DeSimone > ; Attar, AbdulLateef (Abdul Lateef) > ; Igor Kulchytskyy > Subject: RE: [edk2-platforms][PATCH V2 5/8] > ManageabilityPkg/ManageabilityTransportKcsLib >=20 > Caution: This message originated from an External Source. Use proper > caution when opening attachments, clicking links, or responding. >=20 >=20 > Please see my comments inline below. >=20 > Regards, > Nickle >=20 > -----Original Message----- > From: abner.chang@amd.com > Sent: Wednesday, March 8, 2023 10:17 PM > To: devel@edk2.groups.io > Cc: Liming Gao ; Isaac Oram > ; Nate DeSimone > ; Abdul Lateef Attar > ; Nickle Wang ; Igor Kulchytskyy > > Subject: [edk2-platforms][PATCH V2 5/8] > ManageabilityPkg/ManageabilityTransportKcsLib >=20 > External email: Use caution opening links or attachments >=20 >=20 > From: Abner Chang >=20 > This is the KCS manageability transport library instance follows the desi= gn > guidance described in Readme file under ManageabilityPkg. >=20 > Signed-off-by: Abner Chang > Cc: Liming Gao > Cc: Isaac Oram > Cc: Nate DeSimone > Cc: Abdul Lateef Attar > Cc: Nickle Wang > Cc: Igor Kulchytskyy > --- > .../ManageabilityPkg/ManageabilityPkg.dsc | 3 + > .../Dxe/DxeManageabilityTransportKcs.inf | 44 ++ > .../Common/ManageabilityTransportKcs.h | 106 ++++ > .../Common/KcsCommon.c | 480 ++++++++++++++++++ > .../Dxe/ManageabilityTransportKcs.c | 384 ++++++++++++++ > .../Dxe/ManageabilityTransportKcs.uni | 13 + > 6 files changed, 1030 insertions(+) > create mode 100644 > Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/Dxe > ManageabilityTransportKcs.inf > 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/Man > ageabilityTransportKcs.c > create mode 100644 > Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/Man > ageabilityTransportKcs.uni >=20 > diff --git a/Features/ManageabilityPkg/ManageabilityPkg.dsc > b/Features/ManageabilityPkg/ManageabilityPkg.dsc > index 0dd0ab41fc..45e07ac34f 100644 > --- a/Features/ManageabilityPkg/ManageabilityPkg.dsc > +++ b/Features/ManageabilityPkg/ManageabilityPkg.dsc > @@ -36,6 +36,9 @@ > !include MinPlatformPkg/Include/Dsc/CorePeiLib.dsc > !include MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc >=20 > +[Components] > + > +ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/DxeManagea > bil > +ityTransportKcs.inf > + > [LibraryClasses] >=20 > ManageabilityTransportLib|ManageabilityPkg/Library/BaseManageabilityTra > nsportNullLib/BaseManageabilityTransportNull.inf >=20 > diff --git > a/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/Dx > eManageabilityTransportKcs.inf > b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/Dx > eManageabilityTransportKcs.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.
# > +SPDX-License-Identifier: BSD-2-Clause-Patent # ## > + > +[Defines] > + INF_VERSION =3D 0x0001001B > + BASE_NAME =3D DxeManageabilityTransportKcs > + MODULE_UNI_FILE =3D ManageabilityTransportKcs.uni > + FILE_GUID =3D FCCC8B34-145A-4927-9F08-553ADC579AF= 7 > + MODULE_TYPE =3D DXE_DRIVER > + VERSION_STRING =3D 1.0 > + LIBRARY_CLASS =3D ManageabilityTransportLib > + > +# > +# VALID_ARCHITECTURES =3D 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/Library/ManageabilityTransportKcsLib/Commo > n/ManageabilityTransportKcs.h > b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Comm > on/ManageabilityTransportKcs.h > new file mode 100644 > index 0000000000..d5a16efc81 > --- /dev/null > +++ > b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Com > +++ mon/ManageabilityTransportKcs.h > @@ -0,0 +1,106 @@ > +/** @file > + > + Manageability transport KCS internal used definitions. > + > + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights > +reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent **/ > + > +#ifndef MANAGEABILITY_TRANSPORT_KCS_LIB_H_ > +#define MANAGEABILITY_TRANSPORT_KCS_LIB_H_ > + > +#include > + > +#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 respon= se > + data. > + @param[in, out] ResponseDataSize Size of Command Response Data. > + > + @retval EFI_SUCCESS The command byte stream was > + successfully submit to the devic= e and a > + response was successfully receiv= ed. > + @retval EFI_NOT_FOUND The command was not successfully= sent > + to the device or a response was = not > + successfully received from the d= evice. > + @retval EFI_NOT_READY Ipmi Device is not ready for Ipm= i > + 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 o= f > + resource or data size error. > +**/ > + > +EFI_STATUS > +EFIAPI > +KcsTransportSendCommand ( > + IN UINT8 NetFunction, > + IN UINT8 Command, > + IN UINT8 *RequestData, > + IN UINT32 RequestDataSize, > + OUT UINT8 *ResponseData, > + IN OUT UINT32 *ResponseDataSize > + ); > + > +/** > + 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 ad= dress > + > + @retval UINT8 8-bit value. >=20 > This is VOID function so there is no return value here. >=20 > +**/ > +VOID > +KcsRegisterWrite8 ( > + MANAGEABILITY_TRANSPORT_HARDWARE_IO Address, > + UINT8 Value > + ); > + > +#endif > diff --git > a/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Commo > n/KcsCommon.c > b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Comm > on/KcsCommon.c > new file mode 100644 > index 0000000000..ff20f4a18e > --- /dev/null > +++ > b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Com > +++ mon/KcsCommon.c > @@ -0,0 +1,480 @@ > +/** @file > + > + KCS instance of Manageability Transport Library > + > + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights > + reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > +#include > +#include > +#include > +#include > +#include > +#include #include > + > +#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 =3D 0; > + > + while (!(KcsRegisterRead8 (KCS_REG_STATUS) & Flag)) { > + MicroSecondDelay (IPMI_KCS_TIMEOUT_1MS); > + Timeout =3D Timeout + IPMI_KCS_TIMEOUT_1MS; > + if (Timeout >=3D 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 window= s. > +**/ > +EFI_STATUS > +WaitStatusClear ( > + IN UINT8 Flag > + ) > +{ > + UINT64 Timeout =3D 0; > + > + while (KcsRegisterRead8 (KCS_REG_STATUS) & Flag) { > + MicroSecondDelay (IPMI_KCS_TIMEOUT_1MS); > + Timeout =3D Timeout + IPMI_KCS_TIMEOUT_1MS; > + if (Timeout >=3D 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 OB= F > + 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. > + @param[in] RequestDataSize Size of Command Request Data. > + > + @retval EFI_SUCCESS The command byte stream was successf= ully > + submit to the device and a response = was > + successfully received. > + @retval EFI_NOT_FOUND The command was not successfully sen= t to > the > + device or a response was not success= fully > + received from the device. > + @retval EFI_NOT_READY Ipmi Device is not ready for Ipmi co= mmand > + access. > + @retval EFI_DEVICE_ERROR Ipmi Device hardware error. > + @retval EFI_TIMEOUT The command time out. > + @retval EFI_UNSUPPORTED The command was not successfully sen= t > 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, > + IN UINT32 RequestDataSize > + ) >=20 > It looks like the RequestData can be NULL. If it is, we can add "OPTIONAL= " > above. >=20 > We can also check to see if RequestDataSize is not 0 when RequestData is > not NULL. >=20 > +{ > + EFI_STATUS Status; > + UINT32 Length; > + UINT8 *Buffer; > + UINT8 *BufferPtr; > + > + Length =3D sizeof (NetFunction) + sizeof (Command); if (RequestData != =3D > + NULL) { > + Length =3D Length + RequestDataSize; > + } > + > + Buffer =3D AllocateZeroPool (Length); > + if (Buffer =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + // > + // Buffer[0] =3D NetFunction > + // Buffer[1] =3D Command > + // Buffer [2..RequestDataSize] =3D RequestData // BufferPtr =3D Buff= er; > + CopyMem (BufferPtr, &NetFunction, sizeof (NetFunction)); BufferPtr += =3D > + sizeof (NetFunction); CopyMem (BufferPtr, &Command, sizeof > + (Command)); BufferPtr +=3D sizeof (Command); if (Length > (sizeof > + (NetFunction) + sizeof (Command))) { > + CopyMem (BufferPtr, RequestData, RequestDataSize); } > + > + BufferPtr =3D Buffer; > + > + // Step 1. wait for IBF to get clear > + Status =3D 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=3Dwr_start > + KcsRegisterWrite8 (KCS_REG_COMMAND, > + IPMI_KCS_CONTROL_CODE_WRITE_START); > + > + // Step 4. wait for IBF to get clear > + Status =3D 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)) !=3D > 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 =3D WaitStatusClear (IPMI_KCS_IBF); > + if (EFI_ERROR (Status)) { > + FreePool (Buffer); > + return Status; > + } > + > + // Step 9. check state it should be WRITE_STATE, else exit with erro= r > + if (IPMI_KCS_GET_STATE (KcsRegisterRead8 (KCS_REG_STATUS)) !=3D > 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 =3D 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)) !=3D > 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 dev= ice and > + a response was successfully re= ceived. > + @retval EFI_NOT_FOUND The command was not successful= ly > sent > + to the device or a response wa= s not > + successfully received from the > + device. > + @retval EFI_NOT_READY Ipmi Device is not ready for I= pmi > + command access. > + @retval EFI_DEVICE_ERROR Ipmi Device hardware error. > + @retval EFI_TIMEOUT The command time out. > + @retval EFI_UNSUPPORTED The command was not successful= ly > 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; >=20 > It would be good if we check and see if input pointer is NULL or not. If = it is, > return EFI_INVALID_PARAMETER back to caller. >=20 > + > + ReadLength =3D 0; > + while (ReadLength < *Length) { > + // Step 1. wait for IBF to get clear > + Status =3D WaitStatusClear (IPMI_KCS_IBF); > + if (EFI_ERROR (Status)) { > + *Length =3D 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)) =3D=3D > IPMI_KCS_READ_STATE) { > + // Step 2.1.1 check of OBF to get clear > + Status =3D WaitStatusSet (IPMI_KCS_OBF); > + if (EFI_ERROR (Status)) { > + *Length =3D ReadLength; > + return Status; > + } > + > + // Step 2.1.2 read data from data out > + DataByte[ReadLength++] =3D KcsRegisterRead8 (KCS_REG_DATA_IN); > + Status =3D WaitStatusClear (IPMI_KCS_IBF); > + if (EFI_ERROR (Status)) { > + *Length =3D 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)) > =3D=3D IPMI_KCS_IDLE_STATE) { > + // Step 2.2.1 > + Status =3D WaitStatusSet (IPMI_KCS_OBF); > + if (EFI_ERROR (Status)) { > + *Length =3D ReadLength; > + return Status; > + } > + > + // Step 2.2.2 read dummy data > + KcsRegisterRead8 (KCS_REG_DATA_IN); // Dummy read as per IPMI > spec > + *Length =3D ReadLength; > + return EFI_SUCCESS; > + } else { > + *Length =3D ReadLength; > + return EFI_DEVICE_ERROR; > + } > + } > + > + *Length =3D 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 respon= se > + data. > + @param[in, out] ResponseDataSize Size of Command Response Data. > + > + @retval EFI_SUCCESS The command byte stream was > + successfully submit to the devic= e and a > + response was successfully receiv= ed. > + @retval EFI_NOT_FOUND The command was not successfully= sent > + to the device or a response was = not > + successfully received from the d= evice. > + @retval EFI_NOT_READY Ipmi Device is not ready for Ipm= i > + 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 o= f > + resource or data size error. > +**/ > +EFI_STATUS > +EFIAPI > +KcsTransportSendCommand ( > + IN UINT8 NetFunction, > + IN UINT8 Command, > + IN UINT8 *RequestData, > + IN UINT32 RequestDataSize, > + OUT UINT8 *ResponseData, > + IN OUT UINT32 *ResponseDataSize >=20 > Form the function header, this is just OUT, right? ResponseDataSize is in and out. I will also add more descriptions in funct= ion header. > + ) > +{ > + EFI_STATUS Status; > + UINT32 RspHeaderSize; > + IPMI_KCS_RESPONSE_HEADER RspHeader; > + > + if ((RequestData !=3D NULL) && (RequestDataSize <=3D 0)) { > + return EFI_INVALID_PARAMETER; > + } >=20 > Do we need similar check to ResponseData and ResponseDataSize? Yes, I also add OPTIONAL to those parameters in function prototype. Thanks Abner >=20 > + > + Status =3D 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 =3D sizeof (IPMI_KCS_RESPONSE_HEADER); > + Status =3D KcsTransportRead ((UINT8 *)&RspHeader, &RspHeaderSiz= e); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "IPMI KCS read response header failed Status(%r), " \ > + "RspNetFunctionLun =3D 0x%x, " \ > + "Comamnd =3D 0x%x \n", > + Status, > + RspHeader.NetFunc, > + RspHeader.Command > + )); > + return (Status); > + } > + > + Status =3D 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 =3D=3D > MANAGEABILITY_TRANSPORT_KCS_MEMORY_MAP_IO) { > + // Read 8-bit value from 32-bit Memory mapped address. > + Value =3D MmioRead8 ((UINTN)Address.IoAddress32); } else { > + // Read 8-bit value from 16-bit I/O address > + Value =3D 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 ad= dress > + > + @retval UINT8 8-bit value. > +**/ > +VOID > +KcsRegisterWrite8 ( > + MANAGEABILITY_TRANSPORT_HARDWARE_IO Address, > + UINT8 Value > + ) > +{ > + if (mKcsHardwareInfo.MemoryMap =3D=3D > 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/M > anageabilityTransportKcs.c > b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/M > anageabilityTransportKcs.c > new file mode 100644 > index 0000000000..7eb39ddc7a > --- /dev/null > +++ > b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe > +++ /ManageabilityTransportKcs.c > @@ -0,0 +1,384 @@ > +/** @file > + > + KCS instance of Manageability Transport Library > + > + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights > + reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +*/ > + > +#include > +#include > +#include > +#include > +#include #include > + > +#include > +#include > + > +#include "ManageabilityTransportKcs.h" > + > +MANAGEABILITY_TRANSPORT_KCS *mSingleSessionToken =3D NULL; > + > +EFI_GUID *SupportedManageabilityProtocol[] =3D { > + &gManageabilityProtocolIpmiGuid, > + &gManageabilityProtocolMctpGuid > +}; > + > +UINT8 NumberOfSupportedProtocol =3D (sizeof > +(SupportedManageabilityProtocol)/sizeof (EFI_GUID *)); > + > +MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO mKcsHardwareInfo; > + > +/** > + This function initializes the transport interface. > + > + @param [in] TransportToken The transport token acquired thr= ough > + AcquireTransportSession function= . > + @param [in] HardwareInfo The hardware information > + assigned to KCS transport interf= ace. > + > + @retval EFI_SUCCESS Transport interface is initializ= ed > + successfully. > + @retval EFI_INVALID_PARAMETER The invalid transport token. > + @retval EFI_NOT_READY The transport interface works fi= ne but > + @retval is not ready. > + @retval EFI_DEVICE_ERROR The transport interface has prob= lems. > + @retval EFI_ALREADY_STARTED Teh protocol interface has alrea= dy > 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 =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "%a: Invalid transport token.\n", > __FUNCTION__)); > + return EFI_INVALID_PARAMETER; > + } > + > + if (HardwareInfo.Kcs =3D=3D NULL) { > + DEBUG ((DEBUG_INFO, "%a: Hardware information is not provided, use > dfault settings.\n", __FUNCTION__)); > + mKcsHardwareInfo.MemoryMap =3D > MANAGEABILITY_TRANSPORT_KCS_IO_MAP_IO; > + mKcsHardwareInfo.IoBaseAddress.IoAddress16 =3D PcdGet16 > (PcdIpmiKcsBaseAddress); > + mKcsHardwareInfo.IoDataInAddress.IoAddress16 =3D > mKcsHardwareInfo.IoBaseAddress.IoAddress16 + > IPMI_KCS_DATA_IN_REGISTER_OFFSET; > + mKcsHardwareInfo.IoDataOutAddress.IoAddress16 =3D > mKcsHardwareInfo.IoBaseAddress.IoAddress16 + > IPMI_KCS_DATA_OUT_REGISTER_OFFSET; > + mKcsHardwareInfo.IoCommandAddress.IoAddress16 =3D > mKcsHardwareInfo.IoBaseAddress.IoAddress16 + > IPMI_KCS_COMMAND_REGISTER_OFFSET; > + mKcsHardwareInfo.IoStatusAddress.IoAddress16 =3D > + mKcsHardwareInfo.IoBaseAddress.IoAddress16 + > IPMI_KCS_STATUS_REGISTER_OFFSET; } else { > + mKcsHardwareInfo.MemoryMap =3D > ((MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO > *)HardwareInfo.Kcs)->MemoryMap; > + mKcsHardwareInfo.IoBaseAddress =3D > ((MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO > *)HardwareInfo.Kcs)->IoBaseAddress; > + mKcsHardwareInfo.IoDataInAddress =3D > ((MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO > *)HardwareInfo.Kcs)->IoDataInAddress; > + mKcsHardwareInfo.IoDataOutAddress =3D > ((MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO > *)HardwareInfo.Kcs)->IoDataOutAddress; > + mKcsHardwareInfo.IoCommandAddress =3D > ((MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO > *)HardwareInfo.Kcs)->IoCommandAddress; > + mKcsHardwareInfo.IoStatusAddress =3D > + ((MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO > + *)HardwareInfo.Kcs)->IoStatusAddress; > + } > + > + // Get protocol specification name. > + ManageabilityProtocolName =3D 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 funct= ion. > + @param [out] TransportAdditionalStatus The additional status of > transport > + interface. > + NULL means no additional stat= us of this > + transport interface. > + > + @retval EFI_SUCCESS Transport interface status is re= turned. > + @retval EFI_INVALID_PARAMETER The invalid transport token. > + @retval EFI_DEVICE_ERROR The transport interface has prob= lems 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 =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "%a: Invalid transport token.\n", > __FUNCTION__)); > + return EFI_INVALID_PARAMETER; > + } > + > + if (TransportAdditionalStatus =3D=3D NULL) { > + return EFI_SUCCESS; > + } > + > + TransportStatus =3D IPMI_KCS_GET_STATE (KcsRegisterRead8 > (KCS_REG_STATUS)); > + *TransportAdditionalStatus =3D > + MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS_NO_ERRORS; >=20 > TransportAdditionalStatus can be NULL. This may create CPU assertion. We checked if TransportAdditionalStatus=3D=3DNULL in few lines above. Thanks Abner >=20 > + if (TransportStatus !=3D IPMI_KCS_IDLE_STATE) { > + if (TransportStatus =3D=3D IPMI_KCS_READ_STATE) { > + // > + // Transport is in read state. > + *TransportAdditionalStatus |=3D > MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS_BUSY_IN_READ; > + return EFI_NOT_READY; > + } else if (TransportStatus =3D=3D IPMI_KCS_WRITE_STATE) { > + // > + // Transport is in read state. > + *TransportAdditionalStatus |=3D > 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 funct= ion. > + @param [out] TransportAdditionalStatus The additional status of spec= ific > transport > + interface after the reset. > + NULL means no additional stat= us of this > + transport interface. > + > + @retval EFI_SUCCESS Transport interface status is re= turned. > + @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 prob= lems 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 thr= ough > + AcquireTransportSession function= . > + @param [in] TransferToken The transfer token, see the defi= nition 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 =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "%a: Invalid transport token.\n", > __FUNCTION__)); > + return; > + } >=20 > We need same check to TransferToken. >=20 > + > + TransmitHeader =3D (MANAGEABILITY_IPMI_TRANSPORT_HEADER > + *)TransferToken->TransmitHeader; if (TransmitHeader =3D=3D NULL) { > + TransferToken->TransferStatus =3D EFI_INVALID_PARAMETER; > + return; > + } > + > + Status =3D KcsTransportSendCommand ( > + TransmitHeader->NetFn, > + TransmitHeader->Command, > + TransferToken->TransmitPackage.TransmitPayload, > + TransferToken->TransmitPackage.TransmitSizeInByte, > + TransferToken->ReceivePackage.ReceiveBuffer, > + &TransferToken->ReceivePackage.ReceiveSizeInByte > + ); > + > + TransferToken->TransferStatus =3D 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 oper= ations. > + > + @param [in] ManageabilityProtocolSpec The protocol spec the transpo= rt > interface is acquired. > + @param [out] TransportToken The pointer to receive the tr= ansport > token created by > + the target transport interfac= e library. > + @retval EFI_SUCCESS Token is created successfully= . > + @retval EFI_OUT_OF_RESOURCES Out of resource to create a n= ew > 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 =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "%a: No Manageability protocol specification > specified.\n", __FUNCTION__)); > + return EFI_INVALID_PARAMETER; > + } >=20 > Please also check TransportToken pointer. >=20 > + > + Status =3D HelperManageabilityCheckSupportedSpec ( > + &gManageabilityTransportKcsGuid, > + SupportedManageabilityProtocol, > + NumberOfSupportedProtocol, > + ManageabilityProtocolSpec > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: Protocol is not supported on this transpor= t > interface.\n", __FUNCTION__)); > + return EFI_UNSUPPORTED; > + } > + > + if (mSingleSessionToken !=3D NULL) { > + DEBUG ((DEBUG_ERROR, "%a: This manageability transport library only > supports one session transport token.\n", __FUNCTION__)); > + return EFI_OUT_OF_RESOURCES; > + } > + > + KcsTransportToken =3D AllocateZeroPool (sizeof > + (MANAGEABILITY_TRANSPORT_KCS)); if (KcsTransportToken =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "%a: Fail to allocate memory for > MANAGEABILITY_TRANSPORT_KCS\n", __FUNCTION__)); > + return EFI_OUT_OF_RESOURCES; > + } > + KcsTransportToken->Token.Transport =3D AllocateZeroPool (sizeof > + (MANAGEABILITY_TRANSPORT)); if (KcsTransportToken->Token.Transport > =3D=3D NULL) { > + FreePool (KcsTransportToken); > + DEBUG ((DEBUG_ERROR, "%a: Fail to allocate memory for > MANAGEABILITY_TRANSPORT\n", __FUNCTION__)); > + return EFI_OUT_OF_RESOURCES; > + } > + > + KcsTransportToken->Signature = =3D > MANAGEABILITY_TRANSPORT_KCS_SIGNATURE; > + KcsTransportToken->Token.ManageabilityProtocolSpecification = =3D > ManageabilityProtocolSpec; > + KcsTransportToken->Token.Transport->TransportVersion = =3D > MANAGEABILITY_TRANSPORT_TOKEN_VERSION; > + KcsTransportToken->Token.Transport- > >ManageabilityTransportSpecification =3D &gManageabilityTransportKcsGuid; > + KcsTransportToken->Token.Transport->TransportName = =3D > L"KCS"; > + KcsTransportToken->Token.Transport->Function.Version1_0 = =3D > AllocateZeroPool (sizeof (MANAGEABILITY_TRANSPORT_FUNCTION_V1_0)); > + if (KcsTransportToken->Token.Transport->Function.Version1_0 =3D=3D NUL= L) { > + 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 =3D KcsTransportInit; > + KcsTransportToken->Token.Transport->Function.Version1_0- > >TransportReset =3D KcsTransportReset; > + KcsTransportToken->Token.Transport->Function.Version1_0- > >TransportStatus =3D KcsTransportStatus; > + > + KcsTransportToken->Token.Transport->Function.Version1_0- > >TransportTran > + smitReceive =3D KcsTransportTransmitReceive; > + > + mSingleSessionToken =3D KcsTransportToken; > + *TransportToken =3D &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_CAPABILI= TY. > + > +**/ > +VOID > +GetTransportCapability ( > + OUT MANAGEABILITY_TRANSPORT_CAPABILITY *TransportCapability > + ) > +{ > + if (TransportCapability !=3D NULL) { > + *TransportCapability =3D 0; > + } > +} > + > +/** > + This function releases the manageability session. > + > + @param [in] TransportToken The transport token acquired throu= gh > + 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 =3D=3D NULL) { > + Status =3D EFI_INVALID_PARAMETER; > + } > + > + KcsTransportToken =3D MANAGEABILITY_TRANSPORT_KCS_FROM_LINK > + (TransportToken); if (mSingleSessionToken !=3D KcsTransportToken) { > + Status =3D EFI_INVALID_PARAMETER; > + } > + > + if (KcsTransportToken !=3D NULL) { > + FreePool (KcsTransportToken->Token.Transport->Function.Version1_0); > + FreePool (KcsTransportToken->Token.Transport); > + FreePool (KcsTransportToken); > + mSingleSessionToken =3D NULL; > + Status =3D 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/M > anageabilityTransportKcs.uni > b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/M > anageabilityTransportKcs.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.
// // > +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