From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM04-BN8-obe.outbound.protection.outlook.com (NAM04-BN8-obe.outbound.protection.outlook.com [40.107.100.60]) by mx.groups.io with SMTP id smtpd.web10.27509.1677600447943686249 for ; Tue, 28 Feb 2023 08:07:29 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@ami.com header.s=selector1 header.b=UZWAML7k; spf=pass (domain: ami.com, ip: 40.107.100.60, mailfrom: arunk@ami.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=arvAC08kwdMHDct7q2p8JIiR6kMUrAKKVB81C3rTZ7Ap50nw+UVDn+ljkwL1dDDIbfnZiJPsTRJun4tiDn+PonmtdAIoCcM6K8bT9cE+hytCc+KEg/xrnJMXc3spLWbfbYIoQXw0k5E67CwMGPZIEZqEU71YwhMdJ96KrL6DLauZuJcqUB1H8N3MoIrmA5WSPGIxRpgWr/gc5kD38kHfFu1BXpPZBTpa7I0dKZFscS0LyhJQ4Yro+XGIwPDDjSO8PoiLcaO04n+9pdxS0U3jdZWhRSG7N6hxmi3ehara5gVQyqOXW4I+R08NDiFMSrhUO32wIdBl2GYWpjapA6vtQw== 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=TZ4BzQOaIXfL8YMYxM4sO4TLTo44GrCDL2BkRiM/12g=; b=X53g5jCJ7WUW9WWmxOzLKMtl1AWm/OxFa+6E77Uqj6p+z4X5A5JacdrlUBLmzTuoqIKWyEI7MD5u0QqqXjsY3d/xPwA6WmQcf6Lpn+k1mvHi7bwuxgEtVKdafK2wUHYuI0yioih9wQ4vkkmNLTgSlv0b6y0TWqlEcZogpHdPnysMvr6KoZeKx2VrvbDCTBDc0Xq0o51CB7QSJK9L52qpcdKA/SeCI7JI3FfFLtGyH2thfl9JfzHXnlC5nkCebbKF76RnPqW53myYQt4N/MwDAH2p0a48MUnGUaOwSlOyyjY4YSDhhcbAd192YQ+7ty+dWrMTGA8ke/fqPrqz+Wa8Fg== 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=TZ4BzQOaIXfL8YMYxM4sO4TLTo44GrCDL2BkRiM/12g=; b=UZWAML7k6fCPABaJZJPoiGbI+MHC68n/eKUyBSrxxAOQhWGLh24lzGQwkNeZBw9no0goXhsZ7RjJT3BlgILA8BSqV3lO8oV2AgkvI9GInsMELIp96SHaVU+QUB0PMRkJABKjR8UPlrEk8eA0TBe4AW5L9nD3JkH+fnW9o3e8tlU= Received: from PH0PR10MB5403.namprd10.prod.outlook.com (2603:10b6:510:e3::17) by MW4PR10MB6559.namprd10.prod.outlook.com (2603:10b6:303:228::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6156.17; Tue, 28 Feb 2023 16:07:18 +0000 Received: from PH0PR10MB5403.namprd10.prod.outlook.com ([fe80::274f:a419:d1a3:f731]) by PH0PR10MB5403.namprd10.prod.outlook.com ([fe80::274f:a419:d1a3:f731%7]) with mapi id 15.20.6156.017; Tue, 28 Feb 2023 16:07:18 +0000 From: arunk@ami.com To: "devel@edk2.groups.io" , Arun K CC: Sainadh Nagolu , Srinivasan Mani , "isaac.w.oram@intel.com" , "nathaniel.l.desimone@intel.com" , Liming Gao , Vasudevan S , Sundaresan S Subject: [edk2-devel][edk2-platforms][PATCH V1] IpmiFeaturePkg:Provided multliple IPMI interface support Thread-Topic: [edk2-devel][edk2-platforms][PATCH V1] IpmiFeaturePkg:Provided multliple IPMI interface support Thread-Index: AQHZS467x53qDWgDQ0O+I5E25uZEMw== Date: Tue, 28 Feb 2023 16:07:18 +0000 Message-ID: <3714005c79b96119353db26d0034ca0b5da2537d.1677599596.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_|MW4PR10MB6559:EE_ x-ms-office365-filtering-correlation-id: 161eac60-502f-4665-2c6d-08db19a5ddc7 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: x+1EMS7tow2DsB8N05+GtUBAVPOLMvWj+ixKwr1nDZxphC17x/nE6iLeQJ8NP+0w2fJIaDYlqIIU8hbR7UuKL9t+R9E1qWZbrsef1jge4LUIs21CZWxbOHEm0aKYk+gNSMfgiVhlQD8+52qBo/iVRWzChRvLar5fre8a8i+komBRUr+u/UyFZTF8gTovpHf5pfLPLnlEPFIaTA3VqRkAHJ+td6xPVnGymHMAGQisv5oPF1363/plduxO9CLuk26e2sW9FBC6aANMRE/4JAS6pM1jv+rwj0kHuP7IHn1Jh73ff2nkTaSM3ep0xDBwszkOvW7cWQbybBFa1awvnI9kJc6lutgBh6HZlu4yBjU1h+QkQuwh8npk8iOL31/50+XrkO0T2ykbccTf7nSpk7y4FrEXvlGn4M4b7r8mNtTVDh6L12km7ClDtlfzgCAqWR9IXrTvat7UKsfYJRE/Q+3H7gsAY/WaN354K0/UxzyHnTHN/A3nTDoEhbIYPUKKi/GZwwxcDVtiBacVB5PYIvsNwI4j/R31fDeP92jeVUPawoby7vOdEqeySrpbPIW9scFvpgkNqgBs4K7XKmAFIc4CTnM2H2PY0ewC1330VMXg7/g0IGL/TMw8+dPqUUOifdfq6GSF6WPZeeejJ9Idb+gDqU/AzRtFujtUGY6lZkW5ecv34RUAF8BAHecNvvqvsgM0B3K1fhfZPk8C6tRHYZOFl5FIeFvs3/Ytj66On3aKrfM= 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:(13230025)(4636009)(376002)(136003)(396003)(346002)(366004)(39850400004)(451199018)(54906003)(30864003)(316002)(110136005)(19627235002)(66899018)(83380400001)(122000001)(86362001)(38100700002)(40140700001)(8676002)(41300700001)(26005)(66476007)(71200400001)(186003)(5660300002)(6506007)(66556008)(7049001)(66946007)(76116006)(2616005)(2906002)(6486002)(36756003)(66446008)(64756008)(91956017)(38070700005)(4326008)(6512007)(8936002)(478600001)(559001)(579004)(357404004);DIR:OUT;SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?iso-8859-1?Q?gJ6/zMxzd24/ZqJJFii1ZR6bnyNj4iioYs7a5owC3xxyWXgzb8XYZg/ZU7?= =?iso-8859-1?Q?sWzcOlTqT12Fr2NOEWTriCsJtTeDsUttj1SAnS2XzhMDKhUNw4CTZ6LbPN?= =?iso-8859-1?Q?52OGd/fsPiqlTvhubjLRMJU4ZWXwGNC+jLNHDmySTdjB0ypszdKVv8HRwx?= =?iso-8859-1?Q?ida1GgUHBCvpRrtGrTHwS38XprVC1cu3f60BsLNZjUJM4BZW+DlGz3jF2w?= =?iso-8859-1?Q?gBtRSw0SEmXJMUI86/xMcalN8UC/iFRY0iUm+jg8g3Fw1WfvQNy9Mgizgh?= =?iso-8859-1?Q?72SdOj85qM+fQKLAp147kgxAfm3/vX8x2d66oao0+eNYs+gL8FtrT9toYN?= =?iso-8859-1?Q?/Xw+Bax+P8QhmsHLaizia+dK1UXNFGNcVBf/o8EKP1pMrk4h85TPQBaZSC?= =?iso-8859-1?Q?tYtAD8yl4adNeU6WpVB62kqdI/MkZo2S35i2QZk9qb0/NAaMuMcPH2AE8V?= =?iso-8859-1?Q?xc/coAdLfyyVKEoW1voDmcaEH/1lh3BSRzizdztWHXAl3rJmjdmeD8QOmm?= =?iso-8859-1?Q?aurwfmcAAx/QciPZcKCbrxCD0jHFwXS+bMxlzTBRmyiBc2dKcWKC8sElhz?= =?iso-8859-1?Q?LbwnN1N2OjkLJJVcsarPxwldF/CJ420gsRB+U8g8zDX0cdsvDAIY7NfQ1v?= =?iso-8859-1?Q?LyfxadkQeSF5GqbegwprBjImRHgjfjDQd6jFUsIvXamz0lQFFEIP+RsqJ8?= =?iso-8859-1?Q?hvdCxS7P2lEZooVlDs3CAz149Uo/64npfTfQ1kZHcyM9YDGyeInhkZja+O?= =?iso-8859-1?Q?E+HhBJduM+LLdqzFnsL5k6gVtuxHYelG3unY1UFXZU0bt7REgnIAU8wIHo?= =?iso-8859-1?Q?mT9Ingb79tMIRxhoZ/SJWohArLMajvtY5ieOr/ZvAxWSQSfTa35EP/qK1W?= =?iso-8859-1?Q?SAwo1DlZXo/1twsfh2/LloG8xYGDP5kH08fJ7GTHm1BxuGLQKqbIsUNczV?= =?iso-8859-1?Q?Dy1W7uw5hcEdlUNrX9JFaiNz87dAXuH4sE8FJWMUdz6IE0ft1RH5ESfe1P?= =?iso-8859-1?Q?dZyHGP9PlUzLcrBFjmizUNIULec/FyVHuHCU1NygVRqo+GbrXKx4YByDxf?= =?iso-8859-1?Q?p0gVLFWp7cWeJsvKZBsf/ERg9FKvFfxo+nYAG1oMg27k5HkIroFOmvJWlO?= =?iso-8859-1?Q?IihOClQVf8kHAZTDnJDJBBFKa8iWXhr2jwQ6rj6gUiPzE6G/blkCK7ahZO?= =?iso-8859-1?Q?08/feCvRWKXDZsWZB9dx9Uvq3dj7SBxbcTluVRxBk8zTyoSQ0gDJGGVNbU?= =?iso-8859-1?Q?GMOLL9hkY6nq5kKNmTvynDlwcrQsN/SoSDqxXP/Q0XWTDIHRWuHWHr8AU4?= =?iso-8859-1?Q?5tN1riQh61aGyfUJ6CpGNrdKPXTVDZw6SuKGrGLV/aUGXcXmAY34QbBBYY?= =?iso-8859-1?Q?8vICcGw04mt7TqIRr/6x2LDBhqGVKLXbUDouORzDEVhUO8/KiFPN8aIV/j?= =?iso-8859-1?Q?3YvcvQRcwembYv6zMfBg6YMotBBSzXxV0bBCvoSVflWUuAbe1demNmGIRh?= =?iso-8859-1?Q?gnyadOGF7orUnt8oIYIvLoYa7O9+6mvsHj95Xa3SwCLbb9n9L+e8OOb6FW?= =?iso-8859-1?Q?vRu3KbnuYKjyur+7b4hh3NWkh+EuI2SMPcCkch6gtBghjvu2mBYysgCQRj?= =?iso-8859-1?Q?BMmnvcRtUC/6ZgZbBZedKU9SlmvCTXLXiu?= 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: 161eac60-502f-4665-2c6d-08db19a5ddc7 X-MS-Exchange-CrossTenant-originalarrivaltime: 28 Feb 2023 16:07:18.3548 (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: d+9LUaeGeQBnqfJzCjx+vGB0KYkltNLjuYcF0WcjmMChH3RXZ7uH3Lh+RdEC1F2y X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW4PR10MB6559 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 Cc: Vasudevan S Cc: Srinivasan Mani Cc: Sundaresan S Signed-off-by: Arun K --- .../GenericIpmi/Common/IpmiBmc.h | 10 + .../GenericIpmi/Common/IpmiBmcCommon.h | 2 + .../GenericIpmi/Common/IpmiHooks.c | 222 +++++++ .../GenericIpmi/Common/IpmiHooks.h | 92 ++- .../GenericIpmi/Dxe/GenericIpmi.inf | 12 +- .../IpmiFeaturePkg/GenericIpmi/Dxe/IpmiInit.c | 183 ++++++ .../GenericIpmi/Pei/PeiGenericIpmi.c | 273 +++++++-- .../GenericIpmi/Pei/PeiGenericIpmi.h | 3 + .../GenericIpmi/Pei/PeiGenericIpmi.inf | 16 +- .../GenericIpmi/Pei/PeiIpmiBmc.c | 3 +- .../GenericIpmi/Pei/PeiIpmiBmc.h | 9 + .../GenericIpmi/Pei/PeiIpmiBmcDef.h | 31 +- .../GenericIpmi/Pei/PeiIpmiHooks.c | 316 ++++++++++ .../GenericIpmi/Pei/PeiIpmiHooks.h | 211 +++++++ .../GenericIpmi/Smm/SmmGenericIpmi.c | 178 +++++- .../GenericIpmi/Smm/SmmGenericIpmi.inf | 13 +- .../IpmiFeaturePkg/Include/IpmiFeature.dsc | 12 + .../Include/IpmiNetFnAppDefinitions.h | 239 ++++++++ .../Include/IpmiTransport2Definitions.h | 139 +++++ .../Include/Library/BmcCommonInterfaceLib.h | 186 ++++++ .../Include/Library/BtInterfaceLib.h | 83 +++ .../Include/Library/SsifInterfaceLib.h | 165 +++++ .../Include/Ppi/IpmiTransport2Ppi.h | 22 + .../Include/Protocol/IpmiTransport2Protocol.h | 29 + .../IpmiFeaturePkg/IpmiFeaturePkg.dec | 42 ++ .../BmcCommonInterfaceLib.c | 227 +++++++ .../BmcCommonInterfaceLib.inf | 26 + .../BtInterfaceLib/BtInterfaceLib.c | 570 ++++++++++++++++++ .../BtInterfaceLib/BtInterfaceLib.inf | 39 ++ .../SsifInterfaceLib/DxeSsifInterfaceLib.c | 131 ++++ .../SsifInterfaceLib/DxeSsifInterfaceLib.inf | 39 ++ .../SsifInterfaceLib/PeiSsifInterfaceLib.c | 122 ++++ .../SsifInterfaceLib/PeiSsifInterfaceLib.inf | 40 ++ .../SsifInterfaceLib/SmmSsifInterfaceLib.c | 148 +++++ .../SsifInterfaceLib/SmmSsifInterfaceLib.inf | 40 ++ .../SsifInterfaceLib/SsifInterfaceLibCommon.c | 545 +++++++++++++++++ 36 files changed, 4334 insertions(+), 84 deletions(-) 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/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/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/= Common/IpmiBmc.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Generi= cIpmi/Common/IpmiBmc.h index d306a085e5..19fb2a26a3 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/= IpmiBmc.h +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/= IpmiBmc.h @@ -3,6 +3,7 @@ @copyright Copyright 1999 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -21,6 +22,7 @@ #include #include #include +#include #include "IpmiBmcCommon.h" #include "KcsBmc.h" @@ -41,4 +43,12 @@ SM_IPMI_BMC_SIGNATURE \ ) +#define INSTANCE_FROM_IPMI_TRANSPORT2_THIS(a) \ + CR ( \ + a, \ + IPMI_BMC_INSTANCE_DATA, \ + IpmiTransport2, \ + SM_IPMI_BMC_SIGNATURE \ + ) + #endif // _IPMI_BMC_H_ diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/= Common/IpmiBmcCommon.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/= GenericIpmi/Common/IpmiBmcCommon.h index 1e5dfd81f1..930bee21f1 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/= IpmiBmcCommon.h +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/= IpmiBmcCommon.h @@ -3,6 +3,7 @@ @copyright Copyright 1999 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -56,6 +57,7 @@ typedef struct { UINT8 SoftErrorCount; UINT16 IpmiIoBase; IPMI_TRANSPORT IpmiTransport; + IPMI_TRANSPORT2 IpmiTransport2; EFI_HANDLE IpmiSmmHandle; } IPMI_BMC_INSTANCE_DATA; diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/= Common/IpmiHooks.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gene= ricIpmi/Common/IpmiHooks.c index b2788e5a4c..64c3215d90 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/= IpmiHooks.c +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/= IpmiHooks.c @@ -3,6 +3,7 @@ @copyright Copyright 2014 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -48,6 +49,11 @@ Returns: --*/ { + + if (This =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + // // This Will be unchanged ( BMC/KCS style ) // @@ -64,6 +70,217 @@ Returns: ); } // IpmiSendCommand() +EFI_STATUS +EFIAPI +IpmiSendCommand2 ( + 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 + +--*/ +{ + + IPMI_BMC_INSTANCE_DATA *IpmiInstance; + + if (This =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + IpmiInstance =3D INSTANCE_FROM_IPMI_TRANSPORT2_THIS(This); + +#if KcsInterfaceSupport + if ((IpmiInstance->IpmiTransport2.InterfaceType =3D=3D SysInterfaceKcs) = && + (IpmiInstance->IpmiTransport2.Interface.KcsInterfaceState =3D=3D Ipm= iInterfaceInitialized)) { + + return IpmiSendCommand ( + &IpmiInstance->IpmiTransport, + NetFunction, + Lun, + Command, + CommandData, + CommandDataSize, + ResponseData, + ResponseDataSize + ); + } +#endif + +#if BtInterfaceSupport + if ((IpmiInstance->IpmiTransport2.InterfaceType =3D=3D SysInterfaceBt) &= & + (IpmiInstance->IpmiTransport2.Interface.Bt.InterfaceState =3D=3D Ipm= iInterfaceInitialized)) { + + return IpmiBtSendCommandToBmc ( + &IpmiInstance->IpmiTransport2, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8*) ResponseDataSize, + NULL + ); + } +#endif + +#if SsifInterfaceSupport + if ((IpmiInstance->IpmiTransport2.InterfaceType =3D=3D SysInterfaceSsif)= && + (IpmiInstance->IpmiTransport2.Interface.Ssif.InterfaceState =3D=3D I= pmiInterfaceInitialized)) { + + return IpmiSsifSendCommandToBmc ( + &IpmiInstance->IpmiTransport2, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8*) ResponseDataSize, + NULL + ); + } +#endif + + return EFI_UNSUPPORTED; +} // IpmiSendCommand2() + +EFI_STATUS +EFIAPI +IpmiSendCommand2Ex ( + 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 + +--*/ + + IPMI_BMC_INSTANCE_DATA *IpmiInstance; + + if (This =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + IpmiInstance =3D INSTANCE_FROM_IPMI_TRANSPORT2_THIS(This); + +#if KcsInterfaceSupport + if ((InterfaceType =3D=3D SysInterfaceKcs) && + (IpmiInstance->IpmiTransport2.Interface.KcsInterfaceState =3D=3D Ipm= iInterfaceInitialized)) { + + return IpmiSendCommand ( + &IpmiInstance->IpmiTransport, + NetFunction, + Lun, + Command, + CommandData, + CommandDataSize, + ResponseData, + ResponseDataSize + ); + } +#endif + +#if BtInterfaceSupport + if ((InterfaceType =3D=3D SysInterfaceBt) && + (IpmiInstance->IpmiTransport2.Interface.Bt.InterfaceState =3D=3D Ipm= iInterfaceInitialized)) { + + return IpmiBtSendCommandToBmc ( + &IpmiInstance->IpmiTransport2, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8*) ResponseDataSize, + NULL + ); + } +#endif + +#if SsifInterfaceSupport + if ((InterfaceType =3D=3D SysInterfaceSsif) && + (IpmiInstance->IpmiTransport2.Interface.Ssif.InterfaceState =3D=3D I= pmiInterfaceInitialized)) { + + return IpmiSsifSendCommandToBmc ( + &IpmiInstance->IpmiTransport2, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8*) ResponseDataSize, + NULL + ); + } +#endif + + return EFI_UNSUPPORTED; +} + EFI_STATUS EFIAPI IpmiGetBmcStatus ( @@ -89,6 +306,11 @@ Returns: --*/ { + + if ((This =3D=3D NULL) || (BmcStatus =3D=3D NULL) || (ComAddress =3D=3D = NULL)) { + return EFI_INVALID_PARAMETER; + } + return IpmiBmcStatus ( This, BmcStatus, diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/= Common/IpmiHooks.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gene= ricIpmi/Common/IpmiHooks.h index 823cc08c61..29b793bbf0 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/= IpmiHooks.h +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Common/= IpmiHooks.h @@ -3,13 +3,20 @@ @copyright Copyright 2014 - 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 "IpmiBmc.h" +#include +#include +#include +#include +#include +#include +#include // // Internal(hook) function list @@ -54,6 +61,89 @@ Returns: --*/ ; +EFI_STATUS +EFIAPI +IpmiSendCommand2 ( + 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 +EFIAPI +IpmiSendCommand2Ex ( + 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 + +--*/ +; + EFI_STATUS EFIAPI IpmiGetBmcStatus ( diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/= Dxe/GenericIpmi.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gen= ericIpmi/Dxe/GenericIpmi.inf index 8d80aeb6b5..56d1e0c872 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Dxe/Gen= ericIpmi.inf +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Dxe/Gen= ericIpmi.inf @@ -3,6 +3,7 @@ # # @copyright # Copyright 2010 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
# SPDX-License-Identifier: BSD-2-Clause-Patent ## @@ -49,16 +50,23 @@ IoLib ReportStatusCodeLib TimerLib + BmcCommonInterfaceLib + BtInterfaceLib + SsifInterfaceLib [Protocols] gIpmiTransportProtocolGuid # PROTOCOL ALWAYS_PRODUCED gEfiVideoPrintProtocolGuid - -[Guids] + gIpmiTransport2ProtocolGuid [Pcd] gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiIoBaseAddress gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiBmcReadyDelayTimer + gIpmiFeaturePkgTokenSpaceGuid.PcdDefaultSystemInterface + gIpmiFeaturePkgTokenSpaceGuid.PcdBtInterfaceSupport + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifInterfaceSupport + gIpmiFeaturePkgTokenSpaceGuid.PcdKcsInterfaceSupport + gIpmiFeaturePkgTokenSpaceGuid.PcdBtControlPort [Depex] gEfiRuntimeArchProtocolGuid AND diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/= Dxe/IpmiInit.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericI= pmi/Dxe/IpmiInit.c index d788b48867..8e44f9db9c 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Dxe/Ipm= iInit.c +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Dxe/Ipm= iInit.c @@ -3,6 +3,7 @@ @copyright Copyright 1999 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -13,6 +14,7 @@ #include "IpmiBmc.h" #include "IpmiPhysicalLayer.h" #include +#include #ifdef FAST_VIDEO_SUPPORT #include #endif @@ -342,6 +344,119 @@ Returns: return Status; } // GetDeviceId() +/** + Initialize the API and parameters for IPMI Transport2 Instance + + @param[in] IpmiInstance Pointer to IPMI Instance + + @return VOID Nothing. + +**/ +VOID +InitIpmiTransport2 ( + IN IPMI_BMC_INSTANCE_DATA *IpmiInstance + ) +{ + + IpmiInstance->IpmiTransport2.InterfaceType =3D FixedPcdGet8 (= PcdDefaultSystemInterface); + IpmiInstance->IpmiTransport2.IpmiTransport2BmcStatus =3D BmcStatusOk; + IpmiInstance->IpmiTransport2.IpmiSubmitCommand2 =3D IpmiSendComman= d2; + IpmiInstance->IpmiTransport2.IpmiSubmitCommand2Ex =3D IpmiSendComman= d2Ex; + +#if BtInterfaceSupport + InitBtInterfaceData(&IpmiInstance->IpmiTransport2); +#endif + +#if SsifInterfaceSupport + InitSsifInterfaceData(&IpmiInstance->IpmiTransport2); +#endif +} + +/** + Notify call back function. + + @param[in] Event Event which caused this handler. + @param[in] Context Context passed during Event Handler registration. + + @return VOID Nothing. + +**/ +VOID +EFIAPI +DxeNotifyCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + IPMI_INTERFACE_STATE InterfaceState; + EFI_HANDLE Handle; + + InterfaceState =3D IpmiInterfaceNotReady; + +#if SsifInterfaceSupport + InitSsifInterfaceData(&mIpmiInstance->IpmiTransport2); + + if (mIpmiInstance->IpmiTransport2.Interface.Ssif.InterfaceState =3D=3D I= pmiInterfaceInitialized) { + InterfaceState =3D IpmiInterfaceInitialized; + } +#endif + + // Default Interface data should be initialized to install Ipmi Transpor= t2 Protocol. + if (InterfaceState !=3D IpmiInterfaceInitialized) { + return; + } + + Handle =3D NULL; + Status =3D gBS->InstallProtocolInterface ( + &Handle, + &gIpmiTransport2ProtocolGuid, + EFI_NATIVE_INTERFACE, + &mIpmiInstance->IpmiTransport2 + ); + ASSERT_EFI_ERROR (Status); +} + +/** + Registers protocol notify call back. + + @param[in] ProtocolGuid Pointer to Protocol Guid to register + call back. + + @retval EFI_INVALID_PARAMETER If the ProtocolGuid is 0 or NULL. + @retval Others Status of call back registration. + +**/ +EFI_STATUS +DxeRegisterProtocolCallback ( + IN EFI_GUID *ProtocolGuid + ) +{ + EFI_STATUS Status; + EFI_EVENT NotifyEvent; + VOID *Registration; + + if ((ProtocolGuid =3D=3D NULL) || + ((ProtocolGuid !=3D NULL) && IsZeroBuffer (ProtocolGuid, sizeof (EFI= _GUID)))) { + return EFI_INVALID_PARAMETER; + } + + Status =3D gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + DxeNotifyCallback, + NULL, + &NotifyEvent); + + if (!EFI_ERROR (Status)) { + Status =3D gBS->RegisterProtocolNotify ( + ProtocolGuid, + NotifyEvent, + &Registration); + } + + return Status; +} /** This function initializes KCS interface to BMC. @@ -367,7 +482,10 @@ InitializeIpmiKcsPhysicalLayer ( UINT8 ErrorCount; EFI_HANDLE Handle; UINT8 Index; + IPMI_INTERFACE_STATE InterfaceState =3D IpmiInterfaceNotReady; +#if KcsInterfaceSupport EFI_STATUS_CODE_VALUE StatusCodeValue[MAX_SOFT_COUNT]; +#endif ErrorCount =3D 0; mImageHandle =3D ImageHandle; @@ -396,6 +514,8 @@ InitializeIpmiKcsPhysicalLayer ( mIpmiInstance->Signature =3D SM_IPMI_BMC_SIGNAT= URE; mIpmiInstance->SlaveAddress =3D BMC_SLAVE_ADDRESS; mIpmiInstance->BmcStatus =3D BMC_NOTREADY; + +#if KcsInterfaceSupport mIpmiInstance->IpmiTransport.IpmiSubmitCommand =3D IpmiSendCommand; mIpmiInstance->IpmiTransport.GetBmcStatus =3D IpmiGetBmcStatus; @@ -445,7 +565,70 @@ InitializeIpmiKcsPhysicalLayer ( ); ASSERT_EFI_ERROR (Status); } +#endif + + // Initialise the IPMI transport2 + InitIpmiTransport2(mIpmiInstance); + + // Check interface data initialized successfully else register notify = protocol. + for (Index =3D SysInterfaceKcs; Index < SysInterfaceMax; Index++) { + + switch (Index) { +#if KcsInterfaceSupport + case SysInterfaceKcs: + if ((mIpmiInstance->BmcStatus !=3D BMC_HARDFAIL) && (mIpmi= Instance->BmcStatus !=3D BMC_UPDATE_IN_PROGRESS)) { + BMC_INTERFACE_STATUS BmcStatus; + mIpmiInstance->IpmiTransport2.Interface.KcsInterfaceSt= ate =3D IpmiInterfaceInitialized; + Status =3D CheckSelfTestByInterfaceType( + &mIpmiInstance->IpmiTransport2, + &BmcStatus, + SysInterfaceKcs); + if (!EFI_ERROR (Status) && (BmcStatus !=3D BmcStatusHa= rdFail)) { + InterfaceState =3D IpmiInterfaceInitialized; + } else { + mIpmiInstance->IpmiTransport2.Interface.KcsInterfa= ceState =3D IpmiInterfaceInitError; + } + } + break; +#endif +#if BtInterfaceSupport + case SysInterfaceBt: + if (mIpmiInstance->IpmiTransport2.Interface.Bt.InterfaceSt= ate =3D=3D IpmiInterfaceInitialized){ + InterfaceState =3D IpmiInterfaceInitialized; + } + break; +#endif + +#if SsifInterfaceSupport + case SysInterfaceSsif: + if (mIpmiInstance->IpmiTransport2.Interface.Ssif.Interface= State =3D=3D IpmiInterfaceInitialized) { + InterfaceState =3D IpmiInterfaceInitialized; + } else if (mIpmiInstance->IpmiTransport2.Interface.Ssif.In= terfaceState =3D=3D IpmiInterfaceInitError) { + // Register protocol notify for SMBUS Protocol. + Status =3D DxeRegisterProtocolCallback ( + &mIpmiInstance->IpmiTransport2.Interface.S= sif.SsifInterfaceApiGuid); + } + break; +#endif + default: + break; + } + } + + // Any one of the Interface data should be initialized to install IPMI= Transport2 Protocol. + if (InterfaceState !=3D IpmiInterfaceInitialized) { + return EFI_SUCCESS; + } + + Handle =3D NULL; + Status =3D gBS->InstallProtocolInterface ( + &Handle, + &gIpmiTransport2ProtocolGuid, + EFI_NATIVE_INTERFACE, + &mIpmiInstance->IpmiTransport2 + ); + ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; } } // InitializeIpmiKcsPhysicalLayer() diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/= Pei/PeiGenericIpmi.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Ge= nericIpmi/Pei/PeiGenericIpmi.c index 3efb772b68..dc41ea966e 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= GenericIpmi.c +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= GenericIpmi.c @@ -3,6 +3,7 @@ @copyright Copyright 2017 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -10,10 +11,132 @@ #include "PeiGenericIpmi.h" #include #include +#include //////////////////////////////////////////////////////////////////////////= ///// -// Function Implementations -// + +/** + Initialize the API and parameters for IPMI Transport2 Instance + + @param[in] IpmiInstance Pointer to IPMI Instance + + @return VOID + +**/ +VOID +InitIpmiTransport2 ( + IN PEI_IPMI_BMC_INSTANCE_DATA *IpmiInstance + ) +{ + IpmiInstance->IpmiTransport2Ppi.InterfaceType =3D FixedPcdGet8= (PcdDefaultSystemInterface); + IpmiInstance->IpmiTransport2Ppi.IpmiTransport2BmcStatus =3D BmcStatusOk; + IpmiInstance->IpmiTransport2Ppi.IpmiSubmitCommand2 =3D PeiIpmiSendC= ommand2; + IpmiInstance->IpmiTransport2Ppi.IpmiSubmitCommand2Ex =3D PeiIpmiSendC= ommand2Ex; + +#if BtInterfaceSupport + if (!EFI_ERROR (PlatformIpmiIoRangeSet(FixedPcdGet16(PcdBtControlPort)))= ) { + InitBtInterfaceData (&IpmiInstance->IpmiTransport2Ppi); + } +#endif + +#if SsifInterfaceSupport + InitSsifInterfaceData (&IpmiInstance->IpmiTransport2Ppi); +#endif +} + +/** + Notify callback function for interfaces. + + @param[in] PeiServices Describes the list of possible PEI + Services. + @param[in] NotifyDescriptor Pointer to notify descriptor. + @param[in] Ppi Pointer to Ppi. + + @return EFI_STATUS Status of Notify call back. + @retval EFI_NOT_FOUND Ipmi hob is not found. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval EFI_SUCCESS Interface is initialized and installed + Ipmi Ppi successfully. + @retval Others Error status while installing Ppi. +**/ +EFI_STATUS +EFIAPI +NotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + EFI_STATUS Status; + PEI_IPMI_BMC_INSTANCE_DATA *IpmiInstance; + PEI_IPMI_DATA_HOB *IpmiInstancePtrHob; + EFI_HOB_GUID_TYPE *GuidHob; + IPMI_INTERFACE_STATE InterfaceState; + + InterfaceState =3D IpmiInterfaceNotReady; + + GuidHob =3D GetFirstGuidHob (&gPeiIpmiHobGuid); + ASSERT (GuidHob !=3D NULL); + if (GuidHob =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + IpmiInstancePtrHob =3D (PEI_IPMI_DATA_HOB *) GET_GUID_HOB_DATA(GuidHob); + IpmiInstance =3D (PEI_IPMI_BMC_INSTANCE_DATA*) IpmiInstancePtrHob-= >IpmiInstance; + +#if SsifInterfaceSupport + InitSsifInterfaceData(&IpmiInstance->IpmiTransport2Ppi); + + if (IpmiInstance->IpmiTransport2Ppi.Interface.Ssif.InterfaceState =3D=3D= IpmiInterfaceInitialized){ + InterfaceState =3D IpmiInterfaceInitialized; + } +#endif + + // Default Interface data should be initialized to install Ipmi Transpor= t2 Protocol. + if (InterfaceState !=3D IpmiInterfaceInitialized) { + return EFI_UNSUPPORTED; + } + + Status =3D PeiServicesInstallPpi (&IpmiInstance->PeiIpmi2BmcDataDesc); + return Status; +} + +/** + Registers callback for Ppi. + + @param[in] PeiServices Describes the list of possible PEI Services. + @param[in] PpiGuid Pointer to Ppi guid to register call back. + + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Others Status of NotifyPpi(). +**/ +EFI_STATUS +RegisterPpiCallback ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_GUID *PpiGuid + ) +{ + EFI_STATUS Status; + EFI_PEI_NOTIFY_DESCRIPTOR *PpiNotifyDesc; + + if ((PpiGuid =3D=3D NULL) || + ((PpiGuid !=3D NULL) && IsZeroBuffer(PpiGuid, sizeof (EFI_GUID)))) { + return EFI_INVALID_PARAMETER; + } + + PpiNotifyDesc =3D (EFI_PEI_NOTIFY_DESCRIPTOR*) AllocateZeroPool (sizeof = (EFI_PEI_NOTIFY_DESCRIPTOR)); + if (PpiNotifyDesc =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + PpiNotifyDesc->Flags =3D EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_P= EI_PPI_DESCRIPTOR_TERMINATE_LIST; + PpiNotifyDesc->Guid =3D PpiGuid; + PpiNotifyDesc->Notify =3D NotifyCallback; + + Status =3D (*PeiServices)->NotifyPpi (PeiServices, PpiNotifyDesc); + return Status; +} /*************************************************************************= **** @brief @@ -31,8 +154,12 @@ PeiInitializeIpmiKcsPhysicalLayer ( { EFI_STATUS Status; PEI_IPMI_BMC_INSTANCE_DATA *mIpmiInstance; + PEI_IPMI_DATA_HOB *IpmiInstancePtrHob; + IPMI_INTERFACE_STATE InterfaceState; + UINT8 Index; - mIpmiInstance =3D NULL; + mIpmiInstance =3D NULL; + InterfaceState =3D IpmiInterfaceNotReady; // // Send Pre-Boot signal to BMC @@ -60,6 +187,18 @@ PeiInitializeIpmiKcsPhysicalLayer ( return EFI_OUT_OF_RESOURCES; } + + // Create Guided hob to pass IPMI Instance data pointer to notify functi= ons. + IpmiInstancePtrHob =3D BuildGuidHob (&gPeiIpmiHobGuid, sizeof(PEI_IPMI_D= ATA_HOB)); + if (IpmiInstancePtrHob =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Failed to create Hob guid for IPMI Instance!!!= \n")); + FreePool (mIpmiInstance); + return EFI_OUT_OF_RESOURCES; + } + + IpmiInstancePtrHob->IpmiInstance =3D (UINTN)mIpmiInstance; + IpmiInstancePtrHob->PreMemIpmiDataHobPtr =3D IpmiInstancePtrHob; + // // Calibrate TSC Counter. Stall for 10ms, then multiply the resulting n= umber of // ticks in that period by 100 to get the number of ticks in a 1 second = timeout @@ -83,6 +222,7 @@ PeiInitializeIpmiKcsPhysicalLayer ( mIpmiInstance->PeiIpmiBmcDataDesc.Guid =3D &gPeiIpmiTransportPp= iGuid; mIpmiInstance->PeiIpmiBmcDataDesc.Ppi =3D &mIpmiInstance->Ipmi= TransportPpi; +#if KcsInterfaceSupport // // Get the Device ID and check if the system is in Force Update mode. // @@ -94,19 +234,74 @@ PeiInitializeIpmiKcsPhysicalLayer ( // // Do not continue initialization if the BMC is in Force Update Mode. // - if (mIpmiInstance->BmcStatus =3D=3D BMC_UPDATE_IN_PROGRESS || mIpmiInsta= nce->BmcStatus =3D=3D BMC_HARDFAIL) { - return EFI_UNSUPPORTED; + if (mIpmiInstance->BmcStatus !=3D BMC_UPDATE_IN_PROGRESS && mIpmiInstanc= e->BmcStatus !=3D BMC_HARDFAIL) { + Status =3D PeiServicesInstallPpi (&mIpmiInstance->PeiIpmiBmcDataDesc= ); + if (EFI_ERROR (Status)) { + return Status; + } + } +#endif + + InitIpmiTransport2(mIpmiInstance); + + // Check interface data initialized successfully else register notify pr= otocol. + for (Index =3D SysInterfaceKcs; Index < SysInterfaceMax; Index++) { + + switch (Index) { + +#if KcsInterfaceSupport + case SysInterfaceKcs: + if ((mIpmiInstance->BmcStatus !=3D BMC_HARDFAIL) && (mIpmiIn= stance->BmcStatus !=3D BMC_UPDATE_IN_PROGRESS)) { + BMC_INTERFACE_STATUS BmcStatus; + mIpmiInstance->IpmiTransport2Ppi.Interface.KcsInterfaceS= tate =3D IpmiInterfaceInitialized; + Status =3D CheckSelfTestByInterfaceType( + &mIpmiInstance->IpmiTransport2Pp= i, + &BmcStatus, + SysInterfaceKcs); + if (!EFI_ERROR (Status) && (BmcStatus !=3D BmcStatusHard= Fail)) { + InterfaceState =3D IpmiInterfaceInitialized; + } else { + mIpmiInstance->IpmiTransport2Ppi.Interface.KcsInterf= aceState =3D IpmiInterfaceInitError; + } + } + break; +#endif + +#if BtInterfaceSupport + case SysInterfaceBt: + if (mIpmiInstance->IpmiTransport2Ppi.Interface.Bt.InterfaceS= tate =3D=3D IpmiInterfaceInitialized){ + InterfaceState =3D IpmiInterfaceInitialized; + } + break; +#endif + +#if SsifInterfaceSupport + case SysInterfaceSsif: + if (mIpmiInstance->IpmiTransport2Ppi.Interface.Ssif.Interfac= eState =3D=3D IpmiInterfaceInitialized){ + InterfaceState =3D IpmiInterfaceInitialized; + } else if (mIpmiInstance->IpmiTransport2Ppi.Interface.Ssif.I= nterfaceState =3D=3D IpmiInterfaceInitError) { + // Register protocol notify for SMBUS Protocol. + Status =3D RegisterPpiCallback (PeiServices, &mIpmiInsta= nce->IpmiTransport2Ppi.Interface.Ssif.SsifInterfaceApiGuid); + } + break; +#endif + default: + break; + } } - // - // Just produce PPI - // - Status =3D PeiServicesInstallPpi (&mIpmiInstance->PeiIpmiBmcDataDesc); - if (EFI_ERROR (Status)) { - return Status; + // Any one of the Interface data should be initialized to install Ipmi T= ransport2 Protocol. + if (InterfaceState !=3D IpmiInterfaceInitialized) { + DEBUG ((DEBUG_INFO, "Interface not ready yet. \n")); + return EFI_SUCCESS; } - return EFI_SUCCESS; + mIpmiInstance->PeiIpmi2BmcDataDesc.Flags =3D EFI_PEI_PPI_DESCRIPTOR_PPI= | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; + mIpmiInstance->PeiIpmi2BmcDataDesc.Guid =3D &gPeiIpmiTransport2PpiGuid= ; + mIpmiInstance->PeiIpmi2BmcDataDesc.Ppi =3D &mIpmiInstance->IpmiTransp= ort2Ppi; + + Status =3D PeiServicesInstallPpi (&mIpmiInstance->PeiIpmi2BmcDataDesc); + return Status; } /*************************************************************************= **** @@ -176,60 +371,6 @@ PeimIpmiInterfaceInit ( } // PeimIpmiInterfaceInit() -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 - ---*/ -{ - // - // This Will be unchanged ( BMC/KCS style ) - // - return PeiIpmiSendCommandToBmc ( - This, - NetFunction, - Lun, - Command, - CommandData, - (UINT8) CommandDataSize, - ResponseData, - (UINT8 *) ResponseDataSize, - NULL - ); -} // IpmiSendCommand() EFI_STATUS PeiGetIpmiBmcStatus ( diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/= Pei/PeiGenericIpmi.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Ge= nericIpmi/Pei/PeiGenericIpmi.h index d31af85325..59b26b6c86 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= GenericIpmi.h +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= GenericIpmi.h @@ -3,6 +3,7 @@ @copyright Copyright 2017 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -23,7 +24,9 @@ #include #include #include +#include +#include "PeiIpmiHooks.h" #include "PeiIpmiBmcDef.h" #include "PeiIpmiBmc.h" diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/= Pei/PeiGenericIpmi.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/= GenericIpmi/Pei/PeiGenericIpmi.inf index a646161ce1..c42c828c2f 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= GenericIpmi.inf +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= GenericIpmi.inf @@ -3,6 +3,7 @@ # # @copyright # Copyright 2017 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
# SPDX-License-Identifier: BSD-2-Clause-Patent ## @@ -30,6 +31,8 @@ PeiIpmiBmcDef.h PeiGenericIpmi.c PeiGenericIpmi.h + PeiIpmiHooks.c + PeiIpmiHooks.h [Packages] MdePkg/MdePkg.dec @@ -44,17 +47,28 @@ ReportStatusCodeLib TimerLib IpmiPlatformHookLib + HobLib + BmcCommonInterfaceLib + BtInterfaceLib + SsifInterfaceLib [Guids] + gPeiIpmiHobGuid [Ppis] gPeiIpmiTransportPpiGuid #ALWAYS PRODUCE + gPeiIpmiTransport2PpiGuid [Pcd] gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiIoBaseAddress gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiBmcReadyDelayTimer gIpmiFeaturePkgTokenSpaceGuid.PcdSioMailboxBaseAddress gIpmiFeaturePkgTokenSpaceGuid.PcdSignalPreBootToBmc - + gIpmiFeaturePkgTokenSpaceGuid.PcdDefaultSystemInterface + gIpmiFeaturePkgTokenSpaceGuid.PcdBtInterfaceSupport + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifInterfaceSupport + gIpmiFeaturePkgTokenSpaceGuid.PcdKcsInterfaceSupport + gIpmiFeaturePkgTokenSpaceGuid.PcdBtControlPort + [Depex] TRUE diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/= Pei/PeiIpmiBmc.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Generi= cIpmi/Pei/PeiIpmiBmc.c index 32665b3e22..1bd7657c5a 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= IpmiBmc.c +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= IpmiBmc.c @@ -3,6 +3,7 @@ @copyright Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -234,7 +235,7 @@ Returns: EFI_STATUS -PeiIpmiBmcStatus ( +IpmiBmcStatus ( IN PEI_IPMI_TRANSPORT_PPI *This, OUT BMC_STATUS *BmcStatus, OUT SM_COM_ADDRESS *ComAddress, diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/= Pei/PeiIpmiBmc.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Generi= cIpmi/Pei/PeiIpmiBmc.h index 40b9429e84..51ba65966a 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= IpmiBmc.h +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= IpmiBmc.h @@ -3,6 +3,7 @@ @copyright Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -35,4 +36,12 @@ SM_IPMI_BMC_SIGNATURE \ ) +#define INSTANCE_FROM_PEI_IPMI_TRANSPORT2_THIS(a) \ + CR ( \ + a, \ + PEI_IPMI_BMC_INSTANCE_DATA, \ + IpmiTransport2Ppi, \ + SM_IPMI_BMC_SIGNATURE \ + ) + #endif // _PEI_IPMI_BMC_H_ diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/= Pei/PeiIpmiBmcDef.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gen= ericIpmi/Pei/PeiIpmiBmcDef.h index 3fbe70ce62..2799f2bba6 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= IpmiBmcDef.h +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= IpmiBmcDef.h @@ -3,6 +3,7 @@ @copyright Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -10,6 +11,8 @@ #define _PEI_IPMI_COMMON_BMC_H_ #include +#include +#include "ServerManagement.h" #define MAX_TEMP_DATA 160 #define BMC_SLAVE_ADDRESS 0x20 @@ -46,16 +49,18 @@ // Pei Ipmi instance data // typedef struct { - UINTN Signature; - UINT64 KcsTimeoutPeriod; - UINT8 SlaveAddress; - UINT8 TempData[MAX_TEMP_DATA]; - BMC_STATUS BmcStatus; - UINT64 ErrorStatus; - UINT8 SoftErrorCount; - UINT16 IpmiIoBase; - PEI_IPMI_TRANSPORT_PPI IpmiTransportPpi; - EFI_PEI_PPI_DESCRIPTOR PeiIpmiBmcDataDesc; + UINTN Signature; + UINT64 KcsTimeoutPeriod; + UINT8 SlaveAddress; + UINT8 TempData[MAX_TEMP_DATA]; + BMC_STATUS BmcStatus; + UINT64 ErrorStatus; + UINT8 SoftErrorCount; + UINT16 IpmiIoBase; + PEI_IPMI_TRANSPORT_PPI IpmiTransportPpi; + IPMI_TRANSPORT2 IpmiTransport2Ppi; + EFI_PEI_PPI_DESCRIPTOR PeiIpmiBmcDataDesc; + EFI_PEI_PPI_DESCRIPTOR PeiIpmi2BmcDataDesc; } PEI_IPMI_BMC_INSTANCE_DATA; // @@ -152,5 +157,11 @@ Returns: --*/ ; +typedef struct _PEI_IPMI_DATA_HOB PEI_IPMI_DATA_HOB; + +struct _PEI_IPMI_DATA_HOB { + UINTN IpmiInstance; /// IpmiInstance po= inter. + PEI_IPMI_DATA_HOB *PreMemIpmiDataHobPtr; ///< HOB Data point= er before Memory discovered +}; #endif //_PEI_IPMI_COMMON_BMC_H_ 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..9cc3671aa6 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= IpmiHooks.c @@ -0,0 +1,316 @@ +/** @file + IPMI common hook functions + + @copyright + 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 + + 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 + + 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..cacb4ec76e --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= IpmiHooks.h @@ -0,0 +1,211 @@ +/** @file + IPMI common hook functions head file + + @copyright + 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 + +// +// 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/GenericIpmi/= Smm/SmmGenericIpmi.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Ge= nericIpmi/Smm/SmmGenericIpmi.c index fda215baaa..35faf93e30 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Smm/Smm= GenericIpmi.c +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Smm/Smm= GenericIpmi.c @@ -3,6 +3,7 @@ @copyright Copyright 1999 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -24,6 +25,7 @@ #include "IpmiBmcCommon.h" #include "IpmiBmc.h" #include +#include IPMI_BMC_INSTANCE_DATA *mIpmiInstance; EFI_HANDLE mImageHandle; @@ -114,6 +116,112 @@ Returns: return Status; } +/** + Initialize the API and parameters for IPMI Transport2 Instance + + @param[in] IpmiInstance Pointer to IPMI Instance + + @return VOID Nothing. + +**/ +VOID +InitIpmiTransport2 ( + IN IPMI_BMC_INSTANCE_DATA *IpmiInstance + ) +{ + + IpmiInstance->IpmiTransport2.InterfaceType =3D FixedPcdGet8 (P= cdDefaultSystemInterface); + IpmiInstance->IpmiTransport2.IpmiTransport2BmcStatus =3D BmcStatusOk; + IpmiInstance->IpmiTransport2.IpmiSubmitCommand2 =3D IpmiSendCommand= 2; + IpmiInstance->IpmiTransport2.IpmiSubmitCommand2Ex =3D IpmiSendCommand= 2Ex; + +#if BtInterfaceSupport + InitBtInterfaceData (&IpmiInstance->IpmiTransport2); +#endif + +#if SsifInterfaceSupport + InitSsifInterfaceData (&IpmiInstance->IpmiTransport2); +#endif +} + +/** + Notify call back to initialize the interfaces and install Smm Ipmi + protocol. + + @param[in] Protocol Pointer to the protocol guid. + @param[in] Interface Pointer to the protocol instance. + @param[in] Handle Handle on which the protocol is installed. + + @return EFI_STATUS Status of Notify call back. + +**/ +EFI_STATUS +EFIAPI +SmmNotifyCallback ( + IN CONST EFI_GUID *Protocol, + IN VOID *Interface, + IN EFI_HANDLE Handle + ) +{ + + EFI_STATUS Status; + IPMI_INTERFACE_STATE InterfaceState; + + InterfaceState =3D IpmiInterfaceNotReady; + +#if SsifInterfaceSupport + InitSsifInterfaceData(&mIpmiInstance->IpmiTransport2); + + if (mIpmiInstance->IpmiTransport2.Interface.Ssif.InterfaceState =3D=3D I= pmiInterfaceInitialized){ + InterfaceState =3D IpmiInterfaceInitialized; + } +#endif + + if (InterfaceState !=3D IpmiInterfaceInitialized) { + return EFI_SUCCESS; + } + + // Default Interface data should be initialized to install Ipmi Transpor= t2 Protocol. + if (InterfaceState =3D=3D IpmiInterfaceInitialized) { + Handle =3D NULL; + Status =3D gSmst->SmmInstallProtocolInterface ( + &Handle, + &gSmmIpmiTransport2ProtocolGuid, + EFI_NATIVE_INTERFACE, + &mIpmiInstance->IpmiTransport2 + ); + } + return EFI_SUCCESS; +} + +/** + Registers Protocol call back + + @param ProtocolGuid Pointer to Protocol GUID to register call ba= ck + + @retval EFI_INVALID_PARAMETER If the ProtocolGuid is 0 or NULL. + @retval Others Status of Notify registration. +**/ +EFI_STATUS +SmmRegisterProtocolCallback ( + IN EFI_GUID *ProtocolGuid +) +{ + EFI_STATUS Status; + VOID *Registration; + + if ((ProtocolGuid =3D=3D NULL) || + ((ProtocolGuid !=3D NULL) && IsZeroBuffer (ProtocolGuid, sizeof (E= FI_GUID)))) { + return EFI_INVALID_PARAMETER; + } + + Status =3D gSmst->SmmRegisterProtocolNotify ( + ProtocolGuid, + SmmNotifyCallback, + &Registration ); + return Status; +} + EFI_STATUS SmmInitializeIpmiKcsPhysicalLayer ( IN EFI_HANDLE ImageHandle, @@ -141,10 +249,13 @@ Returns: UINT8 ErrorCount; EFI_HANDLE Handle; EFI_STATUS_CODE_VALUE StatusCodeValue[MAX_SOFT_COUNT]; + IPMI_INTERFACE_STATE InterfaceState; + UINT8 Index; DEBUG ((DEBUG_INFO,"SmmInitializeIpmiKcsPhysicalLayer entry \n")); - ErrorCount =3D 0; - mImageHandle =3D ImageHandle; + ErrorCount =3D 0; + mImageHandle =3D ImageHandle; + InterfaceState =3D IpmiInterfaceNotReady; mIpmiInstance =3D AllocateZeroPool (sizeof (IPMI_BMC_INSTANCE_DATA)); ASSERT (mIpmiInstance !=3D NULL); @@ -169,6 +280,7 @@ Returns: mIpmiInstance->IpmiTransport.IpmiSubmitCommand =3D IpmiSendCommand; mIpmiInstance->IpmiTransport.GetBmcStatus =3D IpmiGetBmcStatus; +#if KcsInterfaceSupport DEBUG ((DEBUG_INFO,"IPMI: Waiting for Getting BMC DID in SMM \n")); // // Get the Device ID and check if the system is in Force Update mode. @@ -190,6 +302,68 @@ Returns: &mIpmiInstance->IpmiTransport ); ASSERT_EFI_ERROR (Status); +#endif + + InitIpmiTransport2(mIpmiInstance); + + // Check interface data initialized successfully else register notify = protocol. + for (Index =3D SysInterfaceKcs; Index < SysInterfaceMax; Index++) { + + switch (Index) { +#if KcsInterfaceSupport + case SysInterfaceKcs: + if ((mIpmiInstance->BmcStatus !=3D BMC_HARDFAIL) && (mIpmi= Instance->BmcStatus !=3D BMC_UPDATE_IN_PROGRESS)) { + BMC_INTERFACE_STATUS BmcStatus; + mIpmiInstance->IpmiTransport2.Interface.KcsInterfaceSt= ate =3D IpmiInterfaceInitialized; + Status =3D CheckSelfTestByInterfaceType( + &mIpmiInstance->IpmiTranspo= rt2, + &BmcStatus, + SysInterfaceKcs); + if (!EFI_ERROR (Status) && (BmcStatus !=3D BmcStatusHa= rdFail)) { + InterfaceState =3D IpmiInterfaceInitialized; + } else { + mIpmiInstance->IpmiTransport2.Interface.KcsInterfa= ceState =3D IpmiInterfaceInitError; + } + } + break; +#endif + +#if BtInterfaceSupport + case SysInterfaceBt: + if (mIpmiInstance->IpmiTransport2.Interface.Bt.InterfaceSt= ate =3D=3D IpmiInterfaceInitialized){ + InterfaceState =3D IpmiInterfaceInitialized; + } + break; +#endif + +#if SsifInterfaceSupport + case SysInterfaceSsif: + if (mIpmiInstance->IpmiTransport2.Interface.Ssif.Interface= State =3D=3D IpmiInterfaceInitialized){ + InterfaceState =3D IpmiInterfaceInitialized; + } else if (mIpmiInstance->IpmiTransport2.Interface.Ssif.In= terfaceState =3D=3D IpmiInterfaceInitError) { + // Register protocol notify for SMBUS Protocol. + Status =3D SmmRegisterProtocolCallback (&mIpmiInstance= ->IpmiTransport2.Interface.Ssif.SsifInterfaceApiGuid); + } + break; +#endif + default: + break; + } + } + + // Default Interface data should be initialized to install Ipmi Transp= ort2 Protocol. + if (InterfaceState =3D=3D IpmiInterfaceInitialized) { + Handle =3D NULL; + Status =3D gSmst->SmmInstallProtocolInterface ( + &Handle, + &gSmmIpmiTransport2ProtocolGuid, + EFI_NATIVE_INTERFACE, + &mIpmiInstance->IpmiTransport2 + ); + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_ERROR,"IPMI Transport2 protocol install Status = =3D %r \n",Status)); + } + } DEBUG ((DEBUG_INFO,"SmmInitializeIpmiKcsPhysicalLayer exit \n")); diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/= Smm/SmmGenericIpmi.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/= GenericIpmi/Smm/SmmGenericIpmi.inf index f430195d1e..0e3a387c65 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Smm/Smm= GenericIpmi.inf +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Smm/Smm= GenericIpmi.inf @@ -3,6 +3,7 @@ # # @copyright # Copyright 2010 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
# SPDX-License-Identifier: BSD-2-Clause-Patent ## @@ -39,15 +40,25 @@ IoLib ReportStatusCodeLib TimerLib + BmcCommonInterfaceLib + BtInterfaceLib + SsifInterfaceLib [Protocols] gSmmIpmiTransportProtocolGuid # PROTOCOL ALWAYS_PROD= UCED + gSmmIpmiTransport2ProtocolGuid # PROTOCOL ALWAYS_PROD= UCED [Guids] [Pcd] gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiSmmIoBaseAddress gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiBmcReadyDelayTimer + gIpmiFeaturePkgTokenSpaceGuid.PcdDefaultSystemInterface + gIpmiFeaturePkgTokenSpaceGuid.PcdBtControlPort + gIpmiFeaturePkgTokenSpaceGuid.PcdBtInterfaceSupport + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifInterfaceSupport + gIpmiFeaturePkgTokenSpaceGuid.PcdKcsInterfaceSupport [Depex] - gIpmiTransportProtocolGuid + gIpmiTransportProtocolGuid AND + gSmmIpmiTransport2ProtocolGuid diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ipmi= Feature.dsc b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ipm= iFeature.dsc index 237a4fc006..98d9b602e8 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiFeature= .dsc +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiFeature= .dsc @@ -7,6 +7,7 @@ # for the build infrastructure. # # Copyright (c) 2019 - 2021, Intel Corporation. All rights reserved.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -41,10 +42,21 @@ [LibraryClasses.common.PEI_CORE,LibraryClasses.common.PEIM] IpmiBaseLib|IpmiFeaturePkg/Library/PeiIpmiBaseLib/PeiIpmiBaseLib.inf + SsifInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInt= erfaceLib/PeiSsifInterfaceLib.inf [LibraryClasses.common.DXE_DRIVER,LibraryClasses.common.UEFI_DRIVER] IpmiBaseLib|IpmiFeaturePkg/Library/IpmiBaseLib/IpmiBaseLib.inf +[LibraryClasses.common] + BmcCommonInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Bm= cCommonInterfaceLib.inf + BtInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BtInterfa= ceLib/BtInterfaceLib.inf + +[LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_DRIVE= R] + SsifInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInt= erfaceLib/DxeSsifInterfaceLib.inf + +[LibraryClasses.common.DXE_SMM_DRIVER] + SsifInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInt= erfaceLib/SmmSsifInterfaceLib.inf + ##########################################################################= ###### # # Component section - list of all components that need built for this feat= ure. 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..4d8d5e7160 --- /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 (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; /// + 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 + System Interface. +*/ +typedef struct { + UINT8 KcsInterfaceState; + BT_SYSTEM_INTERFACE Bt; ///< Bt interface. + SSIF_SYSTEM_INTERFACE Ssif; ///< Ssif interface. +} 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. + 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..e44b2920c0 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/Bmc= CommonInterfaceLib.h @@ -0,0 +1,186 @@ + +/** @file BmcCommonInterfaceLib.h + Bmc Common interface library functions. + + @copyright + 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 + + +/** + 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 + ); +#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..d1a8669223 --- /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 (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/SsifInterfaceLib.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/= Include/Library/SsifInterfaceLib.h new file mode 100644 index 0000000000..510ebe3072 --- /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 (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..fceef0b009 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ppi/IpmiTra= nsport2Ppi.h @@ -0,0 +1,22 @@ +/** @file + IPMI Ttransport2 PPI Header File. + + @copyright + 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..ee3ba9810e --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Protocol/Ip= miTransport2Protocol.h @@ -0,0 +1,29 @@ + +/** @file IpmiTransport2Protocol.h + IpmiTransport2 Protocol Header File. + + @copyright + 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/IpmiFeatureP= kg.dec b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/IpmiFeaturePkg.d= ec index 8c1b902446..3f2dd34093 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/IpmiFeaturePkg.dec +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/IpmiFeaturePkg.dec @@ -9,6 +9,7 @@ # # Copyright (c) 2019-2021, Intel Corporation. All rights reserved.
# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -42,17 +43,27 @@ ## @libraryclass Provides an API for the base IPMI library # IpmiBaseLib|Include/Library/IpmiBaseLib.h + + ## @libraryclass Provides generic functions among all interfaces. + BmcCommonInterfaceLib|Include/Library/BmcCommonInterfaceLib.h + BtInterfaceLib|Include/Library/BtInterfaceLib.h + + SsifInterfaceLib|Include/Library/SsifInterfaceLib.h [Guids] gIpmiFeaturePkgTokenSpaceGuid =3D {0xc05283f6, 0xd6a8, 0x48f3, {0x9b, = 0x59, 0xfb, 0xca, 0x71, 0x32, 0x0f, 0x12}} + gPeiIpmiHobGuid =3D {0xcb4d3e13, 0x1e34, 0x4373, {0x8a, 0= x81, 0xe9, 0x0, 0x10, 0xf1, 0xdb, 0xa4}} [Ppis] gPeiIpmiTransportPpiGuid =3D {0x7bf5fecc, 0xc5b5, 0x4b25, {0x81, 0x1b, 0= xb4, 0xb5, 0xb, 0x28, 0x79, 0xf7}} + gPeiIpmiTransport2PpiGuid =3D {0x8122CEBD, 0xF4FD, 0x4EA8, { 0x97, 0x6C,= 0xF0, 0x30, 0xAD, 0xDC, 0x4C, 0xB4 }} [Protocols] gIpmiTransportProtocolGuid =3D {0x6bb945e8, 0x3743, 0x433e, {0xb9, 0x0e= , 0x29, 0xb3, 0x0d, 0x5d, 0xc6, 0x30}} gSmmIpmiTransportProtocolGuid =3D {0x8bb070f1, 0xa8f3, 0x471d, {0x86, 0= x16, 0x77, 0x4b, 0xa3, 0xf4, 0x30, 0xa0}} gEfiVideoPrintProtocolGuid =3D {0x3dbf3e06, 0x9d0c, 0x40d3, {0xb2, 0= x17, 0x45, 0x5f, 0x33, 0x9e, 0x29, 0x09}} + gIpmiTransport2ProtocolGuid =3D { 0x4A1D0E66, 0x5271, 0x4E22, { 0x83, 0x= FE, 0x90, 0x92, 0x1B, 0x74, 0x82, 0x13 }} + gSmmIpmiTransport2ProtocolGuid =3D { 0x1DBD1503, 0x0A60, 0x4230, { 0xAA,= 0xA3, 0x80, 0x16, 0xD8, 0xC3, 0xDE, 0x2F }} [PcdsFeatureFlag] gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiFeatureEnable|FALSE|BOOLEAN|0xA0000= 001 @@ -61,6 +72,37 @@ gIpmiFeaturePkgTokenSpaceGuid.PcdMaxSOLChannels|3|UINT8|0xF0000001 #When True, BIOS will send a Pre-Boot signal to BMC gIpmiFeaturePkgTokenSpaceGuid.PcdSignalPreBootToBmc|FALSE|BOOLEAN|0xF000= 0002 + # typedef enum { + # SysInterfaceUnknown, // Unknown interface type. + # SysInterfaceKcs, // Kcs interface =3D 1. + # SysInterfaceSmic, // Smic interface =3D 2. + # SysInterfaceBt, // Bt interface =3D 3. + # SysInterfaceSsif, // Ssif interface =3D 4. + # SysInterfaceMax // Maximum interface type. + # } SYSTEM_INTERFACE_TYPE; + gIpmiFeaturePkgTokenSpaceGuid.PcdDefaultSystemInterface|1|UINT8|0xF00000= 03 + + #BT Base address, retry counter and delay parameters + gIpmiFeaturePkgTokenSpaceGuid.PcdBtCommandRetryCounter|0x0004E400|UINT32= |0xF0000004 + gIpmiFeaturePkgTokenSpaceGuid.PcdBtControlPort|0xE4|UINT16|0xF0000005 + gIpmiFeaturePkgTokenSpaceGuid.PcdBtBufferPort|0xE5|UINT16|0xF0000006 + gIpmiFeaturePkgTokenSpaceGuid.PcdBtDelayPerRetry|15|UINT32|0xF0000007 + gIpmiFeaturePkgTokenSpaceGuid.PcdBtInterruptMaskPort|0xE6|UINT16|0xF0000= 008 + gIpmiFeaturePkgTokenSpaceGuid.PcdBtBufferSize|0x40|UINT8|0xF0000009 + + #SSIF slave address, retry counter and delay parameters + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifSlaveAddress|0x10|UINT16|0xF000000A + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay|0xCB20|UINT32|0= xF000000B + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifCommandtRetryCounter|0x5|UINT16|0xF= 000000C + + #Interface access type for BMC communication. 0-MMIO, 1-IO + gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiDefaultAccessType|1|UINT8|0xF000000= D + gIpmiFeaturePkgTokenSpaceGuid.PcdMmioBaseAddress|0x0|UINT32|0xF000000E + gIpmiFeaturePkgTokenSpaceGuid.PcdBaseAddressRange|0x0|UINT32|0xF000000F + + gIpmiFeaturePkgTokenSpaceGuid.PcdKcsInterfaceSupport|1|UINT8|0xF0000010 + gIpmiFeaturePkgTokenSpaceGuid.PcdBtInterfaceSupport|1|UINT8|0xF0000011 + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifInterfaceSupport|1|UINT8|0xF0000012 [PcdsDynamic, PcdsDynamicEx] gIpmiFeaturePkgTokenSpaceGuid.PcdFRB2EnabledFlag|TRUE|BOOLEAN|0xD0000001 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..333d4a8643 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/BmcCommonInterfaceLib.c @@ -0,0 +1,227 @@ +/** @file BmcCommonInterfaceLib.c + BmcCommonInterfaceLib generic functions for all interfaces. + + @copyright + 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..f346a3afae --- /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 (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..3651727c41 --- /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 (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..dbc87f3e1e --- /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 (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/SsifInterfaceLib/DxeSsifInterfaceLib.c b/Features/Inte= l/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifI= nterfaceLib/DxeSsifInterfaceLib.c new file mode 100644 index 0000000000..99e25074f9 --- /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 (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..e61c916541 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.inf @@ -0,0 +1,39 @@ +## @file DxeSsifInterfaceLib.inf +# +# INF description file for SsifInterfaceLib Library for DXE and UEFI driv= ers. +# +# @copyright +# 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..02d50e9add --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.c @@ -0,0 +1,122 @@ +/** @file PeiSsifInterfaceLib.c + SSIF Transport Pei phase Implementation library functions. + + @copyright + 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..d7c410fc4f --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.inf @@ -0,0 +1,40 @@ +## @file PeiSsifInterfaceLib.inf +# +# INF description file for SsifInterfaceLib Library for PEIMs. +# +# @copyright +# 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..74c9f0206a --- /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 (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.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..ee67b659be --- /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 (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..da1d0c85b0 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/SsifInterfaceLibCommon.c @@ -0,0 +1,545 @@ +/** @file SsifInterfaceLibCommon.c + SSIF Transport Implementation common functions and variables. + + @copyright + 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= .