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.41]) by mx.groups.io with SMTP id smtpd.web11.2669.1681802190573091975 for ; Tue, 18 Apr 2023 00:16:30 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@amd.com header.s=selector1 header.b=KttE4ede; 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.236.41, mailfrom: abner.chang@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=fm7iNsT8qACnhJynk+nBy9uplGnDAAVKE62PsGhP8SeBJQuJp5xSpKs4CZOHYsduJZSpf5iG3DOQ7gRJVj+wTGEuiR0B1nQIkNdi/Jidn6zvGbacHFjxzfOxIMfeqWXeM/8MJ7i79Ou8kK+08Ru5fM2t4CCwbf/WNQUIhIVD1mvYNjUWQE4mnRbjSy0B+R4qlGEL4FMaXj6v15XKRb3NqjLG4GkoHEsKMgAXeZCd08sNufCZDJz9yvEqZ6epEOYIsJ1WUaNSj5V6wjMv6Lq8qLcAKQqhCx7WeolyCogThBVLG6M0FaABSR3ZnSrNDP46qwdpkUoDZwl8i4h49+EEFQ== 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=gtdWLQhsjTtAiVMicc+D3hqQHC9W1SS8MW3gr8tvfNA=; b=Sa1269hB14j1hvVtv5kd7qGbOm8bwUMPkfxu7BtnuZcUwfhvgIUQkR/GHDt8dzv4geXMkZgghb53fx2rKfbZzMChRj1cnCeycbgrkw4zg02MU4cPxcGkm+nk9SdvSB2RXQGdng8vwQdRHE5ZwabL5Eo8JZ34donWTLZxnr7yjOWWXewh2AoFAbj/wsiKOdM/uXIfdwgWpdZ2+VyQQAtkOt1K9BvvUtohhardQP4Okd1ROp7oq9uk3pHcbEa5Td375qFuRTM1rU6xqqJXeMBY1XIq4Qe1Pjyq2u5JZaATicsg1oxpFu3NmAhXkWB7OFVgQRcCV3LRqVs/9H9nmou/7w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); 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=gtdWLQhsjTtAiVMicc+D3hqQHC9W1SS8MW3gr8tvfNA=; b=KttE4edeRJn4ti9SHr//IWbeFpO6817oPP5eP3EpPDLXipAh2KS+gKtIptWKB+ceZh+mytWUpuwiq92BVrTk3lD80CEqkhSvg0Do5NMNdigQ+4agqn0dMN6ZhKhmJUouqJ9ft9FtGurxRSlQbPLEt71kJlcZFI1Q/X9WoS9vf1g= Received: from DM6PR02CA0084.namprd02.prod.outlook.com (2603:10b6:5:1f4::25) by DS0PR12MB6581.namprd12.prod.outlook.com (2603:10b6:8:d3::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6298.45; Tue, 18 Apr 2023 07:16:27 +0000 Received: from DM6NAM11FT088.eop-nam11.prod.protection.outlook.com (2603:10b6:5:1f4:cafe::a2) by DM6PR02CA0084.outlook.office365.com (2603:10b6:5:1f4::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6298.47 via Frontend Transport; Tue, 18 Apr 2023 07:16:27 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by DM6NAM11FT088.mail.protection.outlook.com (10.13.172.147) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6319.20 via Frontend Transport; Tue, 18 Apr 2023 07:16:27 +0000 Received: from TPE-L1-ABNCHANG.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.34; Tue, 18 Apr 2023 02:16:24 -0500 From: "Chang, Abner" To: CC: Isaac Oram , Abdul Lateef Attar , Nickle Wang , Igor Kulchytskyy Subject: [edk2-platforms][PATCH V2 11/14] ManageabilityPkg/PldmProtocol: Add PLDM protocol Date: Tue, 18 Apr 2023 15:15:40 +0800 Message-ID: <20230418071543.1951-12-abner.chang@amd.com> X-Mailer: git-send-email 2.37.1.windows.1 In-Reply-To: <20230418071543.1951-1-abner.chang@amd.com> References: <20230418071543.1951-1-abner.chang@amd.com> MIME-Version: 1.0 Return-Path: Abner.Chang@amd.com X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DM6NAM11FT088:EE_|DS0PR12MB6581:EE_ X-MS-Office365-Filtering-Correlation-Id: 32a100e3-77bf-4c3e-f983-08db3fdcd333 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: LLfkM+hrZFGshmgBJj6mpvHz0rTMZy4uELpWIovOcrqfWkxdwUOmEk1XI8J8VrsvM67opoUMhgs4nSeXt5mEupS3Cm2fbndn6Sqvw3X0P8xEKAjvg3bhN1fOmmVpC4cu6zirKhmPjy/Kd4RAX/Fb2qcnXCIN+Px2Hu+o5bGLQsxRLxfqjxi+/3GJaOlfSxB/1j9YgD528k9TO5gL9nyM6Qhs+eG/eFal68lUIjCQnUZmVGyZExXhY43x/ePzK8gMYtOZEVuDiDAiLX8HlPIhWcjgS6vqIM6W3tQzpNGWWuR6akNg8FvcLRO1Rw6xanJ60rxE/LIbR4R1hOoyr1EF/Kln7ZnqyW0onfwcZIFrV0fml9Ans2fVEBmbu4h9Iy/ZhxxZTi4zZO3VSD91oNH1qK1cnRjKzp90nwQo+KFlvR2S7T69q1z4tLMOfzeeKMJdDa+0j1lVxE6aeDrOHJ6hjK1b070lnHTtSd9BGSxZNuEw8rRn5ptiJJ5ctihZgtHfPKz8mx8mkPVPGDbt7mTNbTfLb3izDdFyw3jIRTYHOwecn4iRwQZIFl3QFerTJxsmXyLq68+gQCfu8H6p+FgkVc20PTOcVPvfXx9rwpT0RZ82ZjQ2isRaE3fnbfatutp6Vw4XZttvQXrM6qwwfK+/uI0LEN66VUPQlll5TIG1rt2EaX1d81BG44t/vwjtxZ4aEV0j65mjDg3aDeB7DPNLgnSCN30oOUnvRnX4BAU9JsGEKR4AQCMbF1Icqsn7Vve4U/hJrL2Hg7rs0jB6wTVAHw== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230028)(4636009)(39860400002)(376002)(346002)(136003)(396003)(451199021)(40470700004)(46966006)(36840700001)(356005)(82740400003)(7696005)(6666004)(40460700003)(2876002)(54906003)(2906002)(19627235002)(81166007)(478600001)(40480700001)(83380400001)(426003)(336012)(47076005)(186003)(2616005)(16526019)(26005)(82310400005)(36860700001)(36756003)(30864003)(4326008)(5660300002)(70586007)(316002)(1076003)(6916009)(70206006)(86362001)(41300700001)(8676002)(8936002)(36900700001)(44824005);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Apr 2023 07:16:27.1029 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 32a100e3-77bf-4c3e-f983-08db3fdcd333 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DM6NAM11FT088.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS0PR12MB6581 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain From: Abner Chang PldmProtocol that transmits PLDM message over manageability transport interface library. Signed-off-by: Abner Chang Cc: Isaac Oram Cc: Abdul Lateef Attar Cc: Nickle Wang Cc: Igor Kulchytskyy --- .../Include/Dsc/Manageability.dsc | 1 + .../PldmProtocol/Dxe/PldmProtocolDxe.inf | 50 ++ .../PldmProtocol/Common/PldmProtocolCommon.h | 109 +++++ .../PldmProtocol/Common/PldmProtocolCommon.c | 437 ++++++++++++++++++ .../Universal/PldmProtocol/Dxe/PldmProtocol.c | 181 ++++++++ 5 files changed, 778 insertions(+) create mode 100644 Features/ManageabilityPkg/Universal/PldmProtocol/Dxe/Pl= dmProtocolDxe.inf create mode 100644 Features/ManageabilityPkg/Universal/PldmProtocol/Common= /PldmProtocolCommon.h create mode 100644 Features/ManageabilityPkg/Universal/PldmProtocol/Common= /PldmProtocolCommon.c create mode 100644 Features/ManageabilityPkg/Universal/PldmProtocol/Dxe/Pl= dmProtocol.c diff --git a/Features/ManageabilityPkg/Include/Dsc/Manageability.dsc b/Feat= ures/ManageabilityPkg/Include/Dsc/Manageability.dsc index 17f067c6d0..0fab562844 100644 --- a/Features/ManageabilityPkg/Include/Dsc/Manageability.dsc +++ b/Features/ManageabilityPkg/Include/Dsc/Manageability.dsc @@ -32,6 +32,7 @@ =20 [Components.X64] ManageabilityPkg/Universal/IpmiProtocol/Smm/IpmiProtocolSmm.inf + ManageabilityPkg/Universal/PldmProtocol/Dxe/PldmProtocolDxe.inf ManageabilityPkg/Universal/PldmSmbiosTransferDxe/PldmSmbiosTransferDxe.i= nf ManageabilityPkg/Universal/MctpProtocol/Dxe/MctpProtocolDxe.inf =20 diff --git a/Features/ManageabilityPkg/Universal/PldmProtocol/Dxe/PldmProto= colDxe.inf b/Features/ManageabilityPkg/Universal/PldmProtocol/Dxe/PldmProto= colDxe.inf new file mode 100644 index 0000000000..006f77b09a --- /dev/null +++ b/Features/ManageabilityPkg/Universal/PldmProtocol/Dxe/PldmProtocolDxe.= inf @@ -0,0 +1,50 @@ +## @file +# EDKII PLDM Pootocol module INF file. +# +# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x0001001d + BASE_NAME =3D PldmProtocolDxe + FILE_GUID =3D DA83FBDC-ECFE-4094-9ED3-EAFD1342333F + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D DxePldmProtocolEntry + UNLOAD_IMAGE =3D PldmProtocolUnloadImage + +# +# VALID_ARCHITECTURES =3D IA32 X64 ARM AARCH64 +# + +[Sources] + PldmProtocol.c + ../Common/PldmProtocolCommon.c + ../Common/PldmProtocolCommon.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ManageabilityPkg/ManageabilityPkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + ManageabilityTransportHelperLib + ManageabilityTransportLib + UefiDriverEntryPoint + UefiBootServicesTableLib + +[Guids] + gManageabilityTransportMctpGuid + +[Protocols] + gEdkiiPldmProtocolGuid + +[FixedPcd] + gManageabilityPkgTokenSpaceGuid.PcdMctpSourceEndpointId + gManageabilityPkgTokenSpaceGuid.PcdMctpDestinationEndpointId + +[Depex] + TRUE diff --git a/Features/ManageabilityPkg/Universal/PldmProtocol/Common/PldmPr= otocolCommon.h b/Features/ManageabilityPkg/Universal/PldmProtocol/Common/Pl= dmProtocolCommon.h new file mode 100644 index 0000000000..231d6e802e --- /dev/null +++ b/Features/ManageabilityPkg/Universal/PldmProtocol/Common/PldmProtocolC= ommon.h @@ -0,0 +1,109 @@ +/** @file + + EDKII PLDM Protocol common header file. + + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef MANAGEABILITY_EDKII_PLDM_COMMON_H_ +#define MANAGEABILITY_EDKII_PLDM_COMMON_H_ + +#include +#include + +typedef struct { + UINT8 PldmType; + UINT8 PldmCommand; + UINT32 ResponseSize; +} PLDM_MESSAGE_PACKET_MAPPING; + +/** + This functions setup the PLDM transport hardware information according + to the specification of transport token acquired from transport library. + + @param[in] TransportToken The transport interface. + @param[out] HardwareInformation Pointer to receive the hardware = information. + + @retval EFI_SUCCESS Hardware information is returned in Hardw= areInformation. + Caller must free the memory allocated for= HardwareInformation + once it doesn't need it. + @retval EFI_UNSUPPORTED No hardware information for the specifica= tion specified + in the transport token. +**/ +EFI_STATUS +SetupPldmTransportHardwareInformation ( + IN MANAGEABILITY_TRANSPORT_TOKEN *TransportToken, + OUT MANAGEABILITY_TRANSPORT_HARDWARE_INFORMATION *HardwareInformation + ); + +/** + This functions setup the final header/body/trailer packets for + the acquired transport interface. + + @param[in] TransportToken The transport interface. + @param[in] PldmType PLDM message type. + @param[in] PldmCommand PLDM command of this PLDM type. + @param[out] PacketHeader The pointer to receive header of r= equest. + @param[out] PacketHeaderSize Packet header size in bytes. + @param[in, out] PacketBody The request body. + When IN, it is the caller's reques= t body. + When OUT and NULL, the request bod= y is not + changed. + Whee out and non-NULL, the request= body is + changed to comfort the transport i= nterface. + @param[in, out] PacketBodySize The request body size. + When IN and non-zero, it is the ne= w data + length of request body. + When IN and zero, the request body= is unchanged. + @param[out] PacketTrailer The pointer to receive trailer of = request. + @param[out] PacketTrailerSize Packet trailer size in bytes. + + @retval EFI_SUCCESS Request packet is returned. + @retval EFI_UNSUPPORTED Request packet is not returned because + the unsupported transport interface. +**/ +EFI_STATUS +SetupPldmRequestTransportPacket ( + IN MANAGEABILITY_TRANSPORT_TOKEN *TransportToken, + IN UINT8 PldmType, + IN UINT8 PldmCommand, + OUT MANAGEABILITY_TRANSPORT_HEADER *PacketHeader, + OUT UINT16 *PacketHeaderSize, + IN OUT UINT8 **PacketBody, + IN OUT UINT32 *PacketBodySize, + OUT MANAGEABILITY_TRANSPORT_TRAILER *PacketTrailer, + OUT UINT16 *PacketTrailerSize + ); + +/** + Common code to submit PLDM commands + + @param[in] TransportToken Transport token. + @param[in] PldmType PLDM message type. + @param[in] PldmCommand PLDM command of this PLDM type. + @param[in] RequestData Command Request Data. + @param[in] RequestDataSize Size of Command Request Data. + @param[out] ResponseData Command Response Data. The completi= on code is the first byte of response data. + @param[in, out] ResponseDataSize Size of Command Response Data. + + @retval EFI_SUCCESS The command byte stream was successfully = submit to the device and a response was successfully received. + @retval EFI_NOT_FOUND The command was not successfully sent to = the device or a response was not successfully received from the device. + @retval EFI_NOT_READY PLDM transport interface is not ready for= PLDM command access. + @retval EFI_DEVICE_ERROR PLDM 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 resourc= e or data size error. +**/ +EFI_STATUS +CommonPldmSubmitCommand ( + IN MANAGEABILITY_TRANSPORT_TOKEN *TransportToken, + IN UINT8 PldmType, + IN UINT8 PldmCommand, + IN UINT8 *RequestData OPTIONAL, + IN UINT32 RequestDataSize, + OUT UINT8 *ResponseData OPTIONAL, + IN OUT UINT32 *ResponseDataSize + ); + +#endif // MANAGEABILITY_EDKII_PLDM_COMMON_H_ diff --git a/Features/ManageabilityPkg/Universal/PldmProtocol/Common/PldmPr= otocolCommon.c b/Features/ManageabilityPkg/Universal/PldmProtocol/Common/Pl= dmProtocolCommon.c new file mode 100644 index 0000000000..bb4d3f61a0 --- /dev/null +++ b/Features/ManageabilityPkg/Universal/PldmProtocol/Common/PldmProtocolC= ommon.c @@ -0,0 +1,437 @@ +/** @file + + IPMI Manageability Protocol common file. + + 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 +#include +#include "PldmProtocolCommon.h" + +extern CHAR16 *mTransportName; +extern UINT8 mPldmRequestInstanceId; + +PLDM_MESSAGE_PACKET_MAPPING PldmMessagePacketMappingTable[] =3D { + { PLDM_TYPE_SMBIOS, PLDM_GET_SMBIOS_STRUCTURE_TABLE_METADATA_COMMAND_COD= E, sizeof (PLDM_GET_SMBIOS_STRUCTURE_TABLE_METADATA_RESPONSE_FORMAT) }, + { PLDM_TYPE_SMBIOS, PLDM_SET_SMBIOS_STRUCTURE_TABLE_METADATA_COMMAND_COD= E, sizeof (PLDM_SET_SMBIOS_STRUCTURE_TABLE_METADATA_RESPONSE_FORMAT) }, + { PLDM_TYPE_SMBIOS, PLDM_SET_SMBIOS_STRUCTURE_TABLE_COMMAND_CODE, = sizeof (PLDM_SET_SMBIOS_STRUCTURE_TABLE_REQUEST_FORMAT) } +}; + +/** + This function returns the expected full size of PLDM response message. + + @param[in] PldmType PLDM message type. + @param[in] PldmCommand PLDM command of this PLDM type. + + @retval Zero No matched entry for this PldmType/PldmCommand. + @retval None-zero Size of full packet is returned. +**/ +UINT32 +GetFullPacketResponseSize ( + IN UINT8 PldmType, + IN UINT8 PldmCommand + ) +{ + INT16 Index; + PLDM_MESSAGE_PACKET_MAPPING *ThisEntry; + + ThisEntry =3D PldmMessagePacketMappingTable; + for (Index =3D 0; Index < (sizeof (PldmMessagePacketMappingTable)/ sizeo= f (PLDM_MESSAGE_PACKET_MAPPING)); Index++) { + if ((PldmType =3D=3D ThisEntry->PldmType) && (PldmCommand =3D=3D ThisE= ntry->PldmCommand)) { + return ThisEntry->ResponseSize; + } + + ThisEntry++; + } + + return 0; +} + +/** + This functions setup the final header/body/trailer packets for + the acquired transport interface. + + @param[in] TransportToken The transport interface. + @param[in] PldmType PLDM message type. + @param[in] PldmCommand PLDM command of this PLDM type. + @param[out] PacketHeader The pointer to receive header of r= equest. + @param[out] PacketHeaderSize Packet header size in bytes. + @param[in, out] PacketBody The request body. + When IN, it is the caller's reques= t body. + When OUT and NULL, the request bod= y is not + changed. + Whee out and non-NULL, the request= body is + changed to comfort the transport i= nterface. + @param[in, out] PacketBodySize The request body size. + When IN and non-zero, it is the ne= w data + length of request body. + When IN and zero, the request body= is unchanged. + @param[out] PacketTrailer The pointer to receive trailer of = request. + @param[out] PacketTrailerSize Packet trailer size in bytes. + + @retval EFI_SUCCESS Request packet is returned. + @retval EFI_UNSUPPORTED Request packet is not returned because + the unsupported transport interface. +**/ +EFI_STATUS +SetupPldmRequestTransportPacket ( + IN MANAGEABILITY_TRANSPORT_TOKEN *TransportToken, + IN UINT8 PldmType, + IN UINT8 PldmCommand, + OUT MANAGEABILITY_TRANSPORT_HEADER *PacketHeader, + OUT UINT16 *PacketHeaderSize, + IN OUT UINT8 **PacketBody, + IN OUT UINT32 *PacketBodySize, + OUT MANAGEABILITY_TRANSPORT_TRAILER *PacketTrailer, + OUT UINT16 *PacketTrailerSize + ) +{ + MANAGEABILITY_MCTP_TRANSPORT_HEADER *MctpHeader; + PLDM_REQUEST_HEADER *PldmRequestHeader; + + if ((PacketHeader =3D=3D NULL) || (PacketHeaderSize =3D=3D NULL) || + (PacketBody =3D=3D NULL) || (PacketBodySize =3D=3D NULL) || + (PacketTrailer =3D=3D NULL) || (PacketTrailerSize =3D=3D NULL) + ) + { + DEBUG ((DEBUG_ERROR, "%a: One or more than one of the required paramet= ers is NULL.\n", __FUNCTION__)); + return EFI_INVALID_PARAMETER; + } + + if (CompareGuid (&gManageabilityTransportMctpGuid, TransportToken->Trans= port->ManageabilityTransportSpecification)) { + DEBUG ((DEBUG_MANAGEABILITY_INFO, "%a: Setup transport header for PLDM= over MCTP.\n", __FUNCTION__)); + + // This is MCTP transport interface. + MctpHeader =3D AllocateZeroPool (sizeof (MANAGEABILITY_MCTP_TRANSPORT_= HEADER)); + if (MctpHeader =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: Not enough memory for MANAGEABILITY_MCTP_T= RANSPORT_HEADER.\n", __FUNCTION__)); + return EFI_OUT_OF_RESOURCES; + } + + MctpHeader->SourceEndpointId =3D PcdGet8 (PcdMctpSourceEnd= pointId); + MctpHeader->SourceEndpointId =3D PcdGet8 (PcdMctpDestinati= onEndpointId); + MctpHeader->MessageHeader.IntegrityCheck =3D FALSE; + MctpHeader->MessageHeader.MessageType =3D MCTP_MESSAGE_TYPE_PLDM; + *PacketHeader =3D (MANAGEABILITY_TRANSPORT_= HEADER *)MctpHeader; + *PacketHeaderSize =3D sizeof (MANAGEABILITY_TRA= NSPORT_HEADER); + *PacketTrailer =3D NULL; + *PacketTrailerSize =3D 0; + } else { + DEBUG ((DEBUG_ERROR, "%a: No implementation of building up packet.\n",= __FUNCTION__)); + ASSERT (FALSE); + } + + // + // Create header for the final request message. + // + PldmRequestHeader =3D (PLDM_REQUEST_HEADER *)AllocateZeroPool (sizeof (P= LDM_REQUEST_HEADER) + *PacketBodySize); + if (PldmRequestHeader =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: Not enough memory for final PLDM request mes= sage.\n", __FUNCTION__)); + return EFI_OUT_OF_RESOURCES; + } + + PldmRequestHeader->RequestBit =3D PLDM_MESSAGE_HEADER_IS_REQUES= T; + PldmRequestHeader->HeaderVersion =3D PLDM_MESSAGE_HEADER_VERSION; + PldmRequestHeader->PldmType =3D PldmType; + PldmRequestHeader->PldmTypeCommandCode =3D PldmCommand; + PldmRequestHeader->InstanceId =3D mPldmRequestInstanceId; + if ((*PacketBody !=3D NULL) && (*PacketBodySize !=3D 0)) { + CopyMem ( + (VOID *)((UINT8 *)PldmRequestHeader + sizeof (PLDM_REQUEST_HEADER)), + (VOID *)*PacketBody, + *PacketBodySize + ); + } + + *PacketBody =3D (UINT8 *)PldmRequestHeader; + *PacketBodySize =3D sizeof (PLDM_REQUEST_HEADER) + *PacketBodySize; + return EFI_SUCCESS; +} + +/** + Common code to submit PLDM commands + + @param[in] TransportToken Transport token. + @param[in] PldmType PLDM message type. + @param[in] PldmCommand PLDM command of this PLDM type. + @param[in] RequestData Command Request Data. + @param[in] RequestDataSize Size of Command Request Data. + @param[out] ResponseData Command Response Data. The completi= on code is the first byte of response data. + @param[in, out] ResponseDataSize Size of Command Response Data. + + @retval EFI_SUCCESS The command byte stream was successfully = submit to the device and a response was successfully received. + @retval EFI_NOT_FOUND The command was not successfully sent to = the device or a response was not successfully received from the device. + @retval EFI_NOT_READY Ipmi Device is not ready for Ipmi command= access. + @retval EFI_DEVICE_ERROR Ipmi Device hardware error. + @retval EFI_TIMEOUT The command time out. + @retval EFI_UNSUPPORTED The command was not successfully sent to = the device. + @retval EFI_OUT_OF_RESOURCES The resource allocation is out of resourc= e or data size error. +**/ +EFI_STATUS +CommonPldmSubmitCommand ( + IN MANAGEABILITY_TRANSPORT_TOKEN *TransportToken, + IN UINT8 PldmType, + IN UINT8 PldmCommand, + IN UINT8 *RequestData OPTIONAL, + IN UINT32 RequestDataSize, + OUT UINT8 *ResponseData OPTIONAL, + IN OUT UINT32 *ResponseDataSize + ) +{ + EFI_STATUS Status; + UINT8 *ThisRequestData; + UINT32 ThisRequestDataSize; + MANAGEABILITY_TRANSFER_TOKEN TransferToken; + MANAGEABILITY_TRANSPORT_HEADER PldmTransportHeader; + MANAGEABILITY_TRANSPORT_TRAILER PldmTransportTrailer; + MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS TransportAdditionalStatus; + UINT8 *FullPacketResponseData; + UINT32 FullPacketResponseDataSize; + PLDM_RESPONSE_HEADER *ResponseHeader; + UINT16 HeaderSize; + UINT16 TrailerSize; + + if (TransportToken =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: No transport token for PLDM\n", __FUNCTION__= )); + return EFI_UNSUPPORTED; + } + + Status =3D TransportToken->Transport->Function.Version1_0->TransportStat= us ( + TransportToke= n, + &TransportAdd= itionalStatus + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Transport %s for PLDM has problem - (%r)\n",= __FUNCTION__, mTransportName, Status)); + return Status; + } + + ThisRequestData =3D RequestData; // Save the original request= data because the request data maybe modified + // in SetupIpmiRequestTranspor= tPacket() according to transport interface. + ThisRequestDataSize =3D RequestDataSize; // Save the original request= data size because the request data size maybe modified + // in SetupIpmiRequestTranspo= rtPacket() according to transport interface. + PldmTransportHeader =3D NULL; + PldmTransportTrailer =3D NULL; + Status =3D SetupPldmRequestTransportPacket ( + TransportToken, + PldmType, + PldmCommand, + &PldmTransportHeader, + &HeaderSize, + &ThisRequestData, + &ThisRequestDataSize, + &PldmTransportTrailer, + &TrailerSize + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to build packets - (%r)\n", __FUNCTION_= _, Status)); + return Status; + } + + ZeroMem (&TransferToken, sizeof (MANAGEABILITY_TRANSFER_TOKEN)); + TransferToken.TransmitHeader =3D PldmTransportHeader; + TransferToken.TransmitHeaderSize =3D HeaderSize; + TransferToken.TransmitTrailer =3D PldmTransportTrailer; + TransferToken.TransmitTrailerSize =3D TrailerSize; + + // Transmit packet. + if ((ThisRequestData =3D=3D NULL) || (ThisRequestDataSize =3D=3D 0)) { + // Transmit parameter were not changed by SetupIpmiRequestTransportPac= ket(). + TransferToken.TransmitPackage.TransmitPayload =3D RequestData; + TransferToken.TransmitPackage.TransmitSizeInByte =3D ThisRequestDataSi= ze; + } else { + // Transmit parameter were changed by SetupIpmiRequestTransportPacket(= ). + TransferToken.TransmitPackage.TransmitPayload =3D ThisRequestData; + TransferToken.TransmitPackage.TransmitSizeInByte =3D ThisRequestDataSi= ze; + } + + TransferToken.TransmitPackage.TransmitTimeoutInMillisecond =3D MANAGEABI= LITY_TRANSPORT_NO_TIMEOUT; + + // Set receive packet. + FullPacketResponseDataSize =3D GetFullPacketResponseSize (PldmType, Pldm= Command); + if (FullPacketResponseDataSize =3D=3D 0) { + DEBUG ((DEBUG_ERROR, " No mapping entry in PldmMessagePacketMappingTa= ble for PLDM Type:%d Command %d\n", PldmType, PldmCommand)); + ASSERT (FALSE); + } + + FullPacketResponseData =3D (UINT8 *)AllocateZeroPool (FullPacketResponse= DataSize); + if (FullPacketResponseData =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, " Not enough memory for FullPacketResponseDataSi= ze.\n")); + Status =3D EFI_OUT_OF_RESOURCES; + goto ErrorExit2; + } + + // Print out PLDM packet. + DEBUG (( + DEBUG_MANAGEABILITY_INFO, + "%a: Send PLDM type: 0x%x, Command: 0x%x: Request size: 0x%x, Response= size: 0x%x\n", + __FUNCTION__, + PldmType, + PldmCommand, + TransferToken.TransmitPackage.TransmitSizeInByte, + FullPacketResponseDataSize + )); + + HelperManageabilityDebugPrint ( + (VOID *)TransferToken.TransmitPackage.TransmitPayload, + TransferToken.TransmitPackage.TransmitSizeInByte, + "PLDM full request payload.\n" + ); + + TransferToken.ReceivePackage.ReceiveBuffer =3D FullPacket= ResponseData; + TransferToken.ReceivePackage.ReceiveSizeInByte =3D FullPacket= ResponseDataSize; + TransferToken.ReceivePackage.TransmitTimeoutInMillisecond =3D MANAGEABIL= ITY_TRANSPORT_NO_TIMEOUT; + TransportToken->Transport->Function.Version1_0->TransportTransmitReceive= ( + TransportToken, + &TransferToken + ); + // + // Check the response size. + if (TransferToken.ReceivePackage.ReceiveSizeInByte < sizeof (PLDM_RESPON= SE_HEADER)) { + DEBUG (( + DEBUG_MANAGEABILITY_INFO, + "Invalid response header size of PLDM Type %d Command %d, Returned s= ize: %d Expected size: %d\n", + PldmType, + PldmCommand, + TransferToken.ReceivePackage.ReceiveSizeInByte, + FullPacketResponseDataSize + )); + if (ResponseDataSize !=3D NULL) { + if (*ResponseDataSize > TransferToken.ReceivePackage.ReceiveSizeInBy= te) { + *ResponseDataSize =3D TransferToken.ReceivePackage.ReceiveSizeInBy= te; + } + } + + if (ResponseData !=3D NULL) { + CopyMem ((VOID *)ResponseData, (VOID *)FullPacketResponseData, *Resp= onseDataSize); + } + + goto ErrorExit; + } + + // + // Check the integrity of response. data. + ResponseHeader =3D (PLDM_RESPONSE_HEADER *)FullPacketResponseData; + if ((ResponseHeader->PldmHeader.DatagramBit !=3D 0) || + (ResponseHeader->PldmHeader.RequestBit !=3D 0) || + (ResponseHeader->PldmHeader.InstanceId !=3D mPldmRequestInstanceId) = || + (ResponseHeader->PldmHeader.PldmType !=3D PldmType) || + (ResponseHeader->PldmHeader.PldmTypeCommandCode !=3D PldmCommand)) + { + DEBUG ((DEBUG_ERROR, "PLDM integrity check of response data is failed.= \n")); + DEBUG ((DEBUG_ERROR, " Request bit =3D %d (Expected value: 0)\n"))= ; + DEBUG ((DEBUG_ERROR, " Datagram =3D %d (Expected value: 0)\n"))= ; + DEBUG ((DEBUG_ERROR, " Instance ID =3D %d (Expected value: %d)\n",= ResponseHeader->PldmHeader.InstanceId, mPldmRequestInstanceId)); + DEBUG ((DEBUG_ERROR, " Pldm Type =3D %d (Expected value: %d)\n",= ResponseHeader->PldmHeader.PldmType, PldmType)); + DEBUG ((DEBUG_ERROR, " Pldm Command =3D %d (Expected value: %d)\n",= ResponseHeader->PldmHeader.PldmTypeCommandCode, PldmCommand)); + if (ResponseDataSize !=3D NULL) { + if (*ResponseDataSize > TransferToken.ReceivePackage.ReceiveSizeInBy= te) { + *ResponseDataSize =3D TransferToken.ReceivePackage.ReceiveSizeInBy= te; + } + } + + if (ResponseData !=3D NULL) { + CopyMem ((VOID *)ResponseData, (VOID *)FullPacketResponseData, *Resp= onseDataSize); + } + + goto ErrorExit; + } + + // + // Check the response size + if (TransferToken.ReceivePackage.ReceiveSizeInByte !=3D FullPacketRespon= seDataSize) { + DEBUG (( + DEBUG_ERROR, + "The response size is incorrect: Response size %d (Expected %d), Com= pletion code %d.\n", + TransferToken.ReceivePackage.ReceiveSizeInByte, + FullPacketResponseDataSize, + ResponseHeader->PldmCompletionCode + )); + if (ResponseDataSize !=3D NULL) { + if (*ResponseDataSize > TransferToken.ReceivePackage.ReceiveSizeInBy= te) { + *ResponseDataSize =3D TransferToken.ReceivePackage.ReceiveSizeInBy= te; + } + } + + if (ResponseData !=3D NULL) { + CopyMem ((VOID *)ResponseData, (VOID *)FullPacketResponseData, *Resp= onseDataSize); + } + + goto ErrorExit; + } + + if (*ResponseDataSize !=3D (TransferToken.ReceivePackage.ReceiveSizeInBy= te - sizeof (PLDM_RESPONSE_HEADER))) { + DEBUG ((DEBUG_ERROR, " The size of response is not matched to Request= DataSize assigned by caller.\n")); + DEBUG (( + DEBUG_ERROR, + "Caller expects %d, the response size minus PLDM_RESPONSE_HEADER siz= e is %d, Completion Code %d.\n", + *ResponseDataSize, + TransferToken.ReceivePackage.ReceiveSizeInByte - sizeof (PLDM_RESPON= SE_HEADER), + ResponseHeader->PldmCompletionCode + )); + if (ResponseDataSize !=3D NULL) { + if (*ResponseDataSize > TransferToken.ReceivePackage.ReceiveSizeInBy= te) { + *ResponseDataSize =3D TransferToken.ReceivePackage.ReceiveSizeInBy= te; + } + } + + if (ResponseData !=3D NULL) { + CopyMem ((VOID *)ResponseData, (VOID *)FullPacketResponseData, *Resp= onseDataSize); + } + + goto ErrorExit; + } + + // Print out PLDM full responses payload. + HelperManageabilityDebugPrint ((VOID *)FullPacketResponseData, FullPacke= tResponseDataSize, "PLDM full response payload\n"); + + // Copy response data (without header) to caller's buffer. + if ((ResponseData !=3D NULL) && (*ResponseDataSize !=3D 0)) { + *ResponseDataSize =3D FullPacketResponseDataSize - sizeof (PLDM_RESPON= SE_HEADER); + CopyMem ( + (VOID *)ResponseData, + (VOID *)(FullPacketResponseData + sizeof (PLDM_RESPONSE_HEADER)), + *ResponseDataSize + ); + } + + // Return transfer status. + // +ErrorExit: + Status =3D TransferToken.TransferStatus; + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to send PLDM command over %s\n", __FU= NCTION__, mTransportName)); + } + +ErrorExit2: + if (PldmTransportHeader !=3D NULL) { + FreePool ((VOID *)PldmTransportHeader); + } + + if (PldmTransportTrailer !=3D NULL) { + FreePool ((VOID *)PldmTransportTrailer); + } + + if (ThisRequestData !=3D NULL) { + FreePool ((VOID *)ThisRequestData); + } + + if (FullPacketResponseData !=3D NULL) { + FreePool ((VOID *)FullPacketResponseData); + } + + // + // Update PLDM message instance ID. + mPldmRequestInstanceId++; + mPldmRequestInstanceId &=3D PLDM_MESSAGE_HEADER_INSTANCE_ID_MASK; + return Status; +} diff --git a/Features/ManageabilityPkg/Universal/PldmProtocol/Dxe/PldmProto= col.c b/Features/ManageabilityPkg/Universal/PldmProtocol/Dxe/PldmProtocol.c new file mode 100644 index 0000000000..bb34fec16e --- /dev/null +++ b/Features/ManageabilityPkg/Universal/PldmProtocol/Dxe/PldmProtocol.c @@ -0,0 +1,181 @@ +/** @file + This file provides edk2 PLDM SMBIOS Transfer Protocol implementation. + + 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 + +#include "PldmProtocolCommon.h" + +MANAGEABILITY_TRANSPORT_TOKEN *mTransportToken =3D NULL; +CHAR16 *mTransportName; +UINT8 mPldmRequestInstanceId; +UINT32 TransportMaximumPayload; + +/** + This service enables submitting commands via EDKII PLDM protocol. + + @param[in] This EDKII_PLDM_PROTOCOL instance. + @param[in] PldmType PLDM message type. + @param[in] Command PLDM Command of PLDM message type. + @param[in] RequestData Command Request Data. + @param[in] RequestDataSize Size of Command Request Data. + @param[out] ResponseData Command Response Data. The completi= on code is the first byte of response data. + @param[in, out] ResponseDataSize Size of Command Response Data. + + @retval EFI_SUCCESS The command byte stream was successfully = submit to the device and a response was successfully received. + @retval EFI_NOT_FOUND The command was not successfully sent to = the device or a response was not successfully received from the device. + @retval EFI_NOT_READY PLDM transport interface is not ready for= PLDM command access. + @retval EFI_DEVICE_ERROR PLDM transport interface 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 resourc= e or data size error. + @retval EFI_INVALID_PARAMETER Both RequestData and ResponseData are NUL= L +**/ +EFI_STATUS +EFIAPI +PldmSubmitCommand ( + IN EDKII_PLDM_PROTOCOL *This, + IN UINT8 PldmType, + IN UINT8 Command, + IN UINT8 *RequestData, + IN UINT32 RequestDataSize, + OUT UINT8 *ResponseData, + IN OUT UINT32 *ResponseDataSize + ) +{ + EFI_STATUS Status; + + if ((RequestData =3D=3D NULL) && (ResponseData =3D=3D NULL)) { + DEBUG ((DEBUG_ERROR, "%a: Both RequestData and ResponseData are NULL\n= ", __FUNCTION__)); + return EFI_INVALID_PARAMETER; + } + + Status =3D CommonPldmSubmitCommand ( + mTransportToken, + PldmType, + Command, + RequestData, + RequestDataSize, + ResponseData, + ResponseDataSize + ); + return Status; +} + +EDKII_PLDM_PROTOCOL_V1_0 mPldmProtocolV10 =3D { + PldmSubmitCommand +}; + +EDKII_PLDM_PROTOCOL mPldmProtocol; + +/** + The entry point of the PLDM SMBIOS Transfer DXE driver. + + @param[in] ImageHandle - Handle of this driver image + @param[in] SystemTable - Table containing standard EFI services + + @retval EFI_SUCCESS - PLDM Protocol is installed successfully. + @retval Otherwise - Other errors. +**/ +EFI_STATUS +EFIAPI +DxePldmProtocolEntry ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + MANAGEABILITY_TRANSPORT_CAPABILITY TransportCapability; + MANAGEABILITY_TRANSPORT_ADDITIONAL_STATUS TransportAdditionalStatus; + MANAGEABILITY_TRANSPORT_HARDWARE_INFORMATION HardwareInfo; + + Status =3D HelperAcquireManageabilityTransport ( + &gManageabilityProtocolPldmGuid, + &mTransportToken + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to acquire transport interface for PL= DM protocol - %r\n", __FUNCTION__, Status)); + return Status; + } + + Status =3D GetTransportCapability (mTransportToken, &TransportCapability= ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to GetTransportCapability().\n", __FU= NCTION__)); + return Status; + } + + TransportMaximumPayload =3D MANAGEABILITY_TRANSPORT_PAYLOAD_SIZE_FROM_CA= PABILITY (TransportCapability); + if (TransportMaximumPayload =3D=3D (1 << MANAGEABILITY_TRANSPORT_CAPABIL= ITY_MAXIMUM_PAYLOAD_NOT_AVAILABLE)) { + DEBUG ((DEBUG_MANAGEABILITY_INFO, "%a: Transport interface maximum pay= load is undefined.\n", __FUNCTION__)); + } else { + TransportMaximumPayload -=3D 1; + DEBUG ((DEBUG_MANAGEABILITY_INFO, "%a: Transport interface for PLDM pr= otocol has maximum payload 0x%x.\n", __FUNCTION__, TransportMaximumPayload)= ); + } + + mTransportName =3D HelperManageabilitySpecName (mTransportToken->Transpo= rt->ManageabilityTransportSpecification); + DEBUG ((DEBUG_MANAGEABILITY_INFO, "%a: PLDM protocol over %s.\n", __FUNC= TION__, mTransportName)); + + // Initial transport interface with the hardware information assigned. + HardwareInfo.Pointer =3D NULL; + Status =3D HelperInitManageabilityTransport ( + mTransportToken, + HardwareInfo, + &TransportAdditionalStatus + ); + if (EFI_ERROR (Status)) { + return Status; + } + + mPldmRequestInstanceId =3D 0; + mPldmProtocol.ProtocolVersion =3D EDKII_PLDM_PROTOCOL_VERSION; + mPldmProtocol.Functions.Version1_0 =3D &mPldmProtocolV10; + Handle =3D NULL; + Status =3D gBS->InstallProtocolInterface ( + &Handle, + &gEdkiiPldmProtocolGuid, + EFI_NATIVE_INTERFACE, + (VOID **)&mPldmProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to install EDKII PLDM protocol - %r\n= ", __FUNCTION__, Status)); + } + + return Status; +} + +/** + This is the unload handler of PLDM SMBIOS Transfer DXE driver. + + @param[in] ImageHandle The driver's image handle. + + @retval EFI_SUCCESS The image is unloaded. + @retval Others Failed to unload the image. + +**/ +EFI_STATUS +EFIAPI +PldmProtocolUnloadImage ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + + Status =3D EFI_SUCCESS; + if (mTransportToken !=3D NULL) { + Status =3D ReleaseTransportSession (mTransportToken); + } + + return Status; +} --=20 2.37.1.windows.1