From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM11-BN8-obe.outbound.protection.outlook.com (NAM11-BN8-obe.outbound.protection.outlook.com [40.107.236.40]) by mx.groups.io with SMTP id smtpd.web11.14038.1679319156737024064 for ; Mon, 20 Mar 2023 06:32:37 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@nvidia.com header.s=selector2 header.b=f8Az0ibU; spf=permerror, err=parse error for token &{10 18 %{i}._ip.%{h}._ehlo.%{d}._spf.vali.email}: invalid domain name (domain: nvidia.com, ip: 40.107.236.40, mailfrom: nicklew@nvidia.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=J85o07Om24oJkGi9Dh3njd6HFXavABtgCllFrHPjp5u4UOvODzZhakels71LGH9fr4NSZ2eaNUlDHn/9oKAIN38I+YEja+cyxgUNgvnOKguTPwUYP2c0k5uejaDFEd1qWLvlo5sA0Tk10gQrzLEGQ2wZ/GG5ols0uzMMAMWNBTYAqy5rTfmTGzYFTVaP+A+0A5fl9fO10KXeVyoMsf40so3UTyj7hf9bgviVGhEtvroC3bJmddbEDwUStAmaXU347XfNPE6MPFH+tYTIZTyGCsRVPxgMFBa9PffjnlJCvQzdF3l1l3V7eMjnDtZbfSynXe0LA5xX1iMJDhQG7EG8VA== 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=DV+HHTODMGsRWwh8I0zugiGiX+wzNJd6EO+QG8FhijA=; b=MuzQ8qOSadJyxExOZFXuD8N8IEPErtz3sWjezwFEO7XG+F742jFuH26E7uBtNf/vDiOAER6MO4YDc+qc6Q9oHexsQPvBQHlZZi9TPSYaTjvhADCYsv/ROpYeMNu0rc8d3vX//LAspBEODdRMXdR6qum+rZj4TVr1R9ECZwotnaztUSkY/J+yG8stiRBcLGLKWcqY+yimuojL+Cd3+yUbFd3Q7sNAP4RBsjMnM1oWijfw57z4nJbq3jVfyS6hpIxgBCOHqrEW80a+ZRQvdyimqbm4KzBakwQg5Z5kS0Pmu/cQad+qy+Pits3G0F6dvLdKiIf0pc6uaGHJJ0Fkg3v8mw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=DV+HHTODMGsRWwh8I0zugiGiX+wzNJd6EO+QG8FhijA=; b=f8Az0ibUqYcPbGdl6syWCywAhXY1d/Ih4WjLMxMAJe3crMSQz8FCIE/46Y6O4Bns1BJj49mYb/ash0KkRnKzG6/4UFNSau6veowthM7eF8tEC2nJ8evSWAxSjBa3ydy+z7jW7zLDaIshymVXmtsCgYnjt5f0CxAn/gzPfsnWO53qIyhWggxG8E/CCCn25tLhAVr8O7O8Bg5fHK/5SIr4t/dVVQZiJE+aW5FhrPlCEEeoczwTzkA4OavA/nUEYp9ufRDqTwSW+07EB2jiUcensSxzlwqdmWUI4cFdxUuJfVoYUV9l+MNn6Ad2ZY6hglhvD76cTTY3yQcosNB+j2k5Tg== Received: from MW4PR12MB7031.namprd12.prod.outlook.com (2603:10b6:303:1ef::6) by DM4PR12MB5892.namprd12.prod.outlook.com (2603:10b6:8:68::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6178.37; Mon, 20 Mar 2023 13:32:32 +0000 Received: from MW4PR12MB7031.namprd12.prod.outlook.com ([fe80::c27a:fa4b:66ea:d266]) by MW4PR12MB7031.namprd12.prod.outlook.com ([fe80::c27a:fa4b:66ea:d266%5]) with mapi id 15.20.6178.037; Mon, 20 Mar 2023 13:32:28 +0000 From: "Nickle Wang" To: "abner.chang@amd.com" , "devel@edk2.groups.io" CC: Liming Gao , Isaac Oram , Nate DeSimone , Abdul Lateef Attar , Igor Kulchytskyy Subject: Re: [edk2-platforms][PATCH V2 5/8] ManageabilityPkg/ManageabilityTransportKcsLib Thread-Topic: [edk2-platforms][PATCH V2 5/8] ManageabilityPkg/ManageabilityTransportKcsLib Thread-Index: AQHZUci2A1ldg5SekEChp1U6hYv7xa8DunHQ Date: Mon, 20 Mar 2023 13:32:27 +0000 Message-ID: References: <20230308141647.1318-1-abner.chang@amd.com> <20230308141647.1318-6-abner.chang@amd.com> In-Reply-To: <20230308141647.1318-6-abner.chang@amd.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: MW4PR12MB7031:EE_|DM4PR12MB5892:EE_ x-ms-office365-filtering-correlation-id: d34a6980-9f2b-40a8-2a41-08db29478c5b x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: l/bgyBNAY141DCndg3AbvU6y89XETYcUn0+zeUOXERKJNLw53Ckzt/3g6q/dkZDUrL0pnTgYrJJrwCRwhM/udTEZHpSPqgSY2Qftq4h1J9bO89M81qtbemkoTK7eMOysGJjTBjBsKfV5mh99/8Z7RyAPZceIsvo2+ZK/ScAlLW7SnvULvwO/dtSfxJ3N51W02GCsodkJ9K+PhOwSGxf8YcSDheopEoOGRYZAeLy+uxVtzJVT2OzBH6UHPK/Uojqd50KPy8Nb97sNNa/3AG2V1susY30wN72J2qeldiHR2wqgHle083q0fPUUzXMzsIyQbqZhMEvj3/qTf3lHcySZesix70/HUHawWQ6XgaS1EmvEfxHX8aftJtYO5T+0gLeNK8PVYuh+f/4ZaYsW09G9XAUb2uBtIbY6L28M+1cXMvZVodtAmkmnvB0ALme3G1zs9zB797UMVcGEyFwu6+FdioMTmaezhx3NRJ4SUtQhnE0fHc2DO3Yleq6jVL6Cqvj59B5S9ISjPngSS0pJ6FpJmmqTYoGPVI2Sb6gMk8P9s8J9T2aCZRmiFkG7I97wd00OihQsc8jdhzG40O3ke4be6N/srPWs3l1dQJV0tRM5m2BudB9sQOp+eg7TH8tVmnI9p9JYxdn4yUIn9uJi+ExBAu4P1mt5j4squUnCFPCuqd8gSiiiPYH/1su+Tfkevr7aakulLEfIbt2ZSI6qJEQce057lUD1NKFYHfT4JuY5Ej4= x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MW4PR12MB7031.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230025)(4636009)(346002)(39860400002)(376002)(396003)(136003)(366004)(451199018)(7696005)(71200400001)(186003)(4326008)(83380400001)(478600001)(316002)(19627235002)(110136005)(66476007)(66446008)(76116006)(66946007)(64756008)(66556008)(8676002)(9686003)(26005)(6506007)(53546011)(54906003)(41300700001)(52536014)(5660300002)(8936002)(30864003)(38100700002)(122000001)(2906002)(55016003)(86362001)(38070700005)(33656002)(579004)(559001)(44824005);DIR:OUT;SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?0ZeWEOSgGybExjAlZ7YUo6MkxRKV9lHAPEhz86Z4UFiClP66IDa2qiJlW08p?= =?us-ascii?Q?pfZDgDeBa81n7tacURlJjg598Y4zvNA4oXdumlIHmtZ8n+rQ+o6pXCx1mQGp?= =?us-ascii?Q?Nwn53y4RghsMzEF1YLDL35QOkw6/ax1llMFHmTVd63MlxUzZxki0j3uFAbxT?= =?us-ascii?Q?hfLerXk66F/OcYGr1w8wnPt6nWIuA1o3mZrYr9GXUpNlX3gLc8UkJk+ZtAUl?= =?us-ascii?Q?/0eUhxHOuzHego4kQWbj6Lob1nsUQNAf1rmGl9DnY0pXvkukTgEltIbVuzQP?= =?us-ascii?Q?6XXkJLwt6QVrVMVpC6KzxU8phegHCyOkkm8VQSNnil/aY4s/LSyVGPcq4pU6?= =?us-ascii?Q?SeHS1AJf6i/QzKrp2Z0PP72o+pCwhrcRaiJu+xux+C2GCZk9qnkdEBAH2ypU?= =?us-ascii?Q?kVrwNiCr6TOQbS/l7a2zUBAHMerpf6dQFUF1LuDSO7oIUp48NepuZc6HnxpL?= =?us-ascii?Q?7Q1FUG9sKUW8RDdPsTthYBp3D8MUFNPwuxS7bPxdM/QGBP5FdWyvPEWj4HgL?= =?us-ascii?Q?adsp+rF0GAm569pPPA9ioQeVcVbiRws6gZjNizmC3iWPP686iwLVRsxnj418?= =?us-ascii?Q?Jc02YOdz90bOfjw74qENr2Q7PZ4LCL2KkPPjj8bKc84e+3xwDklrW/+Ju5S0?= =?us-ascii?Q?I+6+vE9aYPVDeH93DKyGif41oYVGZ6/fiQ+BQ7uw1odwYmFS55JlB+CeQV3p?= =?us-ascii?Q?5VAL/0nUqe4BKlrv8JhduU+Ry3m0+A8Ud0jR1+qpgIWHc8o95Z01YYcP07Nc?= =?us-ascii?Q?MH0cAAcLeJWdJ+qb1hKEo4cbTTnvH8JMcnHlAVXFi01FfdF0BrMlZMGBLu2E?= =?us-ascii?Q?U7hngCJtTJSPHjqARyqXbCNuGgmCiyR8fIcRvTERPyz5mC74A4vfeUsP9LkV?= =?us-ascii?Q?YOkeDaj+fQw/ZNn6vhFaAJFbLXpIVA611mcpaZyBJxUuwoWqMtIz1Ax6yW8c?= =?us-ascii?Q?YW9YnoMQt6Rm3YiS0imCPxtbbDIsK/ooQ7PCz7IjydI5QoJCjVb+aL4i/dBl?= =?us-ascii?Q?l7xH3jrC/cE0pdsBQZ3jArWv/8o7BkWICEfhfjXdQBYnngb3t0q/4VG5zSW4?= =?us-ascii?Q?hVxLc9W7exzc6dVvQ4O83BTDUea6Z/zBc1HV+BK4Cl/dQNeKSXR+bISPeSxF?= =?us-ascii?Q?EF7+OwBGQvexC4v0EBH2CeoJEt/3TKtjRUWWNrnBn7Y/Al9DzEWNOpoMEgAN?= =?us-ascii?Q?6fs5iffphvgxRWtu1XuOCDaYxvNVJg2RzxHF7sCGBELtLCifUceTprGMr+Ln?= =?us-ascii?Q?z9DLxWbFixfdaNZ7L+nAYHSLWD88nRtkykI6nD0xcDI8BnxdFHHmPWM5SNuh?= =?us-ascii?Q?DeRKp4gJTY7CgNP9hcrMy9yT8Wy/iQR7HhSFGNdQQMGz6mdQsq0ma/ID30ub?= =?us-ascii?Q?tkoZ5sHI+9ELelX6ngAn9DV1ewAxkbDMMkyktoQItal/0vi08oL1BJAMts8x?= =?us-ascii?Q?5PJxo6Bau2FnusEBhIZZxBTHqr4UFELkhSY3Zkd0snILyoCn2eBkrio5cE2G?= =?us-ascii?Q?mJqpYDGtEwpXgpN9jcCe3NGNkSLXFc9dHxoRBxQSfV+OHVB0ZwbGIpnqcPna?= =?us-ascii?Q?Fakdwc8+sbMxDHicDcSjMlqEN5K/0GLQzXFGohhr?= MIME-Version: 1.0 X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: MW4PR12MB7031.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: d34a6980-9f2b-40a8-2a41-08db29478c5b X-MS-Exchange-CrossTenant-originalarrivaltime: 20 Mar 2023 13:32:27.6790 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: n60dX6U7w5bHCmYttrRCt7bSPlNB/FbNyZ1iHhrd71m2QSeLQnWZkbM6Xa/D6Ily4qNnMOmGBTAyUCS1Z5IuoA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB5892 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Please see my comments inline below. Regards, Nickle -----Original Message----- From: abner.chang@amd.com =20 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/ManageabilityTrans= portKcsLib External email: Use caution opening links or attachments From: Abner Chang This is the KCS manageability transport library instance follows the design= guidance described in Readme file under ManageabilityPkg. 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/ManageabilityTranspor= tKcsLib/Dxe/DxeManageabilityTransportKcs.inf create mode 100644 Features/ManageabilityPkg/Library/ManageabilityTranspor= tKcsLib/Common/ManageabilityTransportKcs.h create mode 100644 Features/ManageabilityPkg/Library/ManageabilityTranspor= tKcsLib/Common/KcsCommon.c create mode 100644 Features/ManageabilityPkg/Library/ManageabilityTranspor= tKcsLib/Dxe/ManageabilityTransportKcs.c create mode 100644 Features/ManageabilityPkg/Library/ManageabilityTranspor= tKcsLib/Dxe/ManageabilityTransportKcs.uni diff --git a/Features/ManageabilityPkg/ManageabilityPkg.dsc b/Features/Mana= geabilityPkg/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 +[Components] + =20 +ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe/DxeManageabil +ityTransportKcs.inf + [LibraryClasses] ManageabilityTransportLib|ManageabilityPkg/Library/BaseManageabilityTran= sportNullLib/BaseManageabilityTransportNull.inf diff --git a/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib= /Dxe/DxeManageabilityTransportKcs.inf b/Features/ManageabilityPkg/Library/M= anageabilityTransportKcsLib/Dxe/DxeManageabilityTransportKcs.inf new file mode 100644 index 0000000000..f0a6afa074 --- /dev/null +++ b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe +++ /DxeManageabilityTransportKcs.inf @@ -0,0 +1,44 @@ +## @file +# KCS instance of Manageability Transport Library # # Copyright (C)=20 +2023 Advanced Micro Devices, Inc. All rights reserved.
#=20 +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-553ADC579AF7 + 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= /Common/ManageabilityTransportKcs.h b/Features/ManageabilityPkg/Library/Man= ageabilityTransportKcsLib/Common/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=20 +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',=20 +'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,=20 +MANAGEABILITY_TRANSPORT_KCS, Token,=20 +MANAGEABILITY_TRANSPORT_KCS_SIGNATURE) + +#define IPMI_KCS_GET_STATE(s) (s >> 6) #define IPMI_KCS_SET_STATE(s) =20 +(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 complet= ion + 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 s= ent + to the device or a response was no= t + successfully received from the dev= ice. + @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 s= ent 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, + 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 a= ddress + 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 a= ddress + or 32-bit memory mapped address. + @param[in] Value 8-bit value write to register addr= ess + + @retval UINT8 8-bit value. This is VOID function so there is no return value here. +**/ +VOID +KcsRegisterWrite8 ( + MANAGEABILITY_TRANSPORT_HARDWARE_IO Address, + UINT8 Value + ); + +#endif diff --git a/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib= /Common/KcsCommon.c b/Features/ManageabilityPkg/Library/ManageabilityTransp= ortKcsLib/Common/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=20 + 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 windows. +**/ +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 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. + @param[in] RequestDataSize Size of Command Request Data. + + @retval EFI_SUCCESS The command byte stream was successful= ly + submit to the device and a response wa= s + successfully received. + @retval EFI_NOT_FOUND The command was not successfully sent = to the + device or a response was not successfu= lly + received from the device. + @retval EFI_NOT_READY Ipmi Device is not ready for Ipmi comm= and + 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 reso= urce or + data size error. +**/ +EFI_STATUS +KcsTransportWrite ( + IN UINT8 NetFunction, + IN UINT8 Command, + IN UINT8 *RequestData, + IN UINT32 RequestDataSize + ) It looks like the RequestData can be NULL. If it is, we can add "OPTIONAL" = above. We can also check to see if RequestDataSize is not 0 when RequestData is n= ot NULL. +{ + EFI_STATUS Status; + UINT32 Length; + UINT8 *Buffer; + UINT8 *BufferPtr; + + Length =3D sizeof (NetFunction) + sizeof (Command); if (RequestData != =3D=20 + 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 Buffer= ; =20 + CopyMem (BufferPtr, &NetFunction, sizeof (NetFunction)); BufferPtr +=3D= =20 + sizeof (NetFunction); CopyMem (BufferPtr, &Command, sizeof=20 + (Command)); BufferPtr +=3D sizeof (Command); if (Length > (sizeof=20 + (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,=20 + 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 =20 + 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 error + if (IPMI_KCS_GET_STATE (KcsRegisterRead8 (KCS_REG_STATUS)) !=3D IPMI_K= CS_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=20 + (IPMI_KCS_IBF); if (EFI_ERROR (Status)) { + FreePool (Buffer); + return Status; + } + + // Step 14. check state it should be WRITE_STATE, else exit with=20 + error if (IPMI_KCS_GET_STATE (KcsRegisterRead8 (KCS_REG_STATUS)) !=3D IP= MI_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 po= rt. + @retval EFI_SUCCESS The command byte stream was + successfully submit to the devic= e and + a response was successfully rece= ived. + @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 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= set + to the device. + @retval EFI_OUT_OF_RESOURCES The resource allocation is out o= f + resource or data size error. +**/ +EFI_STATUS +KcsTransportRead ( + OUT UINT8 *DataByte, + IN OUT UINT32 *Length + ) +{ + EFI_STATUS Status; + UINT32 ReadLength; 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. + + 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 complet= ion + 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 s= ent + to the device or a response was no= t + successfully received from the dev= ice. + @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 s= ent 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, + IN UINT32 RequestDataSize, + OUT UINT8 *ResponseData, + IN OUT UINT32 *ResponseDataSize Form the function header, this is just OUT, right? + ) +{ + EFI_STATUS Status; + UINT32 RspHeaderSize; + IPMI_KCS_RESPONSE_HEADER RspHeader; + + if ((RequestData !=3D NULL) && (RequestDataSize <=3D 0)) { + return EFI_INVALID_PARAMETER; + } Do we need similar check to ResponseData and ResponseDataSize? + + 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, &RspHeaderSize)= ; + 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); = =20 + 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 a= ddress + 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 a= ddress + or 32-bit memory mapped address. + @param[in] Value 8-bit value write to register addr= ess + + @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/ManageabilityTransportKcs.c b/Features/ManageabilityPkg/Library/Manage= abilityTransportKcsLib/Dxe/ManageabilityTransportKcs.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=20 + reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +*/ + +#include +#include +#include +#include +#include #include=20 + +#include +#include + +#include "ManageabilityTransportKcs.h" + +MANAGEABILITY_TRANSPORT_KCS *mSingleSessionToken =3D NULL; + +EFI_GUID *SupportedManageabilityProtocol[] =3D { + &gManageabilityProtocolIpmiGuid, + &gManageabilityProtocolMctpGuid +}; + +UINT8 NumberOfSupportedProtocol =3D (sizeof=20 +(SupportedManageabilityProtocol)/sizeof (EFI_GUID *)); + +MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO mKcsHardwareInfo; + +/** + This function initializes the transport interface. + + @param [in] TransportToken The transport token acquired throu= gh + AcquireTransportSession function. + @param [in] HardwareInfo The hardware information + assigned to KCS transport interfac= e. + + @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 proble= ms. + @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=20 +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 dfa= ult settings.\n", __FUNCTION__)); + mKcsHardwareInfo.MemoryMap =3D MANAGEABILITY_TRANSP= ORT_KCS_IO_MAP_IO; + mKcsHardwareInfo.IoBaseAddress.IoAddress16 =3D PcdGet16 (PcdIpmiKcs= BaseAddress); + mKcsHardwareInfo.IoDataInAddress.IoAddress16 =3D mKcsHardwareInfo.IoB= aseAddress.IoAddress16 + IPMI_KCS_DATA_IN_REGISTER_OFFSET; + mKcsHardwareInfo.IoDataOutAddress.IoAddress16 =3D mKcsHardwareInfo.IoB= aseAddress.IoAddress16 + IPMI_KCS_DATA_OUT_REGISTER_OFFSET; + mKcsHardwareInfo.IoCommandAddress.IoAddress16 =3D mKcsHardwareInfo.IoB= aseAddress.IoAddress16 + IPMI_KCS_COMMAND_REGISTER_OFFSET; + mKcsHardwareInfo.IoStatusAddress.IoAddress16 =3D=20 + mKcsHardwareInfo.IoBaseAddress.IoAddress16 + IPMI_KCS_STATUS_REGISTER_OFF= SET; } else { + mKcsHardwareInfo.MemoryMap =3D ((MANAGEABILITY_TRANSPORT_KCS_HA= RDWARE_INFO *)HardwareInfo.Kcs)->MemoryMap; + mKcsHardwareInfo.IoBaseAddress =3D ((MANAGEABILITY_TRANSPORT_KCS_HA= RDWARE_INFO *)HardwareInfo.Kcs)->IoBaseAddress; + mKcsHardwareInfo.IoDataInAddress =3D ((MANAGEABILITY_TRANSPORT_KCS_HA= RDWARE_INFO *)HardwareInfo.Kcs)->IoDataInAddress; + mKcsHardwareInfo.IoDataOutAddress =3D ((MANAGEABILITY_TRANSPORT_KCS_HA= RDWARE_INFO *)HardwareInfo.Kcs)->IoDataOutAddress; + mKcsHardwareInfo.IoCommandAddress =3D ((MANAGEABILITY_TRANSPORT_KCS_HA= RDWARE_INFO *)HardwareInfo.Kcs)->IoCommandAddress; + mKcsHardwareInfo.IoStatusAddress =3D=20 + ((MANAGEABILITY_TRANSPORT_KCS_HARDWARE_INFO=20 + *)HardwareInfo.Kcs)->IoStatusAddress; + } + + // Get protocol specification name. + ManageabilityProtocolName =3D HelperManageabilitySpecName=20 + (TransportToken->ManageabilityProtocolSpecification); + + DEBUG ((DEBUG_INFO, "%a: KCS transport hardware for %s is:\n",=20 + __FUNCTION__, ManageabilityProtocolName)); if (mKcsHardwareInfo.MemoryMa= p) { + 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.Io= BaseAddress.IoAddress16)); + DEBUG ((DEBUG_INFO, "Data in I/O port : 0x%04x\n", mKcsHardwareInfo.Io= DataInAddress.IoAddress16)); + DEBUG ((DEBUG_INFO, "Data out I/O port: 0x%04x\n", mKcsHardwareInfo.Io= DataOutAddress.IoAddress16)); + DEBUG ((DEBUG_INFO, "Command I/O port : 0x%04x\n", mKcsHardwareInfo.Io= CommandAddress.IoAddress16)); + DEBUG ((DEBUG_INFO, "Status I/O port : 0x%04x\n",=20 + 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 th= rough + AcquireTransportSession functio= n. + @param [out] TransportAdditionalStatus The additional status of transp= ort + interface. + NULL means no additional status= of this + transport interface. + + @retval EFI_SUCCESS Transport interface status is retu= rned. + @retval EFI_INVALID_PARAMETER The invalid transport token. + @retval EFI_DEVICE_ERROR The transport interface has proble= ms to return + @retval EFI_UNSUPPORTED The transport interface doesn't ha= ve status report. + Otherwise Other errors. + +**/ +EFI_STATUS +EFIAPI +KcsTransportStatus ( + IN MANAGEABILITY_TRANSPORT_TOKEN *TransportToken, + OUT MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS =20 +*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=20 + MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS_NO_ERRORS; TransportAdditionalStatus can be NULL. This may create CPU assertion. + 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_S= TATUS_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_S= TATUS_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=20 +transport + interface. The additional information of transport interface could be=20 +optionally + returned in TransportAdditionalStatus to describes the status that=20 +can't be + described obviously through EFI_STATUS. + See the definition of MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS. + + @param [in] TransportToken The transport token acquired th= rough + AcquireTransportSession functio= n. + @param [out] TransportAdditionalStatus The additional status of specif= ic transport + interface after the reset. + NULL means no additional status= of this + transport interface. + + @retval EFI_SUCCESS Transport interface status is retu= rned. + @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 proble= ms to return + status. + Otherwise Other errors. + +**/ +EFI_STATUS +EFIAPI +KcsTransportReset ( + IN MANAGEABILITY_TRANSPORT_TOKEN *TransportToken, + OUT MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS =20 +*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=20 +transport + interface. The additional information of transport interface could be=20 +optionally + returned in TransportAdditionalStatus to describes the status that=20 +can't be + described obviously through EFI_STATUS. + See the definition of MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS. + + @param [in] TransportToken The transport token acquired throu= gh + AcquireTransportSession function. + @param [in] TransferToken The transfer token, see the defini= tion 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; + } We need same check to TransferToken. + + TransmitHeader =3D (MANAGEABILITY_IPMI_TRANSPORT_HEADER=20 + *)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,=20 +&TransferToken->TransportAdditionalStatus); +} + +/** + This function acquires to create a transport session to transmit=20 +manageability + packet. A transport token is returned to caller for the follow up operat= ions. + + @param [in] ManageabilityProtocolSpec The protocol spec the transport= interface is acquired. + @param [out] TransportToken The pointer to receive the tran= sport 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 th= is 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 spec= ified.\n", __FUNCTION__)); + return EFI_INVALID_PARAMETER; + } Please also check TransportToken pointer. + + Status =3D 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 !=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: This manageability transport library only su= pports one session transport token.\n", __FUNCTION__)); + return EFI_OUT_OF_RESOURCES; + } + + KcsTransportToken =3D AllocateZeroPool (sizeof=20 + (MANAGEABILITY_TRANSPORT_KCS)); if (KcsTransportToken =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: Fail to allocate memory for MANAGEABILITY_TR= ANSPORT_KCS\n", __FUNCTION__)); + return EFI_OUT_OF_RESOURCES; + } + KcsTransportToken->Token.Transport =3D AllocateZeroPool (sizeof=20 + (MANAGEABILITY_TRANSPORT)); if (KcsTransportToken->Token.Transport =3D= =3D NULL) { + FreePool (KcsTransportToken); + DEBUG ((DEBUG_ERROR, "%a: Fail to allocate memory for MANAGEABILITY_TR= ANSPORT\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 NULL)= { + DEBUG ((DEBUG_ERROR, "%a: Fail to allocate memory for MANAGEABILITY_TR= ANSPORT_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; + =20 + 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 capab= ilities. + See the definitions of + MANAGEABILITY_TRANSPORT_CAPABILITY= . + +**/ +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 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 =3D=3D NULL) { + Status =3D EFI_INVALID_PARAMETER; + } + + KcsTransportToken =3D MANAGEABILITY_TRANSPORT_KCS_FROM_LINK=20 + (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=20 + (%r).\n", __FUNCTION__, Status)); } + + return Status; +} diff --git a/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib= /Dxe/ManageabilityTransportKcs.uni b/Features/ManageabilityPkg/Library/Mana= geabilityTransportKcsLib/Dxe/ManageabilityTransportKcs.uni new file mode 100644 index 0000000000..61a3e8b588 --- /dev/null +++ b/Features/ManageabilityPkg/Library/ManageabilityTransportKcsLib/Dxe +++ /ManageabilityTransportKcs.uni @@ -0,0 +1,13 @@ +// /** @file +// KCS instance of Manageability Transport Library // // Copyright (C)=20 +2023 Advanced Micro Devices, Inc. All rights reserved.
// //=20 +SPDX-License-Identifier: BSD-2-Clause-Patent // // **/ + +#string STR_MODULE_ABSTRACT #language en-US "KCS instance of M= anageability Transport Library" + +#string STR_MODULE_DESCRIPTION #language en-US "KCS Manageability= Transport library implementation." + -- 2.37.1.windows.1