From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-DM6-obe.outbound.protection.outlook.com (NAM10-DM6-obe.outbound.protection.outlook.com [40.107.93.66]) by mx.groups.io with SMTP id smtpd.web10.58103.1686574441625422729 for ; Mon, 12 Jun 2023 05:54:02 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@ami.com header.s=selector1 header.b=G5ndR36V; spf=pass (domain: ami.com, ip: 40.107.93.66, mailfrom: arunk@ami.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=OhS5o7CPqOO53WYvrzgxsriT6vkTKBbuWnNc931awQwkZ3gekO3tL/4d+DE83YnN0XYCos4cOTRgROq+RiMah7mw/F7nAvw2963MiXOg97zXsS44b4MT7iK6fRJNWjd3fQbWtCXxZlrxmGxHj78FaNUeS5Bm4rRfWKdzzpB41H3P3aGFx6/aF+O5mqZRu3BFPsKY3W+8UrRZAaq6dZNiCxZD6wOjLXRtm3CqUo/UGYnXvf4Lo+IosvSZHD/5XNvbgVqIXtsvwmmp793wQXRSCnMJSz15cMucAGHDd26uXfmcbefU4ol/FEgWNDxaZHqAJ4+cAiH9/hH+7mbbLOqHTg== 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=vPugYZ6Iw7jmpsGQR0RdmAOZKkjxNYoxEm2rEfqGr34=; b=Ok8hm3Su3XgPGcooVyOnBkUjf+r26qZNp+kK/yOGeTuNT6C3rHIi5xmcZSlMZ56NvTC+H0wfofxLTcPJrNZ2o3qoAnWl38t5oEEu38Vhs9lxApRE2SwUMO+CLHMWfJO0ZsyMbMQvyh/iMiBqHxULVp6AiCyfrVummIAriNB/msgTmNo4sYd+RZrARi+HkPTpcy7Z5fDgYcPkjGvDzF4yTHlzOCGgLPBMp4MIFV11ftQ+hrgWXQmxClorT8ifme0XFtPRBFPJ0OL2j6FSR9QSmye8lYLX2BD12z8F5OaN4+ysGKlOp3srvJO873nY1+CfvcsqS9TyRgsPwR+YuLY4Rg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=ami.com; dmarc=pass action=none header.from=ami.com; dkim=pass header.d=ami.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ami.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=vPugYZ6Iw7jmpsGQR0RdmAOZKkjxNYoxEm2rEfqGr34=; b=G5ndR36VOJqfaGntckOGT8twv9IJdnPWg3hndppyYexmQ5fxsK9XG/dGs73KR2K9LBVaxHa7Vv+lAE1FfC+qU+GC+hjnB7PI9UYiC+SHDhoeIDRYIhTyhBzyoWh0r7E+BhmEqTArMx8iwZ9G0kDh92ReRdsy08jRfBkG0fOzKNA= Received: from PH0PR10MB5403.namprd10.prod.outlook.com (2603:10b6:510:e3::17) by PH8PR10MB6453.namprd10.prod.outlook.com (2603:10b6:510:22f::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6455.44; Mon, 12 Jun 2023 12:53:55 +0000 Received: from PH0PR10MB5403.namprd10.prod.outlook.com ([fe80::720f:ab76:4f7d:a185]) by PH0PR10MB5403.namprd10.prod.outlook.com ([fe80::720f:ab76:4f7d:a185%5]) with mapi id 15.20.6455.030; Mon, 12 Jun 2023 12:53:55 +0000 From: "Arun K" To: "devel@edk2.groups.io" , Arun K CC: "isaac.w.oram@intel.com" , "nathaniel.l.desimone@intel.com" , Ramkumar Krishnamoorthi , Liming Gao Subject: [edk2-devel][edk2-platforms][PATCH V3-3] IpmiFeaturePkg:Provided multiple IPMI interface support in Library Thread-Topic: [edk2-devel][edk2-platforms][PATCH V3-3] IpmiFeaturePkg:Provided multiple IPMI interface support in Library Thread-Index: AQHZnSzyVcplYVU3hE2nUoZbLp4i0w== Date: Mon, 12 Jun 2023 12:53:55 +0000 Message-ID: <21b9dc3c5e81b4eba7bcb535d69b35d990590e5b.1686573103.git.arunk@ami.com> Accept-Language: en-GB, 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=ami.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: PH0PR10MB5403:EE_|PH8PR10MB6453:EE_ x-ms-office365-filtering-correlation-id: 2668c53b-34fe-41d9-acdf-08db6b4414f6 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: 2Gml1Qr5iqsCQXXzBjT7qJUMF2FmJu4dnfMDMxmfeKTQbD9+r+igwx6PiHme5MDtnX0GaacE6mLj/wFr8f/yR17m56Pdq417fRRe5DEPMARv93kdOggZO8np4LGB/24oK2Ao3bpwUGCtAVMPv1RNGlYyrc/79Eeot9SoYeG2ni2dLipsV0k+gAo3wPKDnYiSwYN24RV4JudBIFCLtCgTBXxacD0KpmhP2kbBpzMKnr31UHd+SuyK00g5nr2GZJe9bQo6SCSSQDNTfgFlC8pqP7J9oOQAB48wDELqLL4R+8bMgyCT+CU8j0mgU0YhUnZq2pWrtfLkef3SeeoQ0O2vUz4PZDgSSgHkaSDZdMyTv9oUNaGg8k7k+opbhRmOtWutJDrcbUdvl1lMw/RLLxc/Msb4Bl9GH1JiADRWyirZ3CQKsIRhPxOAt9bKMP7CHwEBXM3mAcFTaW3cMOcvLW39bXeWrBPG/AwvcLkuc5j/yyUuVPMTDHUt9UIOh878zk+wfI0axZvb0g9Cd4Usy48Xwcb4X27S/CYY/Wp8B36K3smweTb3kg9rhwC3iXWxLbitnVa1o+VtwoDKDLlf8oI419MbX0RemG14IorsA3jLgWu9ces51bSot43/JFexETVC63aXtispA6Kyxtau+fhDRw== x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH0PR10MB5403.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230028)(4636009)(136003)(376002)(39850400004)(366004)(396003)(346002)(451199021)(66899021)(2616005)(7049001)(83380400001)(186003)(6512007)(26005)(6506007)(122000001)(316002)(86362001)(76116006)(91956017)(4326008)(41300700001)(2906002)(5660300002)(64756008)(66446008)(66476007)(66556008)(38100700002)(66946007)(38070700005)(30864003)(478600001)(54906003)(19627235002)(40140700001)(36756003)(8676002)(8936002)(6486002)(110136005)(71200400001)(559001)(579004)(357404004);DIR:OUT;SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?iso-8859-1?Q?V7+Xy2Mimfr57dYLwoZy6+AOd8D3JYuQiRX9cQGqe44O9qRnQWNaoj8cuA?= =?iso-8859-1?Q?Y2G6JCiMoGqBRFyhzHfp5XR24w+piCegGAd1BbWO4DLT2NinoKaFXsqE+/?= =?iso-8859-1?Q?PKErhNTsbFcFZ3g4rCDwLf3W+E1WF/UzRPkbrEA0wppsj6NlpyiS9SDgWl?= =?iso-8859-1?Q?j826hzCmXc57vwI+eSocPeOK8xwRecpR+EIMZzk2qdhV/ZPKqBpsGpB+M2?= =?iso-8859-1?Q?o+QQhRLJTn1U5UDVEhYvPxwOeXg+BGII59TfX/9564CeMVINeSxNgS8Xfn?= =?iso-8859-1?Q?dLaEsn9n78yp2QNjtuDCBTJzV+Tfg6VY4EJCH8NvqFCYSNlEslDCLUB/sr?= =?iso-8859-1?Q?Q1z1S91DhMzmcX4EXvndanosO7T+N4YkukjSzK8St8EqGsW0iB0lhNg8va?= =?iso-8859-1?Q?Y+uEsOoxiEGxn7mtFwq590jaT7WUaJw8l0HiRlbkPpRYggFEhLYwhNnLy2?= =?iso-8859-1?Q?ZUQLn9LGfrqpGYAHBeILtp8SIdV7lC6RrAlAVYyemOeTtDFZAyuUHJSyOT?= =?iso-8859-1?Q?VeLWtSQVyu3qOu04FjReyue8EK6nkbzksAWc2fcV6AhL3JS3b6eirSmooT?= =?iso-8859-1?Q?2PYGjkdNsyGt2DRzKsgvvHurGUvq3IuPnj2ZA0tIZWyVsJaaVW11opTwUj?= =?iso-8859-1?Q?QZdb1CorMWIJKY48hG1ubo9Mkei3RMYAjxL/BKoSv1Qr0zrG/YHzIW/OCw?= =?iso-8859-1?Q?2Ll5RxBo3PDq5XWSZNJY9g0Bdos28qUE0qR+79HhzHimvz2mSCqW66TI08?= =?iso-8859-1?Q?Su7xUu7OPSY+6md7Yv+FNh7LHrgg/PghxVAxHcRG9w88Zyw5UpDkFVlPAh?= =?iso-8859-1?Q?/KKI4+uDTdUTVwtRRJOiLSYGZfx66SnG5ev3lrWNYeWmSDZneE4dPIPmnh?= =?iso-8859-1?Q?m41Mf1YzZCqL4lJHkNLnubPL85QtAXg4Iz6a8ya87Z53q1dwNKNsAiEbDS?= =?iso-8859-1?Q?1n24e59cZTqHm+AghvwpVayqYSinHxSFc3iX5gfPNjuRv5dabj0dPNfH1M?= =?iso-8859-1?Q?hl+6zRzk+2ypWLbQJltlR8VrXSwQRzWXBO8XjSGRGzLhnqpek9jUGj5CNk?= =?iso-8859-1?Q?KbYTqvYj5HXpP46Gsh82M6K7Zu0+Rxvp1yMd95taC6VpTFXW+Key5Pienz?= =?iso-8859-1?Q?uP9rZ9S0gcVARS1TulUOpTV1goGS3/jroXnIqa9F445tF1c0DhHRqISIMD?= =?iso-8859-1?Q?+wXHQahb7jve+tbKbzHsR8k5UbU5g3GP4tZFcctjVp2FyJS0zfrFFV1AnC?= =?iso-8859-1?Q?TDAb5EyD7iv6aPw3HPZJLxIdPnZiPcfrT/lVpTms7yBqVjC/Tp5JCB9TKM?= =?iso-8859-1?Q?9ZRsD5c6SI/RrPMcq03t6UPLYjsUuCJjHf8ReHRdmwDTs2i1vSI2MdIwkk?= =?iso-8859-1?Q?Qc23W56Y6VS18KpIoA1WELBPK2x9oTkFcqfdLg2Hv113XzTqyMQDB9d2Yf?= =?iso-8859-1?Q?P0Eruwt3UiY4r9HxBoXKL3ZI6dhbGe2kicsoYBk0RwgRGkEWC5+BBeAegA?= =?iso-8859-1?Q?fI26KivXQPY+z71HzvQaMWj0OdEOGWUkbhh3Xctmj3JcxpxllHpGsL5UUm?= =?iso-8859-1?Q?tC6CrMCAgJlina0bohDoAvKdAIDdYfFgWuCYUY+y431g2MAAKGlTaC44s8?= =?iso-8859-1?Q?os0r/+SQZ531esodqY++Bpr+optoBmjAue?= MIME-Version: 1.0 X-OriginatorOrg: ami.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: PH0PR10MB5403.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2668c53b-34fe-41d9-acdf-08db6b4414f6 X-MS-Exchange-CrossTenant-originalarrivaltime: 12 Jun 2023 12:53:55.6550 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 27e97857-e15f-486c-b58e-86c2b3040f93 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: KlsXh/RnwKE2uQclzOR1hFeNDbLDYGS5GT6gOdkmGuf+uLAg8g7SK6JDx/OPOiY3 X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH8PR10MB6453 Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Created IpmiTransport2 PPI/Protocol to support multiple IPMI BMC Interface support such as KCS/BT/SSIF with 2 API's IpmiSubmitCommand2 & IpmiSubmitCommand2Ex. IpmiSubmitCommand2 - This API use the default interface (PcdDefaultSystemInterface) to send IPMI command. IpmiSubmitCommand2Ex - This API use the specific interface type to send IPMI command which is passed as an argument. Cc: Isaac Oram Cc: Nate DeSimone Cc: Liming Gao Signed-off-by: Arun K --- .../GenericIpmi/Pei/PeiIpmiHooks.c | 351 +++++++++++ .../GenericIpmi/Pei/PeiIpmiHooks.h | 213 +++++++ .../Include/IpmiNetFnAppDefinitions.h | 239 ++++++++ .../Include/IpmiTransport2Definitions.h | 153 +++++ .../Include/Library/BmcCommonInterfaceLib.h | 200 ++++++ .../Include/Library/BtInterfaceLib.h | 83 +++ .../Include/Library/IpmbInterfaceLib.h | 92 +++ .../Include/Library/SsifInterfaceLib.h | 165 +++++ .../Include/Ppi/IpmiTransport2Ppi.h | 23 + .../Include/Protocol/IpmiTransport2Protocol.h | 30 + .../BmcCommonInterfaceLib.c | 228 +++++++ .../BmcCommonInterfaceLib.inf | 26 + .../BtInterfaceLib/BtInterfaceLib.c | 570 ++++++++++++++++++ .../BtInterfaceLib/BtInterfaceLib.inf | 39 ++ .../IpmbInterfaceLib/DxeIpmbInterfaceLib.c | 94 +++ .../IpmbInterfaceLib/DxeIpmbInterfaceLib.inf | 38 ++ .../IpmbInterfaceLib/IpmbInterfaceLibCommon.c | 351 +++++++++++ .../IpmbInterfaceLib/PeiIpmbInterfaceLib.c | 100 +++ .../IpmbInterfaceLib/PeiIpmbInterfaceLib.inf | 38 ++ .../IpmbInterfaceLib/SmmIpmbInterfaceLib.c | 94 +++ .../IpmbInterfaceLib/SmmIpmbInterfaceLib.inf | 37 ++ .../SsifInterfaceLib/DxeSsifInterfaceLib.c | 131 ++++ .../SsifInterfaceLib/DxeSsifInterfaceLib.inf | 40 ++ .../SsifInterfaceLib/PeiSsifInterfaceLib.c | 123 ++++ .../SsifInterfaceLib/PeiSsifInterfaceLib.inf | 41 ++ .../SsifInterfaceLib/SmmSsifInterfaceLib.c | 148 +++++ .../SsifInterfaceLib/SmmSsifInterfaceLib.inf | 40 ++ .../SsifInterfaceLib/SsifInterfaceLibCommon.c | 546 +++++++++++++++++ 28 files changed, 4233 insertions(+) create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gener= icIpmi/Pei/PeiIpmiHooks.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gener= icIpmi/Pei/PeiIpmiHooks.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/IpmiNetFnAppDefinitions.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/IpmiTransport2Definitions.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/Library/BmcCommonInterfaceLib.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/Library/BtInterfaceLib.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/Library/IpmbInterfaceLib.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/Library/SsifInterfaceLib.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/Ppi/IpmiTransport2Ppi.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/Protocol/IpmiTransport2Protocol.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/BmcCommonInterfaceLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/BmcCommonInterfaceLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/IpmbInterfaceLib/IpmbInterfaceLibCommon.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/SsifInterfaceLib/SsifInterfaceLibCommon.c diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/= Pei/PeiIpmiHooks.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gene= ricIpmi/Pei/PeiIpmiHooks.c new file mode 100644 index 0000000000..bd17cc4a35 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= IpmiHooks.c @@ -0,0 +1,351 @@ +/** @file + IPMI common hook functions + + @copyright + Copyright 1999 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include + +EFI_STATUS +PeiIpmiSendCommand ( + IN PEI_IPMI_TRANSPORT_PPI *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT32 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT32 *ResponseDataSize + ) +/*++ + +Routine Description: + + Send Ipmi Command in the right mode: HECI or KCS, to the + appropiate device, ME or BMC. + +Arguments: + + This - Pointer to IPMI protocol instance + NetFunction - Net Function of command to send + Lun - LUN of command to send + Command - IPMI command to send + CommandData - Pointer to command data buffer, if needed + CommandDataSize - Size of command data buffer + ResponseData - Pointer to response data buffer + ResponseDataSize - Pointer to response data buffer size + +Returns: + + EFI_INVALID_PARAMETER - One of the input values is bad + EFI_DEVICE_ERROR - IPMI command failed + EFI_BUFFER_TOO_SMALL - Response buffer is too small + EFI_UNSUPPORTED - Command is not supported by BMC + EFI_SUCCESS - Command completed successfully + +--*/ +{ + if (This =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // This Will be unchanged ( BMC/KCS style ) + // + return PeiIpmiSendCommandToBmc ( + This, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8 *) ResponseDataSize, + NULL + ); +} // IpmiSendCommand() + +EFI_STATUS +PeiIpmiSendCommand2 ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT32 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT32 *ResponseDataSize + ) +/*++ + +Routine Description: + + This API use the default interface (PcdDefaultSystemInterface) to send I= PMI command + in the right mode to the appropiate device, ME or BMC. + +Arguments: + + This - Pointer to IPMI protocol instance + NetFunction - Net Function of command to send + Lun - LUN of command to send + Command - IPMI command to send + CommandData - Pointer to command data buffer, if needed + CommandDataSize - Size of command data buffer + ResponseData - Pointer to response data buffer + ResponseDataSize - Pointer to response data buffer size + +Returns: + + EFI_INVALID_PARAMETER - One of the input values is bad + EFI_DEVICE_ERROR - IPMI command failed + EFI_BUFFER_TOO_SMALL - Response buffer is too small + EFI_UNSUPPORTED - Command is not supported by BMC + EFI_SUCCESS - Command completed successfully + +--*/ +{ + PEI_IPMI_BMC_INSTANCE_DATA *PeiIpmiInstance; + + if (This =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + PeiIpmiInstance =3D INSTANCE_FROM_PEI_IPMI_TRANSPORT2_THIS(This); + +#if KcsInterfaceSupport + if ((PeiIpmiInstance->IpmiTransport2Ppi.InterfaceType =3D=3D SysInterfac= eKcs) && + (PeiIpmiInstance->IpmiTransport2Ppi.Interface.KcsInterfaceState =3D= =3D IpmiInterfaceInitialized)) { + + return PeiIpmiSendCommand ( + &PeiIpmiInstance->IpmiTransportPpi, + NetFunction, + Lun, + Command, + CommandData, + CommandDataSize, + ResponseData, + ResponseDataSize + ); + } +#endif + +#if BtInterfaceSupport + if ((PeiIpmiInstance->IpmiTransport2Ppi.InterfaceType =3D=3D SysInterfac= eBt) && + (PeiIpmiInstance->IpmiTransport2Ppi.Interface.Bt.InterfaceState =3D= =3D IpmiInterfaceInitialized)) { + + return IpmiBtSendCommandToBmc ( + &PeiIpmiInstance->IpmiTransport2Ppi, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8*) ResponseDataSize, + NULL + ); + } +#endif + +#if SsifInterfaceSupport + if ((PeiIpmiInstance->IpmiTransport2Ppi.InterfaceType =3D=3D SysInterfac= eSsif) && + (PeiIpmiInstance->IpmiTransport2Ppi.Interface.Ssif.InterfaceState = =3D=3D IpmiInterfaceInitialized)) { + return IpmiSsifSendCommandToBmc ( + &PeiIpmiInstance->IpmiTransport2Ppi, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8*) ResponseDataSize, + NULL + ); + } +#endif + +#if IpmbInterfaceSupport + if ((PeiIpmiInstance->IpmiTransport2Ppi.InterfaceType =3D=3D SysInterfac= eIpmb) && + (PeiIpmiInstance->IpmiTransport2Ppi.Interface.Ipmb.InterfaceState = =3D=3D IpmiInterfaceInitialized)) { + return IpmiIpmbSendCommandToBmc ( + &PeiIpmiInstance->IpmiTransport2Ppi, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8*) ResponseDataSize, + NULL + ); + } +#endif + return EFI_UNSUPPORTED; +} // IpmiSendCommand() + +EFI_STATUS +PeiIpmiSendCommand2Ex ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT32 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT32 *ResponseDataSize, + IN SYSTEM_INTERFACE_TYPE InterfaceType + ) +{ +/*++ +Routine Description: + + This API use the specific interface type to send IPMI command + in the right mode to the appropiate device, ME or BMC. + +Arguments: + + This - Pointer to IPMI protocol instance + NetFunction - Net Function of command to send + Lun - LUN of command to send + Command - IPMI command to send + CommandData - Pointer to command data buffer, if needed + CommandDataSize - Size of command data buffer + ResponseData - Pointer to response data buffer + ResponseDataSize - Pointer to response data buffer size + InterfaceType - BMC Interface type. + +Returns: + + EFI_INVALID_PARAMETER - One of the input values is bad + EFI_DEVICE_ERROR - IPMI command failed + EFI_BUFFER_TOO_SMALL - Response buffer is too small + EFI_UNSUPPORTED - Command is not supported by BMC + EFI_SUCCESS - Command completed successfully + +--*/ + + PEI_IPMI_BMC_INSTANCE_DATA *PeiIpmiInstance; + + if (This =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + PeiIpmiInstance =3D INSTANCE_FROM_PEI_IPMI_TRANSPORT2_THIS(This); + +#if KcsInterfaceSupport + if ((InterfaceType =3D=3D SysInterfaceKcs) && + (PeiIpmiInstance->IpmiTransport2Ppi.Interface.KcsInterfaceState =3D= =3D IpmiInterfaceInitialized)) { + + return PeiIpmiSendCommand ( + &PeiIpmiInstance->IpmiTransportPpi, + NetFunction, + Lun, + Command, + CommandData, + CommandDataSize, + ResponseData, + ResponseDataSize + ); + } +#endif + +#if BtInterfaceSupport + + if ((InterfaceType =3D=3D SysInterfaceBt) && + (PeiIpmiInstance->IpmiTransport2Ppi.Interface.Bt.InterfaceState =3D= =3D IpmiInterfaceInitialized)) { + + return IpmiBtSendCommandToBmc ( + &PeiIpmiInstance->IpmiTransport2Ppi, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8*) ResponseDataSize, + NULL + ); + } +#endif + +#if SsifInterfaceSupport + + if ((InterfaceType =3D=3D SysInterfaceSsif) && + (PeiIpmiInstance->IpmiTransport2Ppi.Interface.Ssif.InterfaceState = =3D=3D IpmiInterfaceInitialized)) { + + return IpmiSsifSendCommandToBmc ( + &PeiIpmiInstance->IpmiTransport2Ppi, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8*) ResponseDataSize, + NULL + ); + } +#endif + +#if IpmbInterfaceSupport + if ((InterfaceType =3D=3D SysInterfaceIpmb) && + (PeiIpmiInstance->IpmiTransport2Ppi.Interface.Ipmb.InterfaceState = =3D=3D IpmiInterfaceInitialized)) { + + return IpmiIpmbSendCommandToBmc ( + &PeiIpmiInstance->IpmiTransport2Ppi, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8*) ResponseDataSize, + NULL + ); + } +#endif + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +PeiIpmiBmcStatus ( + IN PEI_IPMI_TRANSPORT_PPI *This, + OUT BMC_STATUS *BmcStatus, + OUT SM_COM_ADDRESS *ComAddress, + IN VOID *Context + ) +/*++ + +Routine Description: + + Updates the BMC status and returns the Com Address + +Arguments: + + This - Pointer to IPMI protocol instance + BmcStatus - BMC status + ComAddress - Com Address + +Returns: + + EFI_SUCCESS - Success + +--*/ +{ + + if ((This =3D=3D NULL) || (BmcStatus =3D=3D NULL) || (ComAddress =3D=3D = NULL)) { + return EFI_INVALID_PARAMETER; + } + + return IpmiBmcStatus ( + This, + BmcStatus, + ComAddress, + NULL + ); +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/= Pei/PeiIpmiHooks.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gene= ricIpmi/Pei/PeiIpmiHooks.h new file mode 100644 index 0000000000..bba61d1e45 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= IpmiHooks.h @@ -0,0 +1,213 @@ +/** @file + IPMI common hook functions head file + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _IPMI_HOOKS_H +#define _IPMI_HOOKS_H + +#include +#include +#include +#include +#include +#include +#include + +// +// Internal(hook) function list +// + +EFI_STATUS +PeiIpmiSendCommand ( + IN PEI_IPMI_TRANSPORT_PPI *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT32 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT32 *ResponseDataSize + ) +/*++ + +Routine Description: + + Send Ipmi Command in the right mode: HECI or KCS, to the + appropiate device, ME or BMC. + +Arguments: + + This - Pointer to IPMI protocol instance + NetFunction - Net Function of command to send + Lun - LUN of command to send + Command - IPMI command to send + CommandData - Pointer to command data buffer, if needed + CommandDataSize - Size of command data buffer + ResponseData - Pointer to response data buffer + ResponseDataSize - Pointer to response data buffer size + +Returns: + + EFI_INVALID_PARAMETER - One of the input values is bad + EFI_DEVICE_ERROR - IPMI command failed + EFI_BUFFER_TOO_SMALL - Response buffer is too small + EFI_UNSUPPORTED - Command is not supported by BMC + EFI_SUCCESS - Command completed successfully + +--*/ +; + +EFI_STATUS +PeiIpmiSendCommand2 ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT32 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT32 *ResponseDataSize + ) +/*++ + +Routine Description: + + This API use the default interface (PcdDefaultSystemInterface) to send I= PMI command + in the right mode to the appropiate device, ME or BMC. + +Arguments: + + This - Pointer to IPMI protocol instance + NetFunction - Net Function of command to send + Lun - LUN of command to send + Command - IPMI command to send + CommandData - Pointer to command data buffer, if needed + CommandDataSize - Size of command data buffer + ResponseData - Pointer to response data buffer + ResponseDataSize - Pointer to response data buffer size + +Returns: + + EFI_INVALID_PARAMETER - One of the input values is bad + EFI_DEVICE_ERROR - IPMI command failed + EFI_BUFFER_TOO_SMALL - Response buffer is too small + EFI_UNSUPPORTED - Command is not supported by BMC + EFI_SUCCESS - Command completed successfully + +--*/ +; + + +EFI_STATUS +PeiIpmiSendCommand2Ex ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT32 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT32 *ResponseDataSize, + IN SYSTEM_INTERFACE_TYPE InterfaceType + ); + +EFI_STATUS +PeiIpmiSendCommandToBMC ( + IN PEI_IPMI_TRANSPORT_PPI *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT8 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT8 *ResponseDataSize, + IN VOID *Context + ) +/*++ +Routine Description: + + This API use the specific interface type to send IPMI command + in the right mode to the appropiate device, ME or BMC. + +Arguments: + + This - Pointer to IPMI protocol instance + NetFunction - Net Function of command to send + Lun - LUN of command to send + Command - IPMI command to send + CommandData - Pointer to command data buffer, if needed + CommandDataSize - Size of command data buffer + ResponseData - Pointer to response data buffer + ResponseDataSize - Pointer to response data buffer size + InterfaceType - BMC Interface type. + +Returns: + + EFI_INVALID_PARAMETER - One of the input values is bad + EFI_DEVICE_ERROR - IPMI command failed + EFI_BUFFER_TOO_SMALL - Response buffer is too small + EFI_UNSUPPORTED - Command is not supported by BMC + EFI_SUCCESS - Command completed successfully + +--*/ +; + +EFI_STATUS +PeiIpmiBmcStatus ( + IN PEI_IPMI_TRANSPORT_PPI *This, + OUT BMC_STATUS *BmcStatus, + OUT SM_COM_ADDRESS *ComAddress, + IN VOID *Context + ) +/*++ + +Routine Description: + + Updates the BMC status and returns the Com Address + +Arguments: + + This - Pointer to IPMI protocol instance + BmcStatus - BMC status + ComAddress - Com Address + Context - Context + +Returns: + + EFI_SUCCESS - Success + +--*/ +; + +EFI_STATUS +IpmiBmcStatus ( + IN PEI_IPMI_TRANSPORT_PPI *This, + OUT BMC_STATUS *BmcStatus, + OUT SM_COM_ADDRESS *ComAddress, + IN VOID *Context + ) +/*++ + +Routine Description: + + Updates the BMC status and returns the Com Address + +Arguments: + + This - Pointer to IPMI protocol instance + BmcStatus - BMC status + ComAddress - Com Address + Context - Context + +Returns: + + EFI_SUCCESS - Success + +--*/ +; +#endif diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ipmi= NetFnAppDefinitions.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/I= nclude/IpmiNetFnAppDefinitions.h new file mode 100644 index 0000000000..ebc98c856a --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiNetFnAp= pDefinitions.h @@ -0,0 +1,239 @@ + +/** @file IpmiNetFnAppDefinitions.h + Ipmi NetFn Application additional commands and its structures. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _IPMI_NETFN_APP_DEFINITIONS_H_ +#define _IPMI_NETFN_APP_DEFINITIONS_H_ + +#include + +#define IPMI_SPEC_VERSION_1_5 0x51 +#define IPMI_SPEC_VERSION_2_0 0x02 +#define IPMI_APP_SELFTEST_RESERVED 0xFF + +#pragma pack(1) +/** + Get Bmc global enables command response. +*/ +typedef struct { + /// Completion code. + UINT8 CompletionCode; + UINT8 ReceiveMsgQueueInterrupt : 1; ///< Receive Message Queue I= nterrupt. + UINT8 EventMsgBufferFullInterrupt : 1; ///< Event Message Buffer Fu= ll Interrupt. + UINT8 EventMsgBuffer : 1; ///< Event Message Buffer. + UINT8 SystemEventLogging : 1; ///< System Event Logging. + UINT8 Reserved : 1; ///< Reserved. + UINT8 OEM0 : 1; ///< OEM0 interrupt. + UINT8 OEM1 : 1; ///< OEM1 interrupt. + UINT8 OEM2 : 1; ///< OEM2 interrupt. +} GET_BMC_GLOBAL_ENABLES_RESPONSE; + +/** + Channel access type. + */ +typedef enum { + ChannelAccessTypeReserved0, ///< Reserved0 + ChannelAccessTypeNonVolatile, ///< NonVolatile + ChannelAccessTypePresentVolatileSetting, ///< PresentVolatileSetting + ChannelAccessTypeReserved1 ///< Reserved1 +} CHANNEL_ACCESS_TYPE; + +/** + Channel access modes. +*/ +typedef enum { + ChannelAccessModeDisabled, ///< Disabled Channel Access Mode. + ChannelAccessModePreBootOnly, ///< Pre-Boot Only Channel Access = Mode. + ChannelAccessModeAlwaysAvailable, ///< Always Available Channel Acce= ss Mode. + ChannelAccessModeShared ///< Shared Channel Access Mode. +} CHANNEL_ACCESS_MODES; + +/** + SSIF read/write support. +*/ +typedef enum { + SsifSinglePartRw, ///< Single Part read-write. + SsifMultiPartRw, ///< Multi Part read-write. + SsifMultiPartRwWithMiddle, ///< Multi Part read-write With Middle. + SsifReserved ///< Reserved. +} SSIF_READ_WRITE_SUPPORT; + +/** + Channnel states. +*/ +typedef enum { + DisbleChannel =3D 0, ///< Disble Channel. + EnableChannel, ///< Enable Channel. + GetChannelState, ///< Get Channel State. + ChannelStateReserved ///< Channel State Reserved. +} CHANNEL_STATE; + +/** + Enable message channel command request structure. +*/ +typedef struct { + UINT8 ChannelNumber : 4; /// Channel Number. + UINT8 Reserved1 : 4; ///< Reserved. + UINT8 ChannelState : 2; ///< Channel State. + UINT8 Reserved2 : 6; ///< Reserved. +} IPMI_ENABLE_MESSAGE_CHANNEL_REQUEST; + +/** + Enable message channel command response structure. +*/ +typedef struct { + UINT8 CompletionCode; /// Completion code. + UINT8 ChannelNumber : 4; ///< Channel Number. + UINT8 Reserved1 : 4; ///< Reserved. + UINT8 ChannelState : 1; ///< Channel State. + UINT8 Reserved2 : 7; ///< Reserved. +} IPMI_ENABLE_MESSAGE_CHANNEL_RESPONSE; + +/** + Set System Info Parameters Command. +*/ +#define IPMI_APP_SET_SYSTEM_INFO 0x58 + +/** + System Info String Encoding. +*/ +typedef enum { + SysInfoAscii, ///< Ascii + SysInfoUtf8, ///< Utf8 + SysInfoUnicode ///< Unicode +} SYSTEM_INFO_STRING_ENCODING; + +/** + System parameter selector. +*/ +typedef enum { + SysInfoSetInProgress, ///< SetInProgress. + SysInfoFirmwareVersion, ///< FirmwareVersion. + SysInfoSystemName, ///< SystemName. + SysInfoPrimaryOsName, ///< PrimaryOsName. + SysInfoPresentOsName, ///< PresentOsName. + SysInfoPresentOsVersion, ///< PresentOsVersion. + SysInfoBmcUrl, ///< BmcUrl. + SysInfoHyperviserUrl, ///< HyperviserUrl. +} SYSTEM_INFO_PARAMETER_SELECTOR; + +/** + System info set state. +*/ +typedef enum { + SysInfoStateSetComplete, ///< SetComplete. + SysInfoStateSetInProgress, ///< SetInProgress. + SysInfoStateCommitWrite, ///< StateCommitWrite. + SysInfoStateReserved, ///< StateReserved. +} SYSTEM_INFO_SET_STATE; + +/** + Set system info parameter command request Structure. +*/ +typedef struct { + UINT8 ParamSelector; /// Parameter selector. + UINT8 SetSelector; ///< Data 1 + UINT8 Data[16]; ///< Data 2:17 +} SET_SYSTEM_INFO_REQUEST; + +/** + Get System Info Parameters Command. +*/ +#define IPMI_APP_GET_SYSTEM_INFO 0x59 + +/** + Get system info Command request Structure. +*/ +typedef struct { + UINT8 Reserved : 7; /// Reserved. + UINT8 GetParam : 1; ///< Get Parameter. + UINT8 ParamSelector; ///< Parameter Selector. + UINT8 SetSelector; ///< Set selector. + UINT8 BlockSelector; ///< Block selector. +} GET_SYSTEM_INFO_REQUEST; + +/** + Get system info command response Structure. +*/ +typedef struct { + UINT8 CompletionCode; /// Completion code. + UINT8 ParamRevision; /// Parameter Revision + union { + struct { + UINT8 State : 2; ///< State. + UINT8 Reserved : 6; ///< Reserved. + }Progress; + UINT8 SetSelector; ///< Set Selector. + }Data1; + UINT8 Data[16]; ///< Data 2:17. +} GET_SYSTEM_INFO_RESPONSE; + +/** + Get system Guid Command response Structure. +*/ +typedef struct { + UINT8 CompletionCode; /// Completion code. + UINT8 Node[6]; ///< Node. + UINT8 Clock[2]; ///< Clock. + UINT16 Time_High; ///< Time High. + UINT16 Time_Mid; ///< Time Middle. + UINT32 Time_Low; ///< Time Low. +} GET_SYSTEM_GUID_RESPONSE; + +/** + Get Bt interface Capability Command response Structure. +*/ +typedef struct { + UINT8 CompletionCode; /// Completion code. + UINT8 OutstaningReq; /// + Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _IPMI_TRANSPORT2_DEFINITIONS_H_ +#define _IPMI_TRANSPORT2_DEFINITIONS_H_ + +typedef struct _IPMI_TRANSPORT2 IPMI_TRANSPORT2; + +/** @internal + BT Interface. +*/ +typedef struct { + UINT8 InterfaceState; /// Interface state. + UINT16 CtrlPort; ///< Control port. + UINT16 ComBuffer; ///< Communication buffer port. + UINT16 IntMaskPort; ///< Interrupt mask port. + UINTN MmioBaseAddress; ///< Mmio base address. + UINTN BaseAddressRange; ///< Mmio base address range to + ///< differentiate port address. + UINT8 AccessType; ///< Access type - IO or MMIO. + UINT32 BtRetryCount; ///< Delay counter for retry. + UINT8 BtSoftErrorCount; ///< Soft error count. + BOOLEAN BtTransportLocked; ///< Interface lock. + UINT8 HosttoBmcBufferSize; ///< Host to Bmc Buffer Size. + UINT8 BmctoHostBufferSize; ///< Bmc to Host Buffer Size. +} BT_SYSTEM_INTERFACE; + +/** @internal + SSIF Interface. +*/ +typedef struct { + UINT8 InterfaceState; /// Interface state. + EFI_GUID SsifInterfaceApiGuid; ///< Smbus instance guid. + UINTN SsifInterfaceApiPtr; ///< Smbus instance pointer. + UINT8 RwSupport; ///< Read-write support. + UINT16 SsifRetryCounter; ///< Retry counter. + BOOLEAN PecSupport; ///< Packet Error Check support. + BOOLEAN SmbAlertSupport; ///< Smbus alert support. + UINT8 SsifSoftErrorCount; ///< Soft error count. + BOOLEAN SsifTransportLocked; ///< Interface lock. +} SSIF_SYSTEM_INTERFACE; + +/** @internal + IPMB Interface. +*/ +typedef struct { + /// Interface state. + UINT8 InterfaceState; + EFI_GUID IpmbInterfaceApiGuid; ///< Ipmb instance guid. + UINTN IpmbInterfaceApiPtr; ///< Ipmb instance pointer. + UINT8 IpmbSoftErrorCount; ///< Soft error count. + BOOLEAN IpmbTransportLocked; ///< Interface lock. +} IPMB_SYSTEM_INTERFACE; + +/** @internal + System Interface. +*/ +typedef struct { + UINT8 KcsInterfaceState; + BT_SYSTEM_INTERFACE Bt; ///< Bt interface. + SSIF_SYSTEM_INTERFACE Ssif; ///< Ssif interface. + IPMB_SYSTEM_INTERFACE Ipmb; +} IPMI_SYSTEM_INTERFACE; + +/** @inrernal + Ipmi Interface Access Type. +*/ +typedef enum { + IpmiMmioAccess, ///< Mmio Access. + IpmiIoAccess ///< Io Access. +} IPMI_ACCESS_TYPE; + +/** @internal + Host to BMC Interface Type. +*/ +typedef enum { + SysInterfaceUnknown, ///< Unknown interface type. + SysInterfaceKcs, ///< Kcs interface. + SysInterfaceSmic, ///< Smic interface. + SysInterfaceBt, ///< Bt interface. + SysInterfaceSsif, ///< Ssif interface. + SysInterfaceIpmb, ///< Ipmb interface. + SysInterfaceMax ///< Maximum interface type. +} SYSTEM_INTERFACE_TYPE; + +/** @internal + BMC Interface status. +*/ +typedef enum { + BmcStatusOk, ///< Bmc status Ok. + BmcStatusSoftFail, ///< Bmc status Soft fail. + BmcStatusHardFail, ///< Bmc status Hard fail. + BmcStatusUpdateInProgress ///< Bmc status Update in progress. +} BMC_INTERFACE_STATUS; + +/** @internal + Ipmi Interface state. +*/ +typedef enum { + IpmiInterfaceNotReady, ///< Interface Not Ready. + IpmiInterfaceInitialized, ///< Interface Initialized. + IpmiInterfaceInitError, ///< Interface Initialization Error. +} IPMI_INTERFACE_STATE; + +// +// IPMI Function Prototypes +// +typedef +EFI_STATUS +(EFIAPI *IPMI_SEND_COMMAND2) ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT32 CommandDataSize, + OUT UINT8 *ResponseData, + OUT UINT32 *ResponseDataSize + ); + +typedef +EFI_STATUS +(EFIAPI *IPMI_SEND_COMMAND2Ex) ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT32 CommandDataSize, + OUT UINT8 *ResponseData, + OUT UINT32 *ResponseDataSize, + IN SYSTEM_INTERFACE_TYPE InterfaceType + ); + + +struct _IPMI_TRANSPORT2 { + UINT64 Revision; + IPMI_SEND_COMMAND2 IpmiSubmitCommand2; + IPMI_SEND_COMMAND2Ex IpmiSubmitCommand2Ex; + IPMI_SYSTEM_INTERFACE Interface; ///< System interface= . + SYSTEM_INTERFACE_TYPE InterfaceType; ///< Bmc Interface Ty= pe. + BMC_INTERFACE_STATUS IpmiTransport2BmcStatus; + EFI_HANDLE IpmiHandle; + UINT8 CompletionCode; +}; + +#endif diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Libr= ary/BmcCommonInterfaceLib.h b/Features/Intel/OutOfBandManagement/IpmiFeatur= ePkg/Include/Library/BmcCommonInterfaceLib.h new file mode 100644 index 0000000000..49cb1e6008 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/Bmc= CommonInterfaceLib.h @@ -0,0 +1,200 @@ + +/** @file BmcCommonInterfaceLib.h + Bmc Common interface library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _BMC_COMMON_INTERFACE_LIB_H_ +#define _BMC_COMMON_INTERFACE_LIB_H_ + +#include +#include +#include + +#define IPMI_APP_SELFTEST_RESERVED 0xFF + +#define IPMI_GET_SET_IN_PROGRESS_RETRY_COUNT 10 +#define IPMI_BIT_CLEAR 0 +#define IPMI_SELECTOR_NONE 0 +#define IPMI_CLEAR_FLAG 0 +#define IPMI_SET_FLAG 1 +#define IPMI_STALL 1000 +#define MIN_TO_100MS 60 * 10 +#define MAX_BMC_CMD_FAIL_COUNT 10 + +// Completion code macros. +#define IPMI_COMPLETION_CODE_SUCCESS 0x00 +#define IPMI_COMPLETION_CODE_DEVICE_SPECIFIC_START 0x01 +#define IPMI_COMPLETION_CODE_DEVICE_SPECIFIC_END 0x7E +#define IPMI_COMPLETION_CODE_COMMAND_SPECIFIC_START 0x80 +#define IPMI_COMPLETION_CODE_COMMAND_SPECIFIC_END 0xBE +#define IPMI_MAX_SOFT_COUNT 10 + +#define IPMI_MAX_BT_CMD_DATA_SIZE 0xFF + +#define IPMI_ERROR_COMPLETION_CODE(a) !((a =3D=3D IPMI_COMPLETION_CODE_= SUCCESS) || \ + ((a >=3D IPMI_COMPLETION_CODE= _DEVICE_SPECIFIC_START) && \ + (a <=3D IPMI_COMPLETION_CODE= _DEVICE_SPECIFIC_END)) || \ + ((a >=3D IPMI_COMPLETION_CODE= _COMMAND_SPECIFIC_START) && \ + (a <=3D IPMI_COMPLETION_CODE= _COMMAND_SPECIFIC_END)) \ + ) + +#define KcsInterfaceSupport FixedPcdGet8 (PcdKcsInterfaceSupp= ort) =3D=3D 1 +#define BtInterfaceSupport FixedPcdGet8 (PcdBtInterfaceSuppo= rt) =3D=3D 1 +#define SsifInterfaceSupport FixedPcdGet8 (PcdSsifInterfaceSup= port) =3D=3D 1 +#define IpmbInterfaceSupport FixedPcdGet8 (PcdIpmbInterfaceSup= port) =3D=3D 1 + +/** + Read 8 bit data from BMC port based on access type. + + @param[in] AccessType Specifies MMIO or IO access. + @param[in] Address Specifies Address to read. + + @return UINT8 Data read. + +**/ +UINT8 +IpmiBmcRead8 ( + IN UINT8 AccessType, + IN UINTN Address +); + +/** + Write 8 bit data to BMC port based on access type. + + @param[in] AccessType Specifies MMIO or IO access. + @param[in] Address Specifies Address to write. + @param[in] Data Specifies data to be written. + + @return Data written. + +**/ +UINT8 +IpmiBmcWrite8 ( + IN UINT8 AccessType, + IN UINTN Address, + IN UINT8 Data +); + +/** + Acquire the lock to use the IPMI transport. + + @param[out] Lock Pointer to Lock. + + @return VOID Returns nothing. + +**/ +VOID +IpmiTransportAcquireLock ( + OUT BOOLEAN *Lock +); + + +/** + Release the lock of IPMI transport. + + @param[out] Lock Pointer to Lock. + + @return VOID Returns nothing. + +**/ +VOID +IpmiTransportReleaseLock ( + OUT BOOLEAN *Lock +); + + +/** + Returns the Lock state of IPMI transport. + + @param[in] Lock Pointer to Lock. + + @retval TRUE IPMI transport is in lock state. + @retval FALSE IPMI transport is in release state. + +*/ +BOOLEAN +IpmiIsIpmiTransportlocked ( + IN BOOLEAN *Lock +); + +/** + Updates the SoftErrorCount of specific interface based on the BMC Erro= r input. + + @param[in] BmcError BMC Error. + @param[in, out] Interface Interface pointer to update soft error= count. + @param[in] InterfaceType Interface type to communicate. + + @retval EFI_SUCCESS Updated SoftErrorCount of specific int= erface. + @retval EFI_INVALID_PARAMETER Invalid Interface pointer or Interface= type. + +**/ +EFI_STATUS +IpmiUpdateSoftErrorCount ( + IN UINT8 BmcError, + IN OUT IPMI_SYSTEM_INTERFACE *Interface, + IN SYSTEM_INTERFACE_TYPE InterfaceType + ); + +/** + Execute the Self Test command with specific interface + + @param IpmiInstance IpmiInstance Data structure pointer. + @param InterfaceType Interface Type + @param[in] InterfaceType Interface type to communicate. + + @return EFI_STATUS Return Status +**/ +EFI_STATUS +CheckSelfTestByInterfaceType ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2, + IN OUT BMC_INTERFACE_STATUS *BmcStatus, + IN SYSTEM_INTERFACE_TYPE InterfaceType + ); + +/** + Initialize BT interface specific data. + + @param[in, out] Interface System interface pointer. + + @retval EFI_SUCCESS Interface is successfully initialized. + @retval Others Return status while initializing interface. + +**/ +EFI_STATUS +InitBtInterfaceData ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ); + +/** + Initialize SSIF interface specific data. + + @param[in, out] Interface System interface pointer. + + @retval EFI_SUCCESS Interface is successfully initialized. + @retval Others Return status while initializing interface. + +**/ +EFI_STATUS +InitSsifInterfaceData ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ); + +/** @internal + Initialize IPMB interface specific data. + + @param[in, out] Interface System interface pointer. + + @retval EFI_SUCCESS Interface is successfully initialized. + @retval Others Error status while initializing interface. + +**/ +EFI_STATUS +InitIpmbInterfaceData ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ); +#endif diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Libr= ary/BtInterfaceLib.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/In= clude/Library/BtInterfaceLib.h new file mode 100644 index 0000000000..183bfdda69 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/BtI= nterfaceLib.h @@ -0,0 +1,83 @@ + +/** @file BtInterfaceLib.h + BT interface common macros and declarations. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _BT_INTERFACE_LIB_H_ +#define _BT_INTERFACE_LIB_H_ + +#include +#include + +#define IPMI_MAX_BT_CMD_DATA_SIZE 0xFF +#define IPMI_CLR_WR_PTR_BIT 0x01 +#define IPMI_CLR_RD_PTR_BIT 0x02 +#define IPMI_H2B_ATN_BIT 0x04 +#define IPMI_B2H_ATN_BIT 0x08 +#define IPMI_H_BUSY 0x40 +#define IPMI_B_BUSY_BIT 0x80 + +/** + BT interface send command implementation. + + @param[in] Interface Pointer to System interface. + @param[in] NetFunction Net function of the command. + @param[in] Lun Logical Unit Number of the command= . + @param[in] Command Command to be sent to BMC. + @param[in] CommandData Command data to be sent along with + Command. + @param[in] CommandDataSize Command Data size. + @param[out] ResponseData Pointer to the response data buffe= r. + @param[in, out] ResponseDataSize Pointer to the response data size. + @param[out] CompletionCode Pointer to completion code. + @param[in] InterfaceType Interface type. + @param[in] Context NULL here. + + @retval EFI_UNSUPPORTED Interface type is not supported. + @retval EFI_NOT_READY Interface is not initialized. + @retval EFI_ACCESS_DENIED Interface is locked. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_BAD_BUFFER_SIZE Invalid buffer size. + @retval EFI_DEVICE_ERROR Error completion code or data size + retrieved is small. + @retval EFI_BUFFER_TOO_SMALL Buffer is too small to update response + data. + @retval EFI_SUCCESS Command sent successfully. + @return Others Error status returned from BMC while + executing the command. + +**/ +EFI_STATUS +EFIAPI +IpmiBtSendCommandToBmc ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT8 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT8 *ResponseDataSize, + IN VOID *Context + ); + +/** + Execute the Get BT Interface Capability command and update the input + and output buffer value of Ipmi Instance. + + @param IpmiInstance Data structure pointer. + + @retval VOID +**/ + +VOID +GetBtInterfaceCapability ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ); + +#endif diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Libr= ary/IpmbInterfaceLib.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/= Include/Library/IpmbInterfaceLib.h new file mode 100644 index 0000000000..5fc1176130 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/Ipm= bInterfaceLib.h @@ -0,0 +1,92 @@ + +/** @file IpmbInterfaceLib.h + IPMB interface common function declarations and macros. + +*/ + +#ifndef _IPMB_INTERFACE_LIB_H_ +#define _IPMB_INTERFACE_LIB_H_ + +#include +#include +#include + +#define IPMI_MAX_IPMB_CMD_DATA_SIZE 0xFF +#define IPMI_READ_FLAG 1 +#define IPMI_WRITE_FLAG 0 +#define IPMI_SEQ_NO 0 // IPMB Message Sequence Numb= er. + +/** @internal + Locate I2c Ppi/Protocol instance and initialize interface pointer. + + @param[in, out] Interface System interface pointer. + + @return EFI_STATUS Status returned from functions used. + +**/ +EFI_STATUS +IpmiGetI2cApiPtr ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 +); + +/** @internal + Send Ipmi command through Ipmb interface. + + @param[in] Interface Pointer to System interface. + @param[in] SlaveAddress I2C device slave address. + @param[in] RequestPacket Pointer to an EFI_I2C_REQUEST_PACKET + structure describing the I2C transaction. + + @return EFI_STATUS Status of the Send I2c command. + +**/ +EFI_STATUS +IpmiI2cSendCommand ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN UINTN SlaveAddress, + IN EFI_I2C_REQUEST_PACKET *RequestPacket + ); + +/** @internal + IPMB interface send command implementation. + + @param[in] Interface Pointer to System interface. + @param[in] NetFunction Net function of the command. + @param[in] Lun Logical Unit Number of the command= . + @param[in] Command Command to be sent to BMC. + @param[in] CommandData Command data to be sent along with + Command. + @param[in] CommandDataSize Command Data size. + @param[out] ResponseData Pointer to the response data buffe= r. + @param[in, out] ResponseDataSize Pointer to the response data size. + @param[out] CompletionCode Pointer to completion code. + @param[in] InterfaceType Interface type. + @param[in] Context NULL here. + + @retval EFI_UNSUPPORTED Interface type is not supported. + @retval EFI_NOT_READY Interface is not initialized. + @retval EFI_ACCESS_DENIED Interface is locked. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_BAD_BUFFER_SIZE Invalid buffer size. + @retval EFI_DEVICE_ERROR Error completion code or data size + retrieved is small. + @retval EFI_BUFFER_TOO_SMALL Buffer is too small to update response + data. + @retval EFI_SUCCESS Command sent successfully. + @return Others Error status returned from BMC while + executing the command. + +**/ +EFI_STATUS +IpmiIpmbSendCommandToBmc ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT8 CommandDataSize, + OUT UINT8 *ResponseData, + IN OUT UINT8 *ResponseDataSize, + IN VOID *Context ); + +#endif // #ifndef _IPMB_INTERFACE_LIB_H diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Libr= ary/SsifInterfaceLib.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/= Include/Library/SsifInterfaceLib.h new file mode 100644 index 0000000000..992e057385 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/Ssi= fInterfaceLib.h @@ -0,0 +1,165 @@ + +/** @file SsifInterfaceLib.h + SSIF interface common function declarations and macros. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _SSIF_INTERFACE_LIB_H +#define _SSIF_INTERFACE_LIB_H + +#include +#include +#include +#include + +#define IPMI_MAX_SSIF_CMD_DATA_SIZE 0xFF +#define IPMI_SMBUS_BLOCK_LENGTH 0x20 + +// Smbus Write Commands. +#define IPMI_SMBUS_SINGLE_WRITE_CMD 0x2 +#define IPMI_SMBUS_MULTI_WRITE_START_CMD 0x6 +#define IPMI_SMBUS_MULTI_WRITE_MIDDLE_CMD 0x7 +#define IPMI_SMBUS_MULTI_WRITE_END_CMD 0x8 + +// Smbus Read Commands. +#define IPMI_SMBUS_SINGLE_READ_CMD 0x3 +#define IPMI_SMBUS_MULTI_READ_START_CMD SMBUS_SINGLE_READ_CMD +#define IPMI_SMBUS_MULTI_READ_MIDDLE_CMD 0x9 +#define IPMI_SMBUS_MULTI_READ_END_CMD 0x9 +#define IPMI_SMBUS_MULTI_READ_RETRY_CMD 0xA + +#define IPMI_MULTI_READ_ZEROTH_STRT_BIT 0x0 +#define IPMI_MULTI_READ_FIRST_STRT_BIT 0x1 + + +/** + Check the SMBUS alert pin status function + + @param VOID Nothing. + + @retval TRUE Alert pin status is set. + @retval FALSE Alert pin status is not set. + +**/ +typedef BOOLEAN (SSIF_ALERT_PIN_CHECK) ( + VOID +); + +/** + Execute the Get System Interface Capability command and update the RwS= upport + and PecSupport of Ipmi Instance. + + @param IpmiInstance Ipmi Instance Data structure pointer. + + @return EFI_STATUS Return Status + +**/ +VOID +GetSystemInterfaceCapability ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ); + +/** + Execute the Get Global Enable command to get receive message queue int= errupt. + + @return VOID + +**/ +VOID +GetGlobalEnables ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 +); + +/** + Locate Smbus instance and initialize interface pointer. + + @param[in, out] Interface System interface pointer. + + @return EFI_STATUS Status returned while locating smbus instance. + +**/ +EFI_STATUS +IpmiGetSmbusApiPtr ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 +); + +/** + Send Ipmi command through Smbus instance. + + @param[in] Interface Pointer to System interface. + @param[in] SlaveAddress The SMBUS hardware address. + @param[in] Command This command is transmitted by the SMB= us + host controller to the SMBus slave dev= ice. + @param[in] Operation Operation to be performed. + @param[in] PecCheck Defines if Packet Error Code (PEC) + checking is required for this operatio= n. + @param[in, out] Length Signifies the number of bytes that thi= s + operation will do. + @param[in, out] Buffer Contains the value of data to execute = to + the SMBus slave device. The length of + this buffer is identified by Length. + + @retval EFI_NOT_FOUND Smbus instance is not found. + @retval Others Return status of the Smbus Execute operation. + +**/ +EFI_STATUS +IpmiSmbusSendCommand ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer +); + +/** + Ssif interface send command implementation. + + @param[in] Interface Pointer to System interface. + @param[in] NetFunction Net function of the command. + @param[in] Lun Logical Unit Number of the command= . + @param[in] Command Command to be sent to BMC. + @param[in] CommandData Command data to be sent along with + Command. + @param[in] CommandDataSize Command Data size. + @param[out] ResponseData Pointer to the response data buffe= r. + @param[in, out] ResponseDataSize Pointer to the response data size. + @param[out] CompletionCode Pointer to completion code. + @param[in] InterfaceType Interface type. + @param[in] Context NULL here. + + @retval EFI_UNSUPPORTED Interface type is not supported. + @retval EFI_NOT_READY Interface is not initialized. + @retval EFI_ACCESS_DENIED Interface is locked. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_BAD_BUFFER_SIZE Invalid buffer size. + @retval EFI_DEVICE_ERROR Error completion code or data size + retrieved is small. + @retval EFI_BUFFER_TOO_SMALL Buffer is too small to update response + data. + @retval EFI_SUCCESS Command sent successfully. + @return Others Error status returned from BMC while + executing the command. + +**/ +EFI_STATUS +EFIAPI +IpmiSsifSendCommandToBmc ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT8 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT8 *ResponseDataSize, + IN VOID *Context +); + +#endif diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ppi/= IpmiTransport2Ppi.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inc= lude/Ppi/IpmiTransport2Ppi.h new file mode 100644 index 0000000000..e977dd2526 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ppi/IpmiTra= nsport2Ppi.h @@ -0,0 +1,23 @@ +/** @file + IPMI Ttransport2 PPI Header File. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _IPMI_TRANSPORT2_PPI_H_ +#define _IPMI_TRANSPORT2_PPI_H_ + +#include +#include + +#define PEI_IPMI_TRANSPORT2_PPI_GUID \ + { \ + 0x8122CEBD, 0xF4FD, 0x4EA8, 0x97, 0x6C, 0xF0, 0x30, 0xAD, 0xDC, 0x4C, = 0xB4 \ + } + +extern EFI_GUID gPeiIpmiTransport2PpiGuid; + +#endif diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Prot= ocol/IpmiTransport2Protocol.h b/Features/Intel/OutOfBandManagement/IpmiFeat= urePkg/Include/Protocol/IpmiTransport2Protocol.h new file mode 100644 index 0000000000..b4186df303 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Protocol/Ip= miTransport2Protocol.h @@ -0,0 +1,30 @@ + +/** @file IpmiTransport2Protocol.h + IpmiTransport2 Protocol Header File. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _IPMI2_TRANSPORT2_PROTO_H_ +#define _IPMI2_TRANSPORT2_PROTO_H_ + +#include +#include + +#define IPMI_TRANSPORT2_PROTOCOL_GUID \ + { \ + 0x4a1d0e66, 0x5271, 0x4e22, { 0x83, 0xfe, 0x90, 0x92, 0x1b, 0x74, = 0x82, 0x13 } \ + } + +#define SMM_IPMI_TRANSPORT2_PROTOCOL_GUID \ + { \ + 0x1dbd1503, 0xa60, 0x4230, { 0xaa, 0xa3, 0x80, 0x16, 0xd8, 0xc3, 0= xde, 0x2f } \ + } + +extern EFI_GUID gIpmiTransport2ProtocolGuid; +extern EFI_GUID gSmmIpmiTransport2ProtocolGuid; + +#endif diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/BmcCommonInterfaceLib.c b/Features/Intel/OutOfBandMana= gement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BmcCommonInterfaceLi= b.c new file mode 100644 index 0000000000..086582cf0e --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/BmcCommonInterfaceLib.c @@ -0,0 +1,228 @@ +/** @file BmcCommonInterfaceLib.c + BmcCommonInterfaceLib generic functions for all interfaces. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include + +/** + Read 8 bit data from BMC port based on access type. + + @param[in] AccessType Specifies MMIO or IO access. + @param[in] Address Specifies Address to read. + + @return UINT8 Data read. + +**/ +UINT8 +IpmiBmcRead8 ( + IN UINT8 AccessType, + IN UINTN Address +) +{ + if (AccessType =3D=3D IpmiIoAccess) { + return IoRead8 (Address); + } else { + return MmioRead8 (Address); + } +} + +/** + Write 8 bit data to BMC port based on access type. + + @param[in] AccessType Specifies MMIO or IO access. + @param[in] Address Specifies Address to write. + @param[in] Data Specifies data to be written. + + @return Data written. + +**/ +UINT8 +IpmiBmcWrite8 ( + IN UINT8 AccessType, + IN UINTN Address, + IN UINT8 Data +) +{ + if (AccessType =3D=3D IpmiIoAccess) { + return IoWrite8 ( + Address, + Data ); + } else { + return MmioWrite8 ( + Address, + Data ); + } +} + +/** + Acquire the lock to use the IPMI transport. + + @param[out] Lock Pointer to Lock. + + @return VOID Returns nothing. + +**/ +VOID +IpmiTransportAcquireLock ( + OUT BOOLEAN *Lock +) +{ + *Lock =3D TRUE; +} + +/** + Release the lock of IPMI transport. + + @param[out] Lock Pointer to Lock. + + @return VOID Returns nothing. + +**/ +VOID +IpmiTransportReleaseLock ( + OUT BOOLEAN *Lock +) +{ + *Lock =3D FALSE; +} + +/** + Returns the Lock state of IPMI transport. + + @param[in] Lock Pointer to Lock. + + @retval TRUE IPMI transport is in lock state. + @retval FALSE IPMI transport is in release state. + +*/ +BOOLEAN +IpmiIsIpmiTransportlocked ( + IN BOOLEAN *Lock +) +{ + return *Lock; +} + +/** @internal + Updates the SoftErrorCount of specific interface based on the BMC Erro= r input. + + @param[in] BmcError BMC Error. + @param[in, out] Interface Interface pointer to update soft error= count. + @param[in] InterfaceType Interface type to communicate. + + @retval EFI_SUCCESS Updated SoftErrorCount of specific int= erface. + @retval EFI_INVALID_PARAMETER Invalid Interface pointer or Interface= type. + +**/ +EFI_STATUS +IpmiUpdateSoftErrorCount ( + IN UINT8 BmcError, + IN OUT IPMI_SYSTEM_INTERFACE *Interface, + IN SYSTEM_INTERFACE_TYPE InterfaceType + ) +{ + UINT8 Errors[] =3D {0xC0, 0xC3, 0xC4, 0xC9, 0xCE, 0xCF, 0xFF, 0x00}; + UINT8 Index =3D 0; + + if ((Interface =3D=3D NULL) || (InterfaceType <=3D SysInterfaceUnknown= ) || + (InterfaceType >=3D SysInterfaceMax)) { + return EFI_INVALID_PARAMETER; + } + + while (Errors[Index] !=3D 0) { + + if (Errors[Index] =3D=3D BmcError) { + + switch (InterfaceType) { + + case SysInterfaceBt: + Interface->Bt.BtSoftErrorCount++; + break; + + case SysInterfaceSsif: + Interface->Ssif.SsifSoftErrorCount++; + break; + + default : + break; + } + } + Index++; + } + return EFI_SUCCESS; +} + +/** + Updates the SoftErrorCount of specific interface based on the BMC Erro= r input. + + @param[in] BmcError BMC Error. + @param[in, out] Interface Interface pointer to update soft error= count. + @param[in] InterfaceType Interface type to communicate. + + @retval EFI_SUCCESS Updated SoftErrorCount of specific int= erface. + @retval EFI_INVALID_PARAMETER Invalid Interface pointer or Interface= type. + +**/ +EFI_STATUS +CheckSelfTestByInterfaceType ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2, + IN OUT BMC_INTERFACE_STATUS *BmcStatus, + IN SYSTEM_INTERFACE_TYPE InterfaceType + ) +{ + EFI_STATUS Status; + IPMI_SELF_TEST_RESULT_RESPONSE BstStatus; + UINT32 ResponseDataSize; + + if (IpmiTransport2 =3D=3D NULL || BmcStatus =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + ResponseDataSize =3D sizeof(IPMI_SELF_TEST_RESULT_RESPONSE); + + Status =3D IpmiTransport2->IpmiSubmitCommand2Ex ( + IpmiTransport2, + IPMI_NETFN_APP, + BMC_LUN, + IPMI_APP_GET_SELFTEST_RESULTS, + NULL, + 0, + (UINT8 *)&BstStatus, + &ResponseDataSize, + InterfaceType); + if (EFI_ERROR(Status)) { + *BmcStatus =3D BmcStatusHardFail; + return Status; + } + + if (BstStatus.CompletionCode =3D=3D IPMI_COMPLETION_CODE_SUCCESS) { + /* Check the self test results. Cases 55h - 58h are Ipmi defined + test results. Additional Cases are device specific test results= .*/ + switch (BstStatus.Result) { + case IPMI_APP_SELFTEST_NO_ERROR: // 0x55 + case IPMI_APP_SELFTEST_NOT_IMPLEMENTED: // 0x56 + case IPMI_APP_SELFTEST_RESERVED: // 0xFF + *BmcStatus =3D BmcStatusOk; + break; + + case IPMI_APP_SELFTEST_ERROR: // 0x57 + *BmcStatus =3D BmcStatusSoftFail; + break; + + default: // 0x58 and Other Device Specific Hardware Error. + *BmcStatus =3D BmcStatusHardFail; + break; + } + } + + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/BmcCommonInterfaceLib.inf b/Features/Intel/OutOfBandMa= nagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BmcCommonInterface= Lib.inf new file mode 100644 index 0000000000..33bb360c41 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/BmcCommonInterfaceLib.inf @@ -0,0 +1,26 @@ +## @file BmcCommonInterfaceLib.inf +# +# INF description file for BmcCommonInterfaceLib Library. +# +# @copyright +# Copyright 2016 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D BmcCommonInterfaceLib + FILE_GUID =3D D86308F8-5246-4B2F-AC25-E3D17170D6EF + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.1 + LIBRARY_CLASS =3D BmcCommonInterfaceLib + +[Sources] + BmcCommonInterfaceLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IpmiFeaturePkg/IpmiFeaturePkg.dec diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.c b/Features/Intel/OutOf= BandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BtInterfaceL= ib/BtInterfaceLib.c new file mode 100644 index 0000000000..a83620cfaf --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/BtInterfaceLib/BtInterfaceLib.c @@ -0,0 +1,570 @@ +/** @file BtInterfaceLib.c + BT Transport implementation library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include + +#define IPMI_BT_DELAY_PER_RETRY FixedPcdGet32 (PcdBtDelayPerRetry) + +/** + Get the BT interface port addresses based on access type. + + @param[in] Interface Pointer to System interface. + @param[out] BtCtrlPort Pointer to Bt control port. + @param[out] BtComBufferPort Pointer to Bt communication buffer por= t. + + @return VOID Nothing. + +**/ +VOID +GetBtPortAddresses ( + IN IPMI_SYSTEM_INTERFACE *Interface, + OUT UINTN *BtCtrlPort, + OUT UINTN *BtComBufferPort + ) +{ + // Update Bt Ports based on Interface AccessType. + if (Interface->Bt.AccessType =3D=3D IpmiIoAccess) { + *BtCtrlPort =3D (UINTN) Interface->Bt.CtrlPort; + *BtComBufferPort =3D (UINTN) Interface->Bt.ComBuffer; + } else { + *BtCtrlPort =3D Interface->Bt.MmioBaseAddress; + *BtComBufferPort =3D *BtCtrlPort + Interface->Bt.BaseAddressRange; + } +} + +/** + Sends the command to BT interface BMC port. + + @param[in] Interface Pointer to System interface. + @param[in] Context NULL here. + @param[in] Data Pointer to command data that will be sent to B= MC + along with Command. + @param[in] DataSize Size of the command data. + + @retval EFI_NOT_READY Interface is not ready to send data. + @retval EFI_SUCCESS Command sent to BMC successfully. + +**/ +EFI_STATUS +SendDataToBtBmcPort ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN VOID *Context, + IN UINT8 *Data, + IN UINT8 DataSize + ) +{ + UINT8 BtCntlData; + UINT8 Index; + UINT32 Retry; + UINTN BtCtrlPort; + UINTN BtComBufferPort; + IPMI_ACCESS_TYPE AccessType; + UINT8 TempDataSize; + BOOLEAN MultipleDataSend; + UINT32 BtRetryCount; + + MultipleDataSend =3D FALSE; + BtRetryCount =3D Interface->Bt.BtRetryCount; + AccessType =3D Interface->Bt.AccessType; + + // Get Bt Ports addresses. + GetBtPortAddresses ( + Interface, + &BtCtrlPort, + &BtComBufferPort ); + + do { + /* Wait for B_BUSY bit to clear (BMC ready to accept a request). + Default delay for each retry is 15 micro seconds.*/ + for (Retry =3D 0; Retry < BtRetryCount; Retry++) { + BtCntlData =3D IpmiBmcRead8 ( + AccessType, + BtCtrlPort ); + if (!(BtCntlData & IPMI_B_BUSY_BIT)) { + break; + } + MicroSecondDelay (IPMI_BT_DELAY_PER_RETRY); + } + + if (Retry =3D=3D BtRetryCount) { + return EFI_TIMEOUT; + } + + // Wait for H2B_ATN bit to clear (Acknowledgment of previous command= s). + for (Retry =3D 0; Retry < BtRetryCount; Retry++) { + BtCntlData =3D IpmiBmcRead8 ( + AccessType, + BtCtrlPort ); + if (!(BtCntlData & IPMI_H2B_ATN_BIT)) { + break; + } + MicroSecondDelay (IPMI_BT_DELAY_PER_RETRY); + } + + if (Retry =3D=3D BtRetryCount) { + return EFI_TIMEOUT; + } + + // Set CLR_WR_PTR. + BtCntlData =3D IPMI_CLR_WR_PTR_BIT; + IpmiBmcWrite8 ( + AccessType, + BtCtrlPort, + BtCntlData ); + + if (DataSize > Interface->Bt.HosttoBmcBufferSize ) { + TempDataSize =3D Interface->Bt.HosttoBmcBufferSize; + MultipleDataSend =3D TRUE; + } else { + TempDataSize =3D DataSize; + MultipleDataSend =3D FALSE; + } + + // Send each message byte out (write data to HOST2BMC buffer). + for (Index =3D 0; Index < TempDataSize; Index++) { + IpmiBmcWrite8 ( + AccessType, + BtComBufferPort, + *(Data + Index) ); + } + + // Set H2B_ATN bit to inform BMC that data is available. + BtCntlData =3D IPMI_H2B_ATN_BIT; + IpmiBmcWrite8 ( + AccessType, + BtCtrlPort, + BtCntlData ); + + //Command data size greater than available Input buffer size. + if (MultipleDataSend) { + Data =3D Data + TempDataSize; + DataSize -=3D TempDataSize; + + for (Retry =3D 0; Retry < BtRetryCount; Retry++) { + BtCntlData =3D IpmiBmcRead8 ( + AccessType, + BtCtrlPort ); + if ((BtCntlData & IPMI_B_BUSY_BIT)) { + break; + } + MicroSecondDelay (IPMI_BT_DELAY_PER_RETRY); + } + + if (Retry =3D=3D BtRetryCount) { + return EFI_TIMEOUT; + } + } + } while (MultipleDataSend); + + return EFI_SUCCESS; +} + +/** + Receives the Data from BT interface BMC port. + + @param[in] Interface Pointer to System interface. + @param[in] Context NULL here. + @param[out] Data Pointer to response data that is received from= BMC. + @param[out] DataSize Size of the response data. + + @retval EFI_NOT_READY Interface is not ready to receive data= . + @retval EFI_SUCCESS Data received from BMC successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + +**/ +EFI_STATUS +ReceiveBmcDataFromBtPort ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN VOID *Context, + OUT UINT8 *Data, + OUT UINT8 *DataSize + ) +{ + UINT8 BtCntlData; + UINT8 Length ; + UINT8 TempDataSize; + UINT8 Index; + UINT32 Retry; + UINTN BtCtrlPort; + UINTN BtComBufferPort; + IPMI_ACCESS_TYPE AccessType; + BOOLEAN MultipleDataReceive; + UINT32 BtRetryCount; + + Length =3D 0; + MultipleDataReceive =3D FALSE; + BtRetryCount =3D Interface->Bt.BtRetryCount; + AccessType =3D Interface->Bt.AccessType; + + // Get Bt Ports addresses. + GetBtPortAddresses ( + Interface, + &BtCtrlPort, + &BtComBufferPort ); + do { + /* Wait for B2H_ATN bit to be set,signaling data is available for ho= st. + Default delay for each retry is 15 micro seconds.*/ + for (Retry =3D 0; Retry < BtRetryCount; Retry++) { + BtCntlData =3D IpmiBmcRead8 ( + AccessType, + BtCtrlPort ); + if (BtCntlData & IPMI_B2H_ATN_BIT) { + break; + } + MicroSecondDelay (IPMI_BT_DELAY_PER_RETRY); + } + + if (Retry =3D=3D BtRetryCount) { + return EFI_TIMEOUT; + } + + // Set H_BUSY bit, indicating host is in process of reading data fro= m interface. + BtCntlData =3D IpmiBmcRead8 ( + AccessType, + BtCtrlPort ); + if (!(BtCntlData & IPMI_H_BUSY )) { + BtCntlData =3D IPMI_H_BUSY; // most bits are rw1c, so cle= ar them. + IpmiBmcWrite8 ( + AccessType, + BtCtrlPort, + BtCntlData ); + } + + // Clear B2H_ATN bit,to acknowledge receipt of message response. + BtCntlData =3D IPMI_B2H_ATN_BIT; // Most bits are rw1c, so clear= them. + IpmiBmcWrite8 ( + AccessType, + BtCtrlPort, + BtCntlData ); + + // Set CLR_RD_PTR bit. + BtCntlData =3D IPMI_CLR_RD_PTR_BIT; // Most bits are rw1c, so clear= them. + IpmiBmcWrite8 ( + AccessType, + BtCtrlPort, + BtCntlData ); + + if (!Length){ + // Read the data bytes from BMC. + Length =3D IpmiBmcRead8 ( + AccessType, + BtComBufferPort ); + if (Length =3D=3D 0x00) { + return EFI_INVALID_PARAMETER; + } + + IpmiBmcWrite8 ( + AccessType, + BtCtrlPort, + BtCntlData ); + + *DataSize =3D Length; + //Increment Length to include length field + Length++; + } + + if (Length > Interface->Bt.BmctoHostBufferSize) { + TempDataSize =3D Interface->Bt.BmctoHostBufferSize; + MultipleDataReceive =3D TRUE; + } else { + TempDataSize =3D Length; + MultipleDataReceive =3D FALSE; + } + + for (Index =3D 0; Index < TempDataSize; Index++) { + *(Data + Index) =3D IpmiBmcRead8 ( + AccessType, + BtComBufferPort ); + } + + // Clear H_BUSY bit indicating host is done reading data from BMC. + BtCntlData =3D IpmiBmcRead8 ( + AccessType, + BtCtrlPort ); + if (BtCntlData & IPMI_H_BUSY) { + BtCntlData =3D IPMI_H_BUSY; // Most bits are rw1c, so cle= ar them. + IpmiBmcWrite8 ( + AccessType, + BtCtrlPort, + BtCntlData ); + } + + if (MultipleDataReceive) { + Data =3D Data + TempDataSize; + Length -=3D TempDataSize; + } + } while (MultipleDataReceive); + + return EFI_SUCCESS; +} + +/** + BT interface send command implementation. + + @param[in] Interface Pointer to System interface. + @param[in] NetFunction Net function of the command. + @param[in] Lun Logical Unit Number of the command= . + @param[in] Command Command to be sent to BMC. + @param[in] CommandData Command data to be sent along with + Command. + @param[in] CommandDataSize Command Data size. + @param[out] ResponseData Pointer to the response data buffe= r. + @param[in, out] ResponseDataSize Pointer to the response data size. + @param[out] CompletionCode Pointer to completion code. + @param[in] InterfaceType Interface type. + @param[in] Context NULL here. + + @retval EFI_UNSUPPORTED Interface type is not supported. + @retval EFI_NOT_READY Interface is not initialized. + @retval EFI_ACCESS_DENIED Interface is locked. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_BAD_BUFFER_SIZE Invalid buffer size. + @retval EFI_DEVICE_ERROR Error completion code or data size + retrieved is small. + @retval EFI_BUFFER_TOO_SMALL Buffer is too small to update response + data. + @retval EFI_SUCCESS Command sent successfully. + @return Others Error status returned from BMC while + executing the command. + +**/ +EFI_STATUS +EFIAPI +IpmiBtSendCommandToBmc ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT8 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT8 *ResponseDataSize, + IN VOID *Context + ) +{ + + UINT8 DataSize; + EFI_STATUS Status; + UINT8 Seq; + UINT8 CmdDataBuffer[IPMI_MAX_BT_CMD_DATA_SIZE]; + IPMI_SYSTEM_INTERFACE Interface; + + Seq =3D 0; + Interface =3D This->Interface; + + if (Interface.Bt.InterfaceState !=3D IpmiInterfaceInitialized) { + return EFI_NOT_READY; + } + + if (((CommandData =3D=3D NULL) && (CommandDataSize !=3D 0)) || (This =3D= =3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + if ((ResponseDataSize =3D=3D NULL) || ((ResponseData =3D=3D NULL) && *Re= sponseDataSize)) { + return EFI_INVALID_PARAMETER; + } + + if (IpmiIsIpmiTransportlocked (&Interface.Bt.BtTransportLocked)) { + return EFI_ACCESS_DENIED; + } else { + IpmiTransportAcquireLock (&Interface.Bt.BtTransportLocked); + } + + CmdDataBuffer[0] =3D (UINT8)CommandDataSize + 0x03; + CmdDataBuffer[1] =3D (UINT8) ((NetFunction << 2) | (Lun & 0xfc)); + CmdDataBuffer[2] =3D Seq; + CmdDataBuffer[3] =3D Command; + + if (CommandDataSize > 0) { + if (CommandData =3D=3D NULL) { + IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked); + return EFI_INVALID_PARAMETER; + } + + if (CommandDataSize <=3D (IPMI_MAX_BT_CMD_DATA_SIZE - 4) ) { + CopyMem ( + &CmdDataBuffer[4], + CommandData, + CommandDataSize ); + } else { + IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked); + return EFI_BAD_BUFFER_SIZE; + } + } + + Status =3D SendDataToBtBmcPort ( + &Interface, + Context, + CmdDataBuffer, + (UINT8)(CommandDataSize + 4)); + + if (Status !=3D EFI_SUCCESS) { + Interface.Bt.BtSoftErrorCount++; + IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked); + return Status; + } + + DataSize =3D IPMI_MAX_BT_CMD_DATA_SIZE; + + Status =3D ReceiveBmcDataFromBtPort ( + &Interface, + Context, + CmdDataBuffer, + &DataSize); + + if (Status !=3D EFI_SUCCESS) { + Interface.Bt.BtSoftErrorCount++; + IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked); + return Status; + } + + if (IPMI_ERROR_COMPLETION_CODE(CmdDataBuffer[4])) { + + IpmiUpdateSoftErrorCount ( + CmdDataBuffer[4], + &Interface, + This->InterfaceType ); + + // Write completion code into return buffer if ipmi command returns= an error. + if (*ResponseDataSize) { + if (ResponseData) { + *ResponseData =3D CmdDataBuffer[4]; + } + *ResponseDataSize =3D 1; + } + IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked); + return EFI_DEVICE_ERROR; + } + + if (DataSize < 4) { + IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked); + return EFI_DEVICE_ERROR; + } + + if ((DataSize - 3) > *((UINT8 *)ResponseDataSize)) { + *ResponseDataSize =3D (UINT8) (DataSize - 3); + IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked); + return EFI_BUFFER_TOO_SMALL; + } + + // Copying the response data into ResponseData buffer. + CopyMem ( + ResponseData, + &CmdDataBuffer[4], + (DataSize - 3) ); + *ResponseDataSize =3D (UINT8) (DataSize - 3); + + IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked); + + return EFI_SUCCESS; +} + +/** + Execute the Get BT Interface Capability command and update the input + and output buffer value of Ipmi Instance. + + @param IpmiInstance Data structure pointer. + + @retval VOID +**/ + +VOID +GetBtInterfaceCapability ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ) +{ + EFI_STATUS Status; + IPMI_BT_INTERFACE_CAPABILITY_RES Responsedata; + UINT32 ResponseSize; + + ResponseSize =3D sizeof(IPMI_BT_INTERFACE_CAPABILITY_RES); + + Status =3D IpmiTransport2->IpmiSubmitCommand2 ( + IpmiTransport2, + IPMI_NETFN_APP, + BMC_LUN, + IPMI_APP_GET_BT_INTERFACE_CAPABILITY, + NULL, + 0, + (UINT8*) &Responsedata, + &ResponseSize ); + + if (EFI_ERROR(Status) || Responsedata.CompletionCode) { + DEBUG ((DEBUG_ERROR, " IPMI_APP_GET_BT_INTERFACE_CAPABILITY Status: = %r Completion code: %x\n", Status, Responsedata.CompletionCode)); + return; + } + + IpmiTransport2->Interface.Bt.HosttoBmcBufferSize =3D Responsedata.InputB= uffSize; + IpmiTransport2->Interface.Bt.BmctoHostBufferSize =3D Responsedata.Output= BuffSize; + + DEBUG ((DEBUG_ERROR, " InputBuffSize:%x OutBuffSize%x BtRetry %x Status= %r \n",IpmiTransport2->Interface.Bt.HosttoBmcBufferSize,IpmiTransport2->In= terface.Bt.BmctoHostBufferSize,Responsedata.RecommandedRetires, Status)); + + return; +} + + +/** + Initialize BT interface specific data. + + @param[in, out] Interface System interface pointer. + + @retval EFI_SUCCESS Interface is successfully initialized. + @retval Others Return status while initializing interface. + +**/ +EFI_STATUS +InitBtInterfaceData ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ) +{ + BMC_INTERFACE_STATUS BmcStatus; + EFI_STATUS Status; + + if (IpmiTransport2->Interface.Bt.InterfaceState =3D=3D IpmiInterfaceInit= ialized) { + return EFI_SUCCESS; + } + + IpmiTransport2->Interface.Bt.CtrlPort =3D FixedPcdGet16 (Pc= dBtControlPort); // BT Control Port + IpmiTransport2->Interface.Bt.ComBuffer =3D FixedPcdGet16 (Pc= dBtBufferPort); // BT Buffer Port + IpmiTransport2->Interface.Bt.IntMaskPort =3D FixedPcdGet16 (Pc= dBtInterruptMaskPort); // BT IntMask Port + IpmiTransport2->Interface.Bt.BtRetryCount =3D FixedPcdGet32 (Pc= dBtCommandRetryCounter); // BT retry count + IpmiTransport2->Interface.Bt.HosttoBmcBufferSize =3D FixedPcdGet8 (Pcd= BtBufferSize); // Host to Bmc Buffer Size. + IpmiTransport2->Interface.Bt.BmctoHostBufferSize =3D FixedPcdGet8 (Pcd= BtBufferSize); // Bmc to Host Buffer Size. + + if (FixedPcdGet8 (PcdIpmiDefaultAccessType)) { + IpmiTransport2->Interface.Bt.AccessType =3D IpmiIoAccess; + IpmiTransport2->Interface.Bt.MmioBaseAddress =3D 0; + IpmiTransport2->Interface.Bt.BaseAddressRange =3D 0; + } else { + IpmiTransport2->Interface.Bt.AccessType =3D IpmiMmioAccess; + IpmiTransport2->Interface.Bt.MmioBaseAddress =3D FixedPcdGet64(Pcd= MmioBaseAddress); + IpmiTransport2->Interface.Bt.BaseAddressRange =3D FixedPcdGet64(Pcd= BaseAddressRange); + } + + IpmiTransportReleaseLock (&IpmiTransport2->Interface.Bt.BtTransportLocke= d); + IpmiTransport2->Interface.Bt.InterfaceState =3D IpmiInterfaceInitialized= ; + + Status =3D CheckSelfTestByInterfaceType( + IpmiTransport2, + &BmcStatus, + SysInterfaceBt); + if (EFI_ERROR (Status) || (BmcStatus =3D=3D BmcStatusHardFail)) { + IpmiTransport2->Interface.Bt.InterfaceState =3D IpmiInterfaceInitErr= or; + return Status; + } + + GetBtInterfaceCapability (IpmiTransport2); + + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.inf b/Features/Intel/Out= OfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BtInterfac= eLib/BtInterfaceLib.inf new file mode 100644 index 0000000000..1dd4386204 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/BtInterfaceLib/BtInterfaceLib.inf @@ -0,0 +1,39 @@ +## @file BtInterfaceLib.inf +# +# INF description file for BtInterfaceLib common library. +# +# @copyright +# Copyright 2016 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D BtInterfaceLib + FILE_GUID =3D DAFB6AEE-0275-45E4-A33C-E3348149C5BF + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.1 + LIBRARY_CLASS =3D BtInterfaceLib + +[Sources] + BtInterfaceLib.c + +[Packages] + MdePkg/MdePkg.dec + IpmiFeaturePkg/IpmiFeaturePkg.dec + +[LibraryClasses] + TimerLib + BmcCommonInterfaceLib + +[Pcd] + gIpmiFeaturePkgTokenSpaceGuid.PcdBtCommandRetryCounter + gIpmiFeaturePkgTokenSpaceGuid.PcdBtControlPort + gIpmiFeaturePkgTokenSpaceGuid.PcdBtBufferPort + gIpmiFeaturePkgTokenSpaceGuid.PcdBtDelayPerRetry + gIpmiFeaturePkgTokenSpaceGuid.PcdBtInterruptMaskPort + gIpmiFeaturePkgTokenSpaceGuid.PcdBtBufferSize + gIpmiFeaturePkgTokenSpaceGuid.PcdBaseAddressRange + gIpmiFeaturePkgTokenSpaceGuid.PcdMmioBaseAddress + gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiDefaultAccessType diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.c b/Features/Inte= l/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbI= nterfaceLib/DxeIpmbInterfaceLib.c new file mode 100644 index 0000000000..c0d5ff02c8 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.c @@ -0,0 +1,94 @@ +/** @file DxeIpmbInterfaceLib.c + IPMB Transport Dxe phase Implementation library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include + +/** @internal + Send Ipmi command through Ipmb interface. + + @param[in] Interface Pointer to System interface. + @param[in] SlaveAddress I2C device slave address. + @param[in] RequestPacket Pointer to an EFI_I2C_REQUEST_PACKET + structure describing the I2C transaction. + + @return EFI_STATUS Status of the Send I2c command. + +**/ +EFI_STATUS +IpmiI2cSendCommand ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN UINTN SlaveAddress, + IN EFI_I2C_REQUEST_PACKET *RequestPacket + ) +{ + EFI_STATUS Status =3D EFI_NOT_FOUND; + EFI_I2C_MASTER_PROTOCOL *I2cMasterTransmit =3D NULL; + + I2cMasterTransmit =3D (EFI_I2C_MASTER_PROTOCOL *)Interface->Ipmb.IpmbInt= erfaceApiPtr; + + if (I2cMasterTransmit !=3D NULL) { + Status =3D I2cMasterTransmit->StartRequest ( + I2cMasterTransmit, + SlaveAddress, + RequestPacket, + NULL, + NULL ); + } + + DEBUG ((DEBUG_INFO, "I2cMasterTransmit->StartRequest Status =3D %r\n", S= tatus)); + return Status; +} + +/** @internal + Locate I2c Ppi/Protocol instance and initialize interface pointer. + + @param[in, out] Interface System interface pointer. + + @return EFI_STATUS Status returned from functions used. + +**/ +EFI_STATUS +IpmiGetI2cApiPtr ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ) +{ + EFI_STATUS Status; + EFI_I2C_MASTER_PROTOCOL *I2cMasterTransmit =3D NULL; + BMC_INTERFACE_STATUS BmcStatus; + + IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiGuid =3D gEfiI2cMasterPro= tocolGuid; + + // Locate the I2C DXE Protocol for Communication. + Status =3D gBS->LocateProtocol ( + &gEfiI2cMasterProtocolGuid, + NULL, + (VOID **)&I2cMasterTransmit ); + + if (EFI_ERROR (Status)) { + return Status; + } + + IpmiTransport2->Interface.Ipmb.InterfaceState =3D IpmiInterfaceInitializ= ed; + IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiPtr =3D (UINTN)I2cMasterT= ransmit; + + Status =3D CheckSelfTestByInterfaceType( + IpmiTransport2, + &BmcStatus, + SysInterfaceIpmb); + if (EFI_ERROR (Status) || (BmcStatus =3D=3D BmcStatusHardFail)) { + IpmiTransport2->Interface.Ipmb.InterfaceState =3D IpmiInterfaceInitE= rror; + } + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.inf b/Features/In= tel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Ipm= bInterfaceLib/DxeIpmbInterfaceLib.inf new file mode 100644 index 0000000000..641d7213d4 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.inf @@ -0,0 +1,38 @@ +## @file DxeIpmbInterfaceLib.inf +# +# INF description file for IpmbInterfaceLib Library for DXE and UEFI driv= ers. +# +# @copyright +# Copyright 2016 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D DxeIpmbInterfaceLib + FILE_GUID =3D 9068B213-4E53-427E-863C-8C7423509035 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.1 + LIBRARY_CLASS =3D IpmbInterfaceLib | DXE_DRIVER DXE_RUNTIME_DRIVER U= EFI_DRIVER UEFI_APPLICATION + +[Sources] + DxeIpmbInterfaceLib.c + IpmbInterfaceLibCommon.c + +[Packages] + MdePkg/MdePkg.dec + IpmiFeaturePkg/IpmiFeaturePkg.dec + +[LibraryClasses] + DebugLib + BaseMemoryLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + BmcCommonInterfaceLib + +[Protocols] + gEfiI2cMasterProtocolGuid + +[Pcd] + gIpmiFeaturePkgTokenSpaceGuid.PcdBmcSlaveAddress diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/IpmbInterfaceLib/IpmbInterfaceLibCommon.c b/Features/I= ntel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Ip= mbInterfaceLib/IpmbInterfaceLibCommon.c new file mode 100644 index 0000000000..fd0be85aa5 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/IpmbInterfaceLib/IpmbInterfaceLibCommon.c @@ -0,0 +1,351 @@ +/** @file IpmbInterfaceLibCommon.c + IPMB Transport implementation common library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include + +#define IPMI_BMC_SLAVE_ADDRESS FixedPcdGet32 (PcdBmcSlaveAddress) +/** @internal + Verify the data integrity using checksum of BMC response data. + + @param[in] ResponseData Response data from BMC. + @param[in] ResponseSize Data size of response data. + + @retval EFI_SUCCESS Data integrity is valid. + @retval EFI_INVALID_PARAMETER Invalid parameter. + +**/ +EFI_STATUS +CheckDataValidity ( + IN UINT8 *ResponseData, + IN UINT8 ResponseSize ) +{ + UINT8 Index; + UINT8 CheckSum =3D 0; + UINT8 DataSum =3D 0; + + // Calculate header checksum. + for (Index =3D 0; Index < 2; Index++) { + DataSum +=3D ResponseData[Index]; + } + + // Verify header checksum. + CheckSum =3D (UINT8) (0x100 - DataSum); + if (CheckSum !=3D ResponseData[2]) { + return EFI_INVALID_PARAMETER; + } + + DataSum =3D 0; + + // Calculate information checksum. + for (Index =3D 3; Index < (ResponseSize - 1); Index++) { + DataSum +=3D ResponseData[Index]; + } + + // Verify information checksum. + CheckSum =3D (UINT8) (0x100 - DataSum); + if (CheckSum !=3D ResponseData[ResponseSize - 1]) { + return EFI_INVALID_PARAMETER; + } + return EFI_SUCCESS; +} + +/** @internal + Sends the command/data to Ipmb interface. + + @param[in] Interface Pointer to System interface. + @param[in] Context NULL here. + @param[in] Data Pointer to command data that will be sent to B= MC + along with Command. + @param[in] DataSize Size of the command data. + + @return EFI_STATUS Status returned from I2C send command. + +**/ +EFI_STATUS +SendDataToIpmbBmcPort ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN VOID *Context, + IN UINT8 *Data, + IN UINT8 DataSize ) +{ + EFI_STATUS Status; + EFI_I2C_REQUEST_PACKET Packet; + + // Pack command data. + Packet.Operation[0].Buffer =3D Data; + Packet.Operation[0].LengthInBytes =3D DataSize; + Packet.Operation[0].Flags =3D IPMI_WRITE_FLAG; + + // Call the StartRequest function. + Status =3D IpmiI2cSendCommand ( + Interface, + IPMI_BMC_SLAVE_ADDRESS, + &Packet ); + + return Status; +} + +/** @internal + Receives the data from Ipmb interface. + + @param[in] Interface Pointer to System interface. + @param[in] Context NULL here. + @param[out] Data Pointer to response data that is received from= BMC. + @param[out] DataSize Size of the response data. + + @return EFI_STATUS Status returned from I2C send command. + +**/ +EFI_STATUS +ReceiveBmcDataFromIpmbPort ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN VOID *Context, + OUT UINT8 *Data, + OUT UINT8 *DataSize ) +{ + EFI_STATUS Status; + EFI_I2C_REQUEST_PACKET Packet; + + // Pack command data. + Packet.Operation[0].Buffer =3D Data; + Packet.Operation[0].Flags =3D IPMI_READ_FLAG; + + // Call the StartRequest function. + Status =3D IpmiI2cSendCommand ( + Interface, + IPMI_BMC_SLAVE_ADDRESS, + &Packet ); + + if (!EFI_ERROR(Status)) { + *DataSize =3D (UINT8)Packet.Operation[0].LengthInBytes; + } + return Status; +} + +/** @internal + IPMB interface send command implementation. + + @param[in] Interface Pointer to System interface. + @param[in] NetFunction Net function of the command. + @param[in] Lun Logical Unit Number of the command= . + @param[in] Command Command to be sent to BMC. + @param[in] CommandData Command data to be sent along with + Command. + @param[in] CommandDataSize Command Data size. + @param[out] ResponseData Pointer to the response data buffe= r. + @param[in, out] ResponseDataSize Pointer to the response data size. + @param[out] CompletionCode Pointer to completion code. + @param[in] InterfaceType Interface type. + @param[in] Context NULL here. + + @retval EFI_UNSUPPORTED Interface type is not supported. + @retval EFI_NOT_READY Interface is not initialized. + @retval EFI_ACCESS_DENIED Interface is locked. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_BAD_BUFFER_SIZE Invalid buffer size. + @retval EFI_DEVICE_ERROR Error completion code or data size + retrieved is small. + @retval EFI_BUFFER_TOO_SMALL Buffer is too small to update response + data. + @retval EFI_SUCCESS Command sent successfully. + @return Others Error status returned from BMC while + executing the command. + +**/ +EFI_STATUS +IpmiIpmbSendCommandToBmc ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT8 CommandDataSize, + OUT UINT8 *ResponseData, + IN OUT UINT8 *ResponseDataSize, + IN VOID *Context ) +{ + EFI_STATUS Status; + UINT8 DataSize; + UINT8 DataSum =3D 0; + UINT8 CheckSum =3D 0; + UINT8 Index; + UINT8 CmdDataBuffer[IPMI_MAX_IPMB_CMD_DATA_SIZE]; + IPMI_SYSTEM_INTERFACE Interface; + + Interface =3D This->Interface; + + if (Interface.Ipmb.InterfaceState !=3D IpmiInterfaceInitialized) { + return EFI_NOT_READY; + } + + if (!ResponseDataSize || (!ResponseData && *ResponseDataSize)) { + return EFI_INVALID_PARAMETER; + } + + if (IpmiIsIpmiTransportlocked (&Interface.Ipmb.IpmbTransportLocked)) { + return EFI_ACCESS_DENIED; + } else { + IpmiTransportAcquireLock (&Interface.Ipmb.IpmbTransportLocked); + } + + if (Interface.Ipmb.IpmbSoftErrorCount >=3D MAX_BMC_CMD_FAIL_COUNT) { + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return EFI_NOT_READY; + } + + /* Request Packet format. + | Slave Address | Netfun/Lun | CheckSum (Check Sum of previous data) + | Slave Address | Seq No | Command | Data 1..N + | CheckSum (Check Sum of previous data).*/ + CmdDataBuffer[0] =3D IPMI_BMC_SLAVE_ADDRESS; + CmdDataBuffer[1] =3D (UINT8) ((NetFunction << 2) | (Lun & 0x03)); + + DataSum +=3D CmdDataBuffer[1] + IPMI_BMC_SLAVE_ADDRESS; + CheckSum =3D (UINT8) (0x100 - DataSum); + DataSum =3D 0; + + CmdDataBuffer[2] =3D CheckSum; + + CmdDataBuffer[3] =3D IPMI_BMC_SLAVE_ADDRESS; + DataSum +=3D IPMI_BMC_SLAVE_ADDRESS; + + CmdDataBuffer[4] =3D IPMI_SEQ_NO; + DataSum +=3D IPMI_SEQ_NO; + + CmdDataBuffer[5] =3D Command; + DataSum +=3D Command; + + if (CommandDataSize > 0) { + if (CommandData =3D=3D NULL) { + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return EFI_INVALID_PARAMETER; + } + //Last data will be Checksum so limiting the Max command data to < I= PMI_MAX_IPMB_CMD_DATA_SIZE - 6 + if (CommandDataSize < (IPMI_MAX_IPMB_CMD_DATA_SIZE - 6)) { + CopyMem ( + &CmdDataBuffer[6], + CommandData, + CommandDataSize ); + } else { + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return EFI_BAD_BUFFER_SIZE; + } + for(Index =3D 0; Index < CommandDataSize; Index++) { + DataSum +=3D CmdDataBuffer[6 + Index]; + } + } + CheckSum =3D (UINT8) (0x100 - DataSum); // Find the checksum for the pa= cking data. + CmdDataBuffer[6] =3D CheckSum; // Update the checksum. + + if ((Status =3D SendDataToIpmbBmcPort ( + &Interface, + Context, + CmdDataBuffer, + (UINT8) (CommandDataSize + 7) ) ) !=3D EFI_SUCCESS) { + Interface.Ipmb.IpmbSoftErrorCount++; + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return Status; + } + + DataSize =3D IPMI_MAX_IPMB_CMD_DATA_SIZE; + if ((Status =3D ReceiveBmcDataFromIpmbPort ( + &Interface, + Context, + CmdDataBuffer, + &DataSize )) !=3D EFI_SUCCESS) { + Interface.Ipmb.IpmbSoftErrorCount++; + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return Status; + } + + /* Response Packet format. + | Slave Address | Netfun/Lun | CheckSum (Check Sum of previous data) + | Slave Address | Seq No | Command | Completion code| Data 1..N + | CheckSum (Check Sum of previous data).*/ + + // Calculate and verify checksum. + Status =3D CheckDataValidity ( + CmdDataBuffer, + DataSize ); + if (EFI_ERROR(Status)) { + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return Status; + } + + if (IPMI_ERROR_COMPLETION_CODE(CmdDataBuffer[6])) { + IpmiUpdateSoftErrorCount ( + CmdDataBuffer[6], + &Interface, + This->InterfaceType ); + // Write completion code into return buffer if an IPMI command retur= ns an error + if (*ResponseDataSize) { + if (ResponseData) { + *ResponseData =3D CmdDataBuffer[6]; + } + *ResponseDataSize =3D 1; + } + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return EFI_DEVICE_ERROR; + } + + if (DataSize < 8) { + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return EFI_DEVICE_ERROR; + } + if ((DataSize - 7) > *((UINT8 *)ResponseDataSize)) { + *ResponseDataSize =3D (UINT8) (DataSize - 7); + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return EFI_BUFFER_TOO_SMALL; + } + + // Copying the response data into ResponseData buffer. + CopyMem ( + ResponseData, + &CmdDataBuffer[6], + (DataSize - 7) ); + *ResponseDataSize =3D (UINT8) (DataSize - 7); + + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return EFI_SUCCESS; +} + +/** @internal + Initialize IPMB interface specific data. + + @param[in, out] Interface System interface pointer. + + @retval EFI_SUCCESS Interface is successfully initialized. + @retval Others Error status while initializing interface. + +**/ +EFI_STATUS +InitIpmbInterfaceData ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ) +{ + EFI_STATUS Status =3D EFI_SUCCESS; + + if (IpmiTransport2->Interface.Ipmb.InterfaceState =3D=3D IpmiInterfaceIn= itialized) { + return Status; + } + + Status =3D IpmiGetI2cApiPtr (IpmiTransport2); + + if (EFI_ERROR(Status)) { + IpmiTransport2->Interface.Ipmb.InterfaceState =3D IpmiInterfaceInitE= rror; + return Status; + } + + IpmiTransportReleaseLock (&IpmiTransport2->Interface.Ipmb.IpmbTransportL= ocked); + IpmiTransport2->Interface.Ipmb.InterfaceState =3D IpmiInterfaceInitializ= ed; + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.c b/Features/Inte= l/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbI= nterfaceLib/PeiIpmbInterfaceLib.c new file mode 100644 index 0000000000..e4db0b4b13 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.c @@ -0,0 +1,100 @@ +/** @file PeiIpmbInterfaceLib.c + IPMB Transport Pei phase implementation library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include + +/** @internal + Send Ipmi command through Ipmb interface. + + @param[in] Interface Pointer to System interface. + @param[in] SlaveAddress I2C device slave address. + @param[in] RequestPacket Pointer to an EFI_I2C_REQUEST_PACKET + structure describing the I2C transaction. + + @return EFI_STATUS Status of the Send I2c command. + +**/ +EFI_STATUS +IpmiI2cSendCommand ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN UINTN SlaveAddress, + IN EFI_I2C_REQUEST_PACKET *RequestPacket ) +{ + EFI_STATUS Status =3D EFI_NOT_FOUND; + EFI_PEI_I2C_MASTER_PPI *I2cMasterTransmit =3D NULL; + + I2cMasterTransmit =3D (EFI_PEI_I2C_MASTER_PPI *)Interface->Ipmb.IpmbIn= terfaceApiPtr; + + if (I2cMasterTransmit !=3D NULL) { + Status =3D I2cMasterTransmit->StartRequest ( + I2cMasterTransmit, + SlaveAddress, + RequestPacket ); + } + + DEBUG ((DEBUG_INFO, "%a I2cMasterTransmit->StartRequest Status =3D %r\= n", __FUNCTION__, Status)); + + return Status; +} + +/** @internal + Locate I2c Ppi/Protocol instance and initialize interface pointer. + + @param[in, out] Interface System interface pointer. + + @return EFI_STATUS Status returned from functions used. + +**/ +EFI_STATUS +IpmiGetI2cApiPtr ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 +) +{ + EFI_STATUS Status; + CONST EFI_PEI_SERVICES **PeiServices; + EFI_PEI_I2C_MASTER_PPI *I2cMasterTransmit =3D NULL; + BMC_INTERFACE_STATUS BmcStatus; + + PeiServices =3D GetPeiServicesTablePointer (); + + IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiGuid =3D gEfiPeiI2cMaster= PpiGuid; + + // Locate the I2C PPI for Communication. + Status =3D (*PeiServices)->LocatePpi ( + PeiServices, + &gEfiPeiI2cMasterPpiGuid, + 0, + NULL, + (VOID **)&I2cMasterTransmit ); + + DEBUG ((DEBUG_INFO, "%a (*PeiServices)->LocatePpi gEfiPeiI2cMasterPpiGui= d Status =3D %r\n", __FUNCTION__, Status)); + + if (EFI_ERROR (Status)) { + return Status; + } + + IpmiTransport2->Interface.Ipmb.InterfaceState =3D IpmiInterfaceInitializ= ed; + IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiPtr =3D (UINTN)I2cMasterT= ransmit; + + Status =3D CheckSelfTestByInterfaceType( + IpmiTransport2, + &BmcStatus, + SysInterfaceIpmb); + + if (EFI_ERROR (Status) || (BmcStatus =3D=3D BmcStatusHardFail)) { + IpmiTransport2->Interface.Ipmb.InterfaceState =3D IpmiInterfaceInitE= rror; + } + + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.inf b/Features/In= tel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Ipm= bInterfaceLib/PeiIpmbInterfaceLib.inf new file mode 100644 index 0000000000..85b19d74c8 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.inf @@ -0,0 +1,38 @@ +## @file PeiIpmbInterfaceLib.inf +# +# INF description file for IpmbInterfacePeiLib Library for PEIMs. +# +# @copyright +# Copyright 2016 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PeiIpmbInterfaceLib + FILE_GUID =3D 843DBE4E-4750-4335-9094-58645D897D62 + MODULE_TYPE =3D PEIM + VERSION_STRING =3D 1.1 + LIBRARY_CLASS =3D IpmbInterfaceLib | PEIM + +[Sources] + PeiIpmbInterfaceLib.c + IpmbInterfaceLibCommon.c + +[Packages] + MdePkg/MdePkg.dec + IpmiFeaturePkg/IpmiFeaturePkg.dec + +[LibraryClasses] + HobLib + DebugLib + BaseMemoryLib + PeiServicesTablePointerLib + BmcCommonInterfaceLib + +[Ppis] + gEfiPeiI2cMasterPpiGuid + +[Pcd] + gIpmiFeaturePkgTokenSpaceGuid.PcdBmcSlaveAddress diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.c b/Features/Inte= l/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbI= nterfaceLib/SmmIpmbInterfaceLib.c new file mode 100644 index 0000000000..2293e3154a --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.c @@ -0,0 +1,94 @@ +/** @file SmmIpmbInterfaceLib.c + IPMB Transport Smm phase implementation library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include + +/** @internal + Send Ipmi command through Ipmb interface. + + @param[in] Interface Pointer to System interface. + @param[in] SlaveAddress I2C device slave address. + @param[in] RequestPacket Pointer to an EFI_I2C_REQUEST_PACKET + structure describing the I2C transaction. + + @return EFI_STATUS Status of the Send I2c command. + +**/ +EFI_STATUS +IpmiI2cSendCommand ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN UINTN SlaveAddress, + IN EFI_I2C_REQUEST_PACKET *RequestPacket ) +{ + EFI_STATUS Status =3D EFI_NOT_FOUND; + EFI_I2C_MASTER_PROTOCOL *I2cMasterTransmit =3D NULL; + + I2cMasterTransmit =3D (EFI_I2C_MASTER_PROTOCOL *)Interface->Ipmb.IpmbI= nterfaceApiPtr; + + if (I2cMasterTransmit !=3D NULL) { + Status =3D I2cMasterTransmit->StartRequest ( + I2cMasterTransmit, + SlaveAddress, + RequestPacket, + NULL, + NULL ); + } + + DEBUG ((DEBUG_INFO, "%a I2cMasterTransmit->StartRequest Status =3D %r\= n", __FUNCTION__, Status)); + + return Status; +} + +/** @internal + Locate I2c Ppi/Protocol instance and initialize interface pointer. + + @param[in, out] Interface System interface pointer. + + @return EFI_STATUS Status returned from functions used. + +**/ +EFI_STATUS +IpmiGetI2cApiPtr ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 +) +{ + EFI_STATUS Status; + EFI_I2C_MASTER_PROTOCOL *I2cMasterTransmit =3D NULL; + BMC_INTERFACE_STATUS BmcStatus; + + IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiGuid =3D gEfiI2cMasterP= rotocolGuid; + + // Locate the I2C SMM Protocol for Communication. + Status =3D gSmst->SmmLocateProtocol ( + &gEfiI2cMasterProtocolGuid, + NULL, + (VOID **)&I2cMasterTransmit ); + + DEBUG ((DEBUG_INFO, "%a SmmLocateProtocol gEfiI2cMasterProtocolGuid St= atus =3D %r\n", __FUNCTION__, Status)); + + if (EFI_ERROR(Status)) { + return Status; + } + + IpmiTransport2->Interface.Ipmb.InterfaceState =3D IpmiInterfaceInitial= ized; + IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiPtr =3D (UINTN)I2cMaste= rTransmit; + + Status =3D CheckSelfTestByInterfaceType( + IpmiTransport2, + &BmcStatus, + SysInterfaceIpmb); + if (EFI_ERROR (Status) || (BmcStatus =3D=3D BmcStatusHardFail)) { + IpmiTransport2->Interface.Ipmb.InterfaceState =3D IpmiInterfaceIni= tError; + } + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.inf b/Features/In= tel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Ipm= bInterfaceLib/SmmIpmbInterfaceLib.inf new file mode 100644 index 0000000000..2d3c089ef2 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.inf @@ -0,0 +1,37 @@ +## @file SmmAmiIpmbInterfaceLib.inf +# +# INF description file for SmmAmiIpmbInterfaceLib Library for DXE SMM dri= vers. +# +# @copyright +# Copyright 2016 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SmmIpmbInterfaceLib + FILE_GUID =3D C39F9DC3-37C7-41C1-BE05-8C1524493947 + MODULE_TYPE =3D DXE_SMM_DRIVER + VERSION_STRING =3D 1.1 + LIBRARY_CLASS =3D IpmbInterfaceLib | DXE_SMM_DRIVER + +[Sources] + SmmIpmbInterfaceLib.c + IpmbInterfaceLibCommon.c + +[Packages] + MdePkg/MdePkg.dec + IpmiFeaturePkg/IpmiFeaturePkg.dec + +[LibraryClasses] + DebugLib + BaseMemoryLib + SmmServicesTableLib + BmcCommonInterfaceLib + +[Protocols] + gEfiI2cMasterProtocolGuid + +[Pcd] + gIpmiFeaturePkgTokenSpaceGuid.PcdBmcSlaveAddress diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.c b/Features/Inte= l/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifI= nterfaceLib/DxeSsifInterfaceLib.c new file mode 100644 index 0000000000..60b2b8e016 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.c @@ -0,0 +1,131 @@ +/** @file DxeSsifInterfaceLib.c + SSIF Transport Dxe phase Implementation library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Send Ipmi command through Smbus instance. + + @param[in] Interface Pointer to System interface. + @param[in] SlaveAddress The SMBUS hardware address. + @param[in] Command This command is transmitted by the SMB= us + host controller to the SMBus slave dev= ice. + @param[in] Operation Operation to be performed. + @param[in] PecCheck Defines if Packet Error Code (PEC) + checking is required for this operatio= n. + @param[in, out] Length Signifies the number of bytes that thi= s + operation will do. + @param[in, out] Buffer Contains the value of data to execute = to + the SMBus slave device. The length of + this buffer is identified by Length. + + @retval EFI_NOT_FOUND Smbus instance is not found. + @retval Others Return status of the Smbus Execute operation. + +**/ +EFI_STATUS +IpmiSmbusSendCommand ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + EFI_SMBUS_HC_PROTOCOL *EfiSmbusHcProtocol; + + Status =3D EFI_NOT_FOUND; + EfiSmbusHcProtocol =3D (EFI_SMBUS_HC_PROTOCOL *)Interface->Ssif.SsifInte= rfaceApiPtr; + + if (EfiSmbusHcProtocol !=3D NULL) { + Status =3D EfiSmbusHcProtocol->Execute ( + EfiSmbusHcProtocol, + SlaveAddress, + Command, + Operation, + PecCheck, + Length, + Buffer ); + } + + DEBUG ((DEBUG_INFO, "EfiSmbusHcProtocol->Execute Status =3D %r\n", Statu= s)); + return Status; +} + +/** + Locate Smbus instance and initialize interface pointer. + + @param[in, out] Interface System interface pointer. + + @return EFI_STATUS Status returned while locating smbus instance. + +**/ +EFI_STATUS +IpmiGetSmbusApiPtr ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ) +{ + EFI_STATUS Status; + EFI_SMBUS_HC_PROTOCOL *EfiSmbusHcProtocol; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + UINTN Index; + BMC_INTERFACE_STATUS BmcStatus; + + IpmiTransport2->Interface.Ssif.SsifInterfaceApiGuid =3D gEfiSmbusHcProto= colGuid; + + Status =3D gBS->LocateHandleBuffer( + ByProtocol, + &gEfiSmbusHcProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + for (Index =3D 0; Index < HandleCount; Index++) { + Status =3D gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiSmbusHcProtocolGuid, + (VOID **)&EfiSmbusHcProtocol ); + if (EFI_ERROR (Status)) { + continue; + } + + IpmiTransport2->Interface.Ssif.InterfaceState =3D IpmiInterfaceInit= ialized; + IpmiTransport2->Interface.Ssif.SsifInterfaceApiPtr =3D (UINTN)EfiSm= busHcProtocol; + + Status =3D CheckSelfTestByInterfaceType( + IpmiTransport2, + &BmcStatus, + SysInterfaceSsif); + if (EFI_ERROR (Status) || (BmcStatus =3D=3D BmcStatusHardFail)) { + IpmiTransport2->Interface.Ssif.InterfaceState =3D IpmiInterface= InitError; + continue; + } + + GetSystemInterfaceCapability (IpmiTransport2); + GetGlobalEnables (IpmiTransport2); + break; + } + + FreePool(HandleBuffer); + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.inf b/Features/In= tel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Ssi= fInterfaceLib/DxeSsifInterfaceLib.inf new file mode 100644 index 0000000000..d9120b220c --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.inf @@ -0,0 +1,40 @@ +## @file DxeSsifInterfaceLib.inf +# +# INF description file for SsifInterfaceLib Library for DXE and UEFI driv= ers. +# +# @copyright +# Copyright 2016 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D DxeSsifInterfaceLib + FILE_GUID =3D AD66E7C3-FE13-4849-970E-118347FFE857 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.1 + LIBRARY_CLASS =3D SsifInterfaceLib | DXE_DRIVER DXE_RUNTIME_DRIVER U= EFI_DRIVER UEFI_APPLICATION + +[Sources] + DxeSsifInterfaceLib.c + SsifInterfaceLibCommon.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IpmiFeaturePkg/IpmiFeaturePkg.dec + +[LibraryClasses] + UefiLib + MemoryAllocationLib + BmcCommonInterfaceLib + +[Protocols] + gEfiSmbusHcProtocolGuid + +[Pcd] + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifSlaveAddress + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifCommandtRetryCounter + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.c b/Features/Inte= l/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifI= nterfaceLib/PeiSsifInterfaceLib.c new file mode 100644 index 0000000000..0cb7e4afd1 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.c @@ -0,0 +1,123 @@ +/** @file PeiSsifInterfaceLib.c + SSIF Transport Pei phase Implementation library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include + +/** + Send Ipmi command through Smbus instance. + + @param[in] Interface Pointer to System interface. + @param[in] SlaveAddress The SMBUS hardware address. + @param[in] Command This command is transmitted by the SMB= us + host controller to the SMBus slave dev= ice. + @param[in] Operation Operation to be performed. + @param[in] PecCheck Defines if Packet Error Code (PEC) + checking is required for this operatio= n. + @param[in, out] Length Signifies the number of bytes that thi= s + operation will do. + @param[in, out] Buffer Contains the value of data to execute = to + the SMBus slave device. The length of + this buffer is identified by Length. + + @retval EFI_NOT_FOUND Smbus instance is not found. + @retval Others Return status of the Smbus Execute operation. + +**/ +EFI_STATUS +IpmiSmbusSendCommand ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + EFI_PEI_SMBUS2_PPI *EfiPeiSmbus2Ppi; + + Status =3D EFI_NOT_FOUND; + EfiPeiSmbus2Ppi =3D (EFI_PEI_SMBUS2_PPI *)Interface->Ssif.SsifInterfaceA= piPtr; + + if (EfiPeiSmbus2Ppi !=3D NULL) { + Status =3D EfiPeiSmbus2Ppi->Execute ( + EfiPeiSmbus2Ppi, + SlaveAddress, + Command, + Operation, + PecCheck, + Length, + Buffer ); + } + + DEBUG ((DEBUG_INFO, "%a EfiPeiSmbus2Ppi->Execute Status =3D %r\n", __FUN= CTION__, Status)); + return Status; +} + +/** + Locate Smbus instance and initialize interface pointer. + + @param[in, out] Interface System interface pointer. + + @return EFI_STATUS Status returned while locating smbus instance. + +**/ +EFI_STATUS +IpmiGetSmbusApiPtr ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 +) +{ + EFI_STATUS Status; + UINTN Instance; + CONST EFI_PEI_SERVICES **PeiServices; + EFI_PEI_SMBUS2_PPI *EfiPeiSmbus2Ppi; + BMC_INTERFACE_STATUS BmcStatus; + + PeiServices =3D GetPeiServicesTablePointer (); + + IpmiTransport2->Interface.Ssif.SsifInterfaceApiGuid =3D gEfiPeiSmbus2Pp= iGuid; + + // Traverse all Smbus2 PPI instances and find the right instance for SSI= F. + for (Instance =3D 0; ; Instance++) { + // Locate the Smbus Ppi. + Status =3D (*PeiServices)->LocatePpi ( + PeiServices, + &gEfiPeiSmbus2PpiGuid, + Instance, + NULL, + (VOID **)&EfiPeiSmbus2Ppi ); + if (EFI_ERROR (Status)) { + break; + } + + IpmiTransport2->Interface.Ssif.InterfaceState =3D IpmiInterfaceInit= ialized; + IpmiTransport2->Interface.Ssif.SsifInterfaceApiPtr =3D (UINTN)EfiPe= iSmbus2Ppi; + + Status =3D CheckSelfTestByInterfaceType( + IpmiTransport2, + &BmcStatus, + SysInterfaceSsif); + if (EFI_ERROR (Status) || (BmcStatus =3D=3D BmcStatusHardFail)) { + IpmiTransport2->Interface.Ssif.InterfaceState =3D IpmiInterface= InitError; + continue; + } + + GetSystemInterfaceCapability (IpmiTransport2); + GetGlobalEnables (IpmiTransport2); + break; + } + + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.inf b/Features/In= tel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Ssi= fInterfaceLib/PeiSsifInterfaceLib.inf new file mode 100644 index 0000000000..b3aad43671 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.inf @@ -0,0 +1,41 @@ +## @file PeiSsifInterfaceLib.inf +# +# INF description file for SsifInterfaceLib Library for PEIMs. +# +# @copyright +# Copyright 2016 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PeiSsifInterfaceLib + FILE_GUID =3D EDA631E3-DC66-4120-BADF-B6BA73B6ABD4 + MODULE_TYPE =3D PEIM + VERSION_STRING =3D 1.1 + LIBRARY_CLASS =3D SsifInterfaceLib | PEIM + +[Sources] + PeiSsifInterfaceLib.c + SsifInterfaceLibCommon.c + +[Packages] + MdePkg/MdePkg.dec + IpmiFeaturePkg/IpmiFeaturePkg.dec + +[LibraryClasses] + DebugLib + TimerLib + BaseMemoryLib + PeiServicesTablePointerLib + BmcCommonInterfaceLib + +[Ppis] + gEfiPeiSmbus2PpiGuid + +[Pcd] + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifSlaveAddress + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifCommandtRetryCounter + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.c b/Features/Inte= l/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifI= nterfaceLib/SmmSsifInterfaceLib.c new file mode 100644 index 0000000000..4fb4a889ed --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.c @@ -0,0 +1,148 @@ +/** @file SmmSsifInterfaceLib.c + SSIF Transport SMM phase Implementation library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Send Ipmi command through Smbus instance. + + @param[in] Interface Pointer to System interface. + @param[in] SlaveAddress The SMBUS hardware address. + @param[in] Command This command is transmitted by the SMB= us + host controller to the SMBus slave dev= ice. + @param[in] Operation Operation to be performed. + @param[in] PecCheck Defines if Packet Error Code (PEC) + checking is required for this operatio= n. + @param[in, out] Length Signifies the number of bytes that thi= s + operation will do. + @param[in, out] Buffer Contains the value of data to execute = to + the SMBus slave device. The length of + this buffer is identified by Length. + + @retval EFI_NOT_FOUND Smbus instance is not found. + @retval Others Return status of the Smbus Execute operation. + +**/ +EFI_STATUS +IpmiSmbusSendCommand ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + EFI_SMBUS_HC_PROTOCOL *EfiSmbusHcProtocol; + + Status =3D EFI_NOT_FOUND; + EfiSmbusHcProtocol =3D (EFI_SMBUS_HC_PROTOCOL *)Interface->Ssif.SsifInte= rfaceApiPtr; + + if (EfiSmbusHcProtocol !=3D NULL) { + Status =3D EfiSmbusHcProtocol->Execute ( + EfiSmbusHcProtocol, + SlaveAddress, + Command, + Operation, + PecCheck, + Length, + Buffer ); + } + + DEBUG ((DEBUG_INFO, "%a EfiSmbusHcProtocol->Execute Status =3D %r\n", __= FUNCTION__, Status)); + + return Status; +} + +/** + Locate Smbus instance and initialize interface pointer. + + @param[in, out] Interface System interface pointer. + + @return EFI_STATUS Status returned while locating smbus instance. + +**/ +EFI_STATUS +IpmiGetSmbusApiPtr ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 +) +{ + EFI_STATUS Status; + EFI_SMBUS_HC_PROTOCOL *EfiSmbusHcProtocol; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer =3D NULL; + UINTN Index; + BMC_INTERFACE_STATUS BmcStatus; + + IpmiTransport2->Interface.Ssif.SsifInterfaceApiGuid =3D gEfiSmbusHcProto= colGuid; + HandleCount =3D 0; + + Status =3D gSmst->SmmLocateHandle ( + ByProtocol, + &gEfiSmbusHcProtocolGuid, + NULL, + &HandleCount, + HandleBuffer ); + if (EFI_ERROR (Status) && Status =3D=3D EFI_BUFFER_TOO_SMALL) { + // Allocate memory for Handle buffer + HandleBuffer =3D AllocateZeroPool (HandleCount); + if (HandleBuffer =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + Status =3D gSmst->SmmLocateHandle ( + ByProtocol, + &gEfiSmbusHcProtocolGuid, + NULL, + &HandleCount, + HandleBuffer ); + if (EFI_ERROR (Status)) { + // Free HandleBuffer memory + FreePool(HandleBuffer); + return EFI_NOT_FOUND; + } + } + + for (Index =3D 0; Index < HandleCount; Index++) { + Status =3D gSmst->SmmHandleProtocol ( + HandleBuffer[Index], + &gEfiSmbusHcProtocolGuid, + (VOID **)&EfiSmbusHcProtocol ); + if (EFI_ERROR (Status)) { + continue; + } + IpmiTransport2->Interface.Ssif.InterfaceState =3D IpmiInterfaceInit= ialized; + IpmiTransport2->Interface.Ssif.SsifInterfaceApiPtr =3D (UINTN)EfiSm= busHcProtocol; + + Status =3D CheckSelfTestByInterfaceType( + IpmiTransport2, + &BmcStatus, + SysInterfaceSsif); + if (EFI_ERROR (Status) || (BmcStatus =3D=3D BmcStatusHardFail)) { + IpmiTransport2->Interface.Ssif.InterfaceState =3D IpmiInterface= InitError; + continue; + } + + GetSystemInterfaceCapability (IpmiTransport2); + GetGlobalEnables (IpmiTransport2); + break; + } + + FreePool(HandleBuffer); + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.inf b/Features/In= tel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Ssi= fInterfaceLib/SmmSsifInterfaceLib.inf new file mode 100644 index 0000000000..a7e25647e2 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.inf @@ -0,0 +1,40 @@ +## @file SmmSsifInterfaceLib.inf +# +# INF description file for SsifInterfaceLib Library for DXE SMM drivers. +# +# @copyright +# Copyright 2016 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SmmSsifInterfaceLib + FILE_GUID =3D DB817B63-FA26-44FA-BF84-8D48596F982B + MODULE_TYPE =3D DXE_SMM_DRIVER + VERSION_STRING =3D 1.1 + LIBRARY_CLASS =3D SsifInterfaceLib | DXE_SMM_DRIVER + +[Sources] + SmmSsifInterfaceLib.c + SsifInterfaceLibCommon.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IpmiFeaturePkg/IpmiFeaturePkg.dec + +[LibraryClasses] + SmmServicesTableLib + MemoryAllocationLib + BmcCommonInterfaceLib + +[Protocols] + gEfiSmbusHcProtocolGuid + +[Pcd] + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifSlaveAddress + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifCommandtRetryCounter + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/SsifInterfaceLib/SsifInterfaceLibCommon.c b/Features/I= ntel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Ss= ifInterfaceLib/SsifInterfaceLibCommon.c new file mode 100644 index 0000000000..5b6feb194f --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/SsifInterfaceLibCommon.c @@ -0,0 +1,546 @@ +/** @file SsifInterfaceLibCommon.c + SSIF Transport Implementation common functions and variables. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include + +SSIF_ALERT_PIN_CHECK *gSsifAlertPinCheckHookList[] =3D +{ + NULL +}; + +/** + Check the SMBUS alert pin status function + + @param VOID Nothing. + + @retval TRUE Alert pin status is set. + @retval FALSE Alert pin status is not set. + +**/ +BOOLEAN +CheckAlertPinHook ( + VOID + ) +{ + BOOLEAN CheckAlertSignal =3D FALSE; + UINTN Index; + + for (Index =3D 0; gSsifAlertPinCheckHookList[Index]; Index++) { + CheckAlertSignal =3D gSsifAlertPinCheckHookList[Index](); + } + + return CheckAlertSignal; +} + +/** + Sends the command/data to Ssif interface. + + @param[in] Interface Pointer to System interface. + @param[in] Context NULL here. + @param[in] Data Pointer to command data that will be sent to B= MC + along with Command. + @param[in] DataSize Size of the command data. + + @return EFI_STATUS Status returned from Smbus send command. + +**/ +EFI_STATUS +SendDataToSsifBmcPort ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN VOID *Context, + IN UINT8 *Data, + IN UINT8 DataSize + ) +{ + EFI_STATUS Status; + EFI_SMBUS_DEVICE_ADDRESS BmcAddress; + UINTN IpmiWriteCommand; + UINT8 IpmiData[IPMI_SMBUS_BLOCK_LENGTH]; + UINTN DataLength; + UINT8 DataIndex; + BOOLEAN PECSupport; + UINT8 RetryCount; + UINT8 OriginalDataSize; + + DataLength =3D DataSize; + DataIndex =3D 0; + RetryCount =3D 0; + OriginalDataSize =3D DataSize; + PECSupport =3D Interface->Ssif.PecSupport; + BmcAddress.SmbusDeviceAddress =3D FixedPcdGet16 (PcdSsifSlaveAddress); + ZeroMem (IpmiData, sizeof(IpmiData)); + + do { + if (OriginalDataSize =3D=3D DataSize) { + if (DataSize <=3D IPMI_SMBUS_BLOCK_LENGTH) { + // Working single writes start. + DataLength =3D DataSize; + IpmiWriteCommand =3D IPMI_SMBUS_SINGLE_WRITE_CMD; + CopyMem ( + IpmiData, + &Data[DataIndex*IPMI_SMBUS_BLOCK_LENGTH], + DataLength ); + } else { + // Working multi-part writes start. + IpmiWriteCommand =3D IPMI_SMBUS_MULTI_WRITE_START_CMD; + DataLength =3D IPMI_SMBUS_BLOCK_LENGTH; + CopyMem ( + IpmiData, + &Data[DataIndex*IPMI_SMBUS_BLOCK_LENGTH], + DataLength ); + } + } else { + if (DataSize > IPMI_SMBUS_BLOCK_LENGTH) { + // Working multi-part writes middle. + IpmiWriteCommand =3D IPMI_SMBUS_MULTI_WRITE_MIDDLE_CMD; + DataLength =3D IPMI_SMBUS_BLOCK_LENGTH; + CopyMem ( + IpmiData, + &Data[DataIndex*IPMI_SMBUS_BLOCK_LENGTH], + DataLength ); + } else { + // Working multi-part writes end. + IpmiWriteCommand =3D IPMI_SMBUS_MULTI_WRITE_END_CMD; + DataLength =3D DataSize; + CopyMem ( + IpmiData, + &Data[DataIndex*IPMI_SMBUS_BLOCK_LENGTH], + DataLength ); + } + } + + Status =3D IpmiSmbusSendCommand ( + Interface, + BmcAddress, + IpmiWriteCommand, + EfiSmbusWriteBlock, + PECSupport, + &DataLength, + IpmiData ); + if (!EFI_ERROR(Status)) { + if (DataSize >=3D IPMI_SMBUS_BLOCK_LENGTH) { + RetryCount =3D 0; + DataSize -=3D IPMI_SMBUS_BLOCK_LENGTH; + DataIndex++; + } else { + DataSize =3D 0; + } + } else { + if (RetryCount =3D=3D Interface->Ssif.SsifRetryCounter) { + break; + } else { + RetryCount++; + // Failed retries delay about 60ms to 250ms. + MicroSecondDelay (FixedPcdGet32 (PcdSsifRequestRetriesDelay)= ); + /* If the Multi-part write fails, then try to write the + data from the beginning.*/ + if (IpmiWriteCommand !=3D IPMI_SMBUS_SINGLE_WRITE_CMD) { + DataSize =3D OriginalDataSize; + DataIndex =3D 0; + } + } + } + + } while (DataSize); + return Status; +} + +/** + Receives the Data from BMC port + + @param[in] Interface Pointer to System interface. + @param[in] Context NULL here. + @param[out] Data Pointer to response data that is received from + BMC. + @param[out] DataSize Size of the response data. + + @retval EFI_SUCCESS Data received from BMC successfully. + @retval Others Status of the Receiving data to BMC port. + + @return EFI_STATUS Status returned from Smbus send command. + +**/ +EFI_STATUS +ReceiveBmcDataFromSsifPort ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN VOID *Context, + OUT UINT8 *Data, + OUT UINT8 *DataSize + ) +{ + EFI_STATUS Status; + EFI_SMBUS_DEVICE_ADDRESS BmcAddress; + UINTN IpmiReadCommand; + UINT8 IpmiData[IPMI_SMBUS_BLOCK_LENGTH]; + UINTN DataLength; + BOOLEAN PECSupport; + UINT8 RetryCount; + UINT8 OriginalDataSize; + + DataLength =3D *DataSize; + RetryCount =3D 0; + OriginalDataSize =3D *DataSize; + PECSupport =3D Interface->Ssif.PecSupport; + BmcAddress.SmbusDeviceAddress =3D FixedPcdGet16 (PcdSsifSlaveAddress); + IpmiReadCommand =3D IPMI_SMBUS_SINGLE_READ_CMD; + + while (RetryCount <=3D Interface->Ssif.SsifRetryCounter) { + + Status =3D IpmiSmbusSendCommand ( + Interface, + BmcAddress, + IpmiReadCommand, + EfiSmbusReadBlock, + PECSupport, + &DataLength, + (VOID *)IpmiData ); + if (EFI_ERROR(Status)) { + RetryCount++; + // Failed retries delay about 60ms to 250ms. + MicroSecondDelay (FixedPcdGet32 (PcdSsifRequestRetriesDelay)); + /* If the Multi-part Read command fails, then try to read the + data from the beginning.*/ + if (IpmiReadCommand !=3D IPMI_SMBUS_SINGLE_READ_CMD) { + IpmiReadCommand =3D IPMI_SMBUS_SINGLE_READ_CMD; + } + DataLength =3D OriginalDataSize; + continue; + } + + if (IpmiReadCommand =3D=3D IPMI_SMBUS_SINGLE_READ_CMD) { + if ((IpmiData[0] =3D=3D IPMI_MULTI_READ_ZEROTH_STRT_BIT) && + (IpmiData[1] =3D=3D IPMI_MULTI_READ_FIRST_STRT_BIT)) { + // Working multi-part reads start. + CopyMem ( + Data, + &IpmiData[2], + DataLength-2 ); + *DataSize =3D (UINT8)DataLength-2; + IpmiReadCommand =3D IPMI_SMBUS_MULTI_READ_MIDDLE_CMD; + } else { + // Working single reads start. + CopyMem ( + Data, + IpmiData, + DataLength ); + *DataSize =3D (UINT8)DataLength; + break; + } + } else { + if(IpmiData[0] =3D=3D 0xFF) { + // Working multi-part reads end. + CopyMem ( + &Data[*DataSize], + &IpmiData[1], + DataLength-1 ); + *DataSize +=3D (UINT8)DataLength-1; + break; + } else { + // Working multi-part reads middle. + CopyMem ( + &Data[*DataSize], + &IpmiData[1], + DataLength-1 ); + *DataSize +=3D (UINT8)DataLength-1; + IpmiReadCommand =3D IPMI_SMBUS_MULTI_READ_MIDDLE_CMD; + } + } + } + + return Status; +} + +/** @internal + SSIF interface Ipmi send command Implementation + + @param[in] Interface Pointer to System interface. + @param[in] NetFunction Net function of the command. + @param[in] Lun Logical Unit Number of the command= . + @param[in] Command Command to be sent to BMC. + @param[in] CommandData Command data to be sent along with + Command. + @param[in] CommandDataSize Command Data size. + @param[out] ResponseData Pointer to the response data buffe= r. + @param[in, out] ResponseDataSize Pointer to the response data size. + @param[out] CompletionCode Pointer to completion code. + @param[in] InterfaceType Interface type. + @param[in] Context NULL here. + + @retval EFI_UNSUPPORTED Interface type is not supported. + @retval EFI_NOT_READY Interface is not initialized. + @retval EFI_ACCESS_DENIED Interface is locked. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_BAD_BUFFER_SIZE Invalid buffer size. + @retval EFI_DEVICE_ERROR Error completion code or data size + retrieved is small. + @retval EFI_BUFFER_TOO_SMALL Buffer is too small to update + response data. + @retval EFI_SUCCESS Command sent successfully. + @return Others Error status returned from BMC while + executing the command. + +**/ +EFI_STATUS +EFIAPI +IpmiSsifSendCommandToBmc ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT8 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT8 *ResponseDataSize, + IN VOID *Context +) +{ + EFI_STATUS Status; + UINT8 DataSize; + UINT8 CmdDataBuffer[IPMI_MAX_SSIF_CMD_DATA_SIZE]; + IPMI_SYSTEM_INTERFACE Interface; + + Interface =3D This->Interface; + + if (Interface.Ssif.InterfaceState !=3D IpmiInterfaceInitialized) { + return EFI_NOT_READY; + } + + if (((CommandData =3D=3D NULL) && (CommandDataSize!=3D 0)) || (This =3D= =3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + if ((ResponseDataSize =3D=3D NULL) || ((ResponseData =3D=3D NULL) && *Re= sponseDataSize)) { + return EFI_INVALID_PARAMETER; + } + + if (IpmiIsIpmiTransportlocked (&Interface.Ssif.SsifTransportLocked)) { + return EFI_ACCESS_DENIED; + } else { + IpmiTransportAcquireLock (&Interface.Ssif.SsifTransportLocked); + } + + // Check the SSIF interface multi-part reads/writes supported. + // Block length include Command data, NetFn, and Command parameter. + if (((Interface.Ssif.RwSupport =3D=3D SsifSinglePartRw) && + ((CommandDataSize + 2) > IPMI_SMBUS_BLOCK_LENGTH)) || + ((Interface.Ssif.RwSupport =3D=3D SsifMultiPartRw) && + ((CommandDataSize + 2) > (2*IPMI_SMBUS_BLOCK_LENGTH))) || + ((Interface.Ssif.RwSupport =3D=3D SsifMultiPartRwWithMiddle) && + ((CommandDataSize + 2) > IPMI_MAX_SSIF_CMD_DATA_SIZE))) { + + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_INVALID_PARAMETER; + } + + if (Interface.Ssif.SsifSoftErrorCount >=3D MAX_BMC_CMD_FAIL_COUNT) { + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_NOT_READY; + } + + CmdDataBuffer[0] =3D (UINT8) ((NetFunction << 2) | (Lun & 0x03)); + CmdDataBuffer[1] =3D Command; + + if (CommandDataSize > 0) { + if (CommandData =3D=3D NULL) { + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_INVALID_PARAMETER; + } + if (CommandDataSize <=3D (IPMI_MAX_SSIF_CMD_DATA_SIZE - 2) ) { + CopyMem ( + &CmdDataBuffer[2], + CommandData, + CommandDataSize ); + } else { + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_BAD_BUFFER_SIZE; + } + } + + Status =3D SendDataToSsifBmcPort ( + &Interface, + Context, + CmdDataBuffer, + (UINT8)(CommandDataSize + 2)); + + if (Status !=3D EFI_SUCCESS) { + Interface.Ssif.SsifSoftErrorCount++; + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return Status; + } + + // Hook to check smbus alert pin. + if (Interface.Ssif.SmbAlertSupport) { + if (!CheckAlertPinHook()) { + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_DEVICE_ERROR; + } + } else { + MicroSecondDelay(FixedPcdGet32 (PcdSsifRequestRetriesDelay)); + } + DataSize =3D IPMI_SMBUS_BLOCK_LENGTH; + + Status =3D ReceiveBmcDataFromSsifPort ( + &Interface, + Context, + CmdDataBuffer, + &DataSize); + if (Status !=3D EFI_SUCCESS) { + Interface.Ssif.SsifSoftErrorCount++; + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return Status; + } + + if (IPMI_ERROR_COMPLETION_CODE(CmdDataBuffer[2])) { + IpmiUpdateSoftErrorCount ( + CmdDataBuffer[2], + &Interface, + This->InterfaceType ); + // Write completion code into return buffer if ipmi command returns = an error. + if (*ResponseDataSize) { + if (ResponseData) { + *ResponseData =3D CmdDataBuffer[2]; + } + *ResponseDataSize =3D 1; + } + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_DEVICE_ERROR; + } + + if (DataSize < 3) { + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_DEVICE_ERROR; + } + + if ((DataSize - 2) > *((UINT8 *)ResponseDataSize)) { + *ResponseDataSize =3D (UINT8) (DataSize - 3); + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_BUFFER_TOO_SMALL; + } + + // Copying the response data into ResponseData buffer. + CopyMem ( + ResponseData, + &CmdDataBuffer[2], + (DataSize - 2) ); + *ResponseDataSize =3D (UINT8) (DataSize - 2); + + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_SUCCESS; +} + +/** + Execute the Get System Interface Capability command and update the RwS= upport + and PecSupport of Ipmi Instance. + + @param IpmiInstance Ipmi Instance Data structure pointer. + + @return EFI_STATUS Return Status + +**/ +VOID +GetSystemInterfaceCapability ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ) +{ + EFI_STATUS Status; + IPMI_GET_SYSTEM_INTERFACE_CAPABILITY_REQ GetSystemInterfaceCapabi= lityCmd; + IPMI_GET_SYSTEM_INTERFACE_CAPABILITY_RES GetSsifInterfaceCapabili= ty; + UINT32 DataSize =3D sizeof (Get= SsifInterfaceCapability); + + GetSystemInterfaceCapabilityCmd.SystemInterfaceType =3D 0x0; // SSIF + GetSystemInterfaceCapabilityCmd.Reserved =3D 0x0; + + Status =3D IpmiTransport2->IpmiSubmitCommand2 ( + IpmiTransport2, + IPMI_NETFN_APP, + BMC_LUN, + IPMI_APP_GET_SYSTEM_INTERFACE_CA= PABILITIES, + (UINT8*) &GetSystemInterfaceCapa= bilityCmd, + sizeof (GetSystemInterfaceCapabi= lityCmd), + (UINT8*) &GetSsifInterfaceCapabi= lity, + &DataSize); + if (!EFI_ERROR (Status)) { + IpmiTransport2->Interface.Ssif.RwSupport =3D GetSsifInterfaceCapabil= ity.TransactionSupport; + IpmiTransport2->Interface.Ssif.PecSupport =3D GetSsifInterfaceCapabi= lity.PecSupport; + } +} + +/** + Execute the Get Global Enable command to get receive message queue int= errupt. + + @return VOID + +**/ +VOID +GetGlobalEnables ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 +) +{ + EFI_STATUS Status; + IPMI_BMC_GLOBAL_ENABLES_RES BmcGlobalEnables; + UINT32 ResponseDataSize =3D sizeof (BmcGlob= alEnables); + + // + // Get Global Enable Information. + // + Status =3D IpmiTransport2->IpmiSubmitCommand2( + IpmiTransport2, + IPMI_NETFN_APP, + BMC_LUN, + IPMI_APP_GET_BMC_GLOBAL_ENABLES, + NULL, + 0, + (UINT8 *) (&BmcGlobalEnables), + &ResponseDataSize ); + if (!EFI_ERROR(Status)) { + // + // Set Smb alert pin based on ReceiveMsgQueueInterrupt bit + // + IpmiTransport2->Interface.Ssif.SmbAlertSupport =3D BmcGlobalEnables.= ReceiveMsgQueueInterrupt; + } +} + +/** + Initialize SSIF interface specific data. + + @param[in, out] Interface System interface pointer. + + @retval EFI_SUCCESS Interface is successfully initialized. + @retval Others Return status while initializing interface. + +**/ +EFI_STATUS +InitSsifInterfaceData ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ) +{ + EFI_STATUS Status =3D EFI_SUCCESS; + + if (IpmiTransport2->Interface.Ssif.InterfaceState =3D=3D IpmiInterfaceIn= itialized) { + return Status; + } + + IpmiTransport2->Interface.Ssif.SsifRetryCounter =3D FixedPcdGet16 (Pc= dSsifCommandtRetryCounter); + IpmiTransport2->Interface.Ssif.PecSupport =3D FALSE; + IpmiTransport2->Interface.Ssif.RwSupport =3D 0x0; // SSIF mu= lti-part reads/writes support. + IpmiTransport2->Interface.Ssif.SmbAlertSupport =3D FALSE; // SMB ale= rt pin support. + + Status =3D IpmiGetSmbusApiPtr (IpmiTransport2); + if (EFI_ERROR(Status)) { + IpmiTransport2->Interface.Ssif.InterfaceState =3D IpmiInterfaceInitE= rror; + return Status; + } + + IpmiTransportReleaseLock (&IpmiTransport2->Interface.Ssif.SsifTransportL= ocked); + return Status; +} -- 2.38.1.windows.1 -The information contained in this message may be confidential and propriet= ary to American Megatrends (AMI). This communication is intended to be read= only by the individual or entity to whom it is addressed or by their desig= nee. If the reader of this message is not the intended recipient, you are o= n notice that any distribution of this message, in any form, is strictly pr= ohibited. Please promptly notify the sender by reply e-mail or by telephone= at 770-246-8600, and then delete or destroy all copies of the transmission= .