From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mx.groups.io with SMTP id smtpd.web11.3895.1686620700143039273 for ; Mon, 12 Jun 2023 18:45:00 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=hE8Bw37K; spf=pass (domain: intel.com, ip: 192.55.52.93, mailfrom: isaac.w.oram@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1686620700; x=1718156700; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=U5A/N8ALtoTex4cGINwAs6kXyXG4XH53NG0H+uPtivk=; b=hE8Bw37KKLnN4UaVoN4+UaTi7GJ/6cSEeazmodvn4lm4saHsWLLlQ2Bc 8QDwIZcrMPXZiKQkaU24JM7anziibbjC+ZmQPCGZkLL7Ws1mAL0HDv9fP k+XZyrb9j7v5JjsJUlb4wH0o8bHiCuAiXlT0KaXuIYvVQ7C77vZgkew1r dr0LtCly8glCYvhQSV2f5F860/Ntew8X9gS2amEML9cafEWFn5/GYXp4d EmgDXLPBoVQ7wQhMvEPchGZBUlLxLGxcZlWo1DV38g4ltXlHtCYee61Av GMaTwiXzg829GHdDN9xw4IDx3/+CP5F2kj+wwWPh+JJJktvbdhLZE0jBC w==; X-IronPort-AV: E=McAfee;i="6600,9927,10739"; a="355701438" X-IronPort-AV: E=Sophos;i="6.00,238,1681196400"; d="scan'208";a="355701438" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Jun 2023 18:44:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10739"; a="835699064" X-IronPort-AV: E=Sophos;i="6.00,238,1681196400"; d="scan'208";a="835699064" Received: from fmsmsx601.amr.corp.intel.com ([10.18.126.81]) by orsmga004.jf.intel.com with ESMTP; 12 Jun 2023 18:44:58 -0700 Received: from fmsmsx610.amr.corp.intel.com (10.18.126.90) by fmsmsx601.amr.corp.intel.com (10.18.126.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.23; Mon, 12 Jun 2023 18:44:57 -0700 Received: from FMSEDG603.ED.cps.intel.com (10.1.192.133) by fmsmsx610.amr.corp.intel.com (10.18.126.90) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.23 via Frontend Transport; Mon, 12 Jun 2023 18:44:57 -0700 Received: from NAM10-MW2-obe.outbound.protection.outlook.com (104.47.55.100) by edgegateway.intel.com (192.55.55.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.23; Mon, 12 Jun 2023 18:44:56 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=B/govirtLBWlFvqQjczdZTjXcbVkv3mDNtzounAXMICEGmzJ5CzoIYsUqUizd6auaJZfbWHcZ25wGD0OkaY6k5rcbtfQ+a3qeDjwHx5ZVPqXFj0sUxnvoypCd3mJgd91llcVyQWWkDfX350PkHyeYdQZduD+X9dbK3WzPlYCzbE+ctZM0QIfIw/LJD4moXB24GCOwVVlEzmtydSuHpl665CywyB0YvZRPLHqJ+Az6z2EcBYG5xnoJ/D2gNgqsKIZ3MDDtYPb3y46tie4puxTy2g8SaMpROBbbVMTsxL8SXgw9164jPGQ8AFl2AtKHh8i+pnHX51j5WuKtWYbDN4EWQ== 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=rJWiQkhWcKDo4XF7Dv0kE7rxiNTSJlV2p9amPMSzCAQ=; b=oFhfu87qXXbhyPVgO9mCrnNM9cw7SfvFjxCzXp+4l3grndzaQZj54UrnYl9mgwr3ldE4YzngzwDtzVtVTmpTgqNpruxwXynaM6To2zHF4rWZVksMcd4Vo0PsKpv2Wbp2VotLUB65Tme5VcFQjcaUma+jDc5AsNtY37S85ZZ1STUx4yH5WYWVDgO0u+04ly+wVvbGEDAzPjyESpMed3nw4wu0E6duJxzedX5RhjjRNG/kLWoRte9mmebtoEkrAWRQ1lEwwWZuJiur4GCqh8RdlQm3CxDl+cE2rOUTr5NX4Tdz5Z5oVXD6IaEbxhjD/Cd2aPWivwA4kf5ok6agtZkE2Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Received: from SA1PR11MB5801.namprd11.prod.outlook.com (2603:10b6:806:23d::13) by SN7PR11MB7667.namprd11.prod.outlook.com (2603:10b6:806:32a::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6455.32; Tue, 13 Jun 2023 01:44:50 +0000 Received: from SA1PR11MB5801.namprd11.prod.outlook.com ([fe80::6979:a90f:e224:41c5]) by SA1PR11MB5801.namprd11.prod.outlook.com ([fe80::6979:a90f:e224:41c5%4]) with mapi id 15.20.6455.043; Tue, 13 Jun 2023 01:44:50 +0000 From: "Isaac Oram" To: Arun K , "devel@edk2.groups.io" CC: "Desimone, Nathaniel L" , "Ramkumar Krishnamoorthi" , "Gao, Liming" Subject: Re: [edk2-devel][edk2-platforms][PATCH V3-3] IpmiFeaturePkg:Provided multiple IPMI interface support in Library Thread-Topic: [edk2-devel][edk2-platforms][PATCH V3-3] IpmiFeaturePkg:Provided multiple IPMI interface support in Library Thread-Index: AQHZnSzyVcplYVU3hE2nUoZbLp4i06+H5NTw Date: Tue, 13 Jun 2023 01:44:50 +0000 Message-ID: References: <21b9dc3c5e81b4eba7bcb535d69b35d990590e5b.1686573103.git.arunk@ami.com> In-Reply-To: <21b9dc3c5e81b4eba7bcb535d69b35d990590e5b.1686573103.git.arunk@ami.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: SA1PR11MB5801:EE_|SN7PR11MB7667:EE_ x-ms-office365-filtering-correlation-id: 06c8603c-69f1-4b88-59c4-08db6bafc6e7 x-ld-processed: 46c98d88-e344-4ed4-8496-4ed7712e255d,ExtAddr x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: Ao0882BIw1G41pmyOCYLGP00witsmcNrUAjbV4mf8kbMN2b/0rJijsgcCwVuPfGkcVO8IIR7FA933hIoRM2nyUrgQaarSdNPsYBLbk7zjVhfCov7RQT0A/k7NTDBTRZP/6bACvKRrnjzR++piTiMrbz/nZ+j6k2KQ3FWAfcoUNvQUKcutog88VOSPSq4M5s69oG3hpBvFWU8c8Xb3eclBf2pKUS5sRv4H7LoV/vJ1ZNzuBYpsCb1JsL1sPnBQHU+EA9LC7VbOMmLeqXRDmHGANqARNkjZ0o7XZoOJca9x7CmDtqeUMbbnjCSyFBjGY17ZsIe548jwjwUYzOhIRLeeVlJnb1zxx0zGYZo8CCOWJX0Hbx2Xh6PqnFCkeP98ry48mp2DEwyMsux1vm+Oisu4mlD5DYgUaK+MCQqIJ3FoLWU3fclwgNyKKbQvYF0UQ9kQjsxAjOA9Jct5gUK5Cd+xLfIiCDwFbZp6zWwTceqgJEGlNBzbA/rlI8t+6c6ameoUN1bGVQs6+OlUxJ9hCcFcuiRdhSd9GO6rY7gs33/CY3/6P6wcCQ/utHEzGH/jVOIZKb5K2uDsVuzRrGozTbB0HeStdnE/iD/yeOMcK09u1cWiYffsDgCKkDBfmoW1SY+JBSwsm1SziVXTzESWN70qA== x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SA1PR11MB5801.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230028)(366004)(396003)(346002)(39860400002)(376002)(136003)(451199021)(2906002)(30864003)(38070700005)(40140700001)(86362001)(33656002)(52536014)(66899021)(55016003)(5660300002)(7696005)(186003)(83380400001)(6506007)(9686003)(53546011)(26005)(122000001)(19627235002)(110136005)(54906003)(71200400001)(76116006)(66946007)(66446008)(478600001)(82960400001)(4326008)(66476007)(316002)(38100700002)(66556008)(8936002)(8676002)(41300700001)(64756008)(559001)(579004)(357404004);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?OMG6RATXrSldgXPbsm8ckeBGhhxr1a04mx+Yflb5oHpCfI45QmepPPgy0UoO?= =?us-ascii?Q?jeoHq77CXY8C3bdiAs2MRgrU/rGn1zZmWfvuzbVyG97Lh4OmAOJT35Je/p1B?= =?us-ascii?Q?TN2PIFUDOL8E/DH0OSpxIrIdJ5w7QkOzpY68TIvdxDlQYnGipEPCjz6i5y1f?= =?us-ascii?Q?83jkmDJKrsZv1P0Mx1pvSzFT6x2bADVdR8fDI2BDMZkl9OJUg3efskJnl9aq?= =?us-ascii?Q?iaLUyuWgQj2HHD2lag11ud8TB12kJJhDOl9zNkk1wObHiTDiCJTzyB2tJ4HD?= =?us-ascii?Q?t33IA7ihRSaxt2zy5Y+a+VK2BYRW2WVZMW90yVvlGy7hI7vKxyFVcdxHDAh3?= =?us-ascii?Q?nyiOitCF3d6Tn/RufS8URAlJXI92wE1FAYmmDGvKd6Ss8KR67+VsZIVCidxn?= =?us-ascii?Q?yIpMY69BgwxNT/XEVFeriPIiWzHt2lU28zX4sFGbHRpk/3AL5UfwC9QFxlD3?= =?us-ascii?Q?Q7fXjy+pMXljSZMaitq/sSk1G+FGXzIkxUqh8oVwjMGxTSY68eBBpFX5lPnU?= =?us-ascii?Q?C1QGx4Kv4mcdAbUfGs2tkbt8L/RA8kAztkh2m6S7FoXANJUS5wA/1UhOX64x?= =?us-ascii?Q?59EDGIpHFOxpU6E5q1aaByd194d4OWVwEeChaDKEEfVv4TBvumkmzZO/13I7?= =?us-ascii?Q?sSJxfIocZ39Sx+iLWPkI8ZSF7H7wJpU4dreKxJJsifiQ9S/u/IKYZW+Nb5HS?= =?us-ascii?Q?LHiB0qyCwoQkYYGdGp7+sDhr3YKkezZ5SXXtThSPqADzLx7rtcTXpaIN/x0R?= =?us-ascii?Q?i9TPIJp05fWJDeqTM0+Zv2DZ3ihLIO/XXjNi+mvYXdxJp+amLPniryTmVR2s?= =?us-ascii?Q?Zc9f3hv3IfHzEWuWqGxNOtq7rZeBcrhFzjMp/nD+XS1prIxD3+eZjLoZjG88?= =?us-ascii?Q?iCsjryAXEIVLJYclKKVqSuxuX0fSI9Xy3R8VSrsH0vHI3nqU+1NyEelvdERo?= =?us-ascii?Q?9HThne8rPzYW0UJjrLYd4xZlKAym2CAIO+7WGJBZvgJZp896vwDmd3RbgwGR?= =?us-ascii?Q?J4lvVW8Cyo9YgR6WY7UK26l+GW58AprmVgJi96F8xFIM2AHDSdtRXsnNIuXx?= =?us-ascii?Q?kEFqpWDyg0FdLqa1vsC0QFx3kY8CMLNtx2j31M79MoNmRE6JtQ9KTA/Apcm4?= =?us-ascii?Q?1S8SxPiwcisTfA5GergBtr01MlcySfXGzrqaV6DO03SsR5UQLw0QU3dD9zdl?= =?us-ascii?Q?SGgFuB+MV09SmrHXkS0DMWeM6anMJxBdv3w/9D70OYbWWfLbs+U+B6vKmw1S?= =?us-ascii?Q?fqqEfYb1SpF+Yqcb6F/6mdnkiKnTeaeRO4kHqYDinziqkiKmJoROVMl4Nl5a?= =?us-ascii?Q?JEbsWxadjkOaXKqjJmS+hXVfLYwEJqTnROl7iryPf+x3OQ6UEsL0smTH+GPZ?= =?us-ascii?Q?xYgdAFf9WXYDzF3yt5QF5US6V6OfUhCTz/GuPK5c0sVdtwS/zpIlEWBBqOnP?= =?us-ascii?Q?crHGvZFJvMuDDTsxMxNaDA9m/4hHKSNRF8oxrzNaAN/zEPyINSzJiHcZHWLy?= =?us-ascii?Q?t3I2VeftOojQNBE/nVHj4OJJKqugSpUWvOwEXRYJg66uHfUY0ZDEm6DtWeAZ?= =?us-ascii?Q?PyFydK9L+mzmCF63bmBSSh5ZINN5Amieoo0eLnPc?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: SA1PR11MB5801.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 06c8603c-69f1-4b88-59c4-08db6bafc6e7 X-MS-Exchange-CrossTenant-originalarrivaltime: 13 Jun 2023 01:44:50.3075 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: t5FNE9zbAJhnqzTU6tQjGcPDhWsNVb7np28T8GNrXU+4Ra+iOQxPHHVwR/eWPjBZeMCJ9N0vWchf2mW/RHREcg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR11MB7667 Return-Path: isaac.w.oram@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable The new library function comment blocks have lots of issues mismatching par= ameters. Some of the prior issues with coding style. Indents, (, { etc. This does not seem like the patch series supports git bisect. The first tw= o patches don't build without the third patch. One thing that is not clear to me is if multiple interfaces are supposed to= be supported/enabled at the same time. It seems like sometimes an action = is done for each one if enabled, and other times just the first one enabled= will perform an action and return. It seems like there is a PCD PcdDefaul= tSystemInterface to control which interface is enabled. But there doesn't = seem to be any error checking. E.G. if I select KCS and have it disabled v= ia PcdKcsInterfaceSupport, this seems like an invalid configuration and the= re is no build error. I would suggest that more comments be added to the various PCD describing e= xpected uses and combinations. I would also request adding details to the edk2-platforms\Features\Intel\Ou= tOfBandManagement\IpmiFeaturePkg\Readme.md describing libraries and their c= onfiguration. There are library and configuration sections exactly for exp= laining these kinds of design options supported and how to configure. Regards, Isaac -----Original Message----- From: Arun K =20 Sent: Monday, June 12, 2023 5:54 AM To: devel@edk2.groups.io; Arun K Cc: Oram, Isaac W ; Desimone, Nathaniel L ; Ramkumar Krishnamoorthi ; Gao, = Liming Subject: [edk2-devel][edk2-platforms][PATCH V3-3] IpmiFeaturePkg:Provided m= ultiple IPMI interface support in Library Created IpmiTransport2 PPI/Protocol to support multiple IPMI BMC Interface support such as KCS/BT/SSIF with 2 API's IpmiSubmitCommand2 & IpmiSubmitCommand2Ex. IpmiSubmitCommand2 - This API use the default interface (PcdDefaultSystemInterface) to send IPMI command. IpmiSubmitCommand2Ex - This API use the specific interface type to send IPMI command which is passed as an argument. Cc: Isaac Oram Cc: Nate DeSimone Cc: Liming Gao Signed-off-by: Arun K --- .../GenericIpmi/Pei/PeiIpmiHooks.c | 351 +++++++++++ .../GenericIpmi/Pei/PeiIpmiHooks.h | 213 +++++++ .../Include/IpmiNetFnAppDefinitions.h | 239 ++++++++ .../Include/IpmiTransport2Definitions.h | 153 +++++ .../Include/Library/BmcCommonInterfaceLib.h | 200 ++++++ .../Include/Library/BtInterfaceLib.h | 83 +++ .../Include/Library/IpmbInterfaceLib.h | 92 +++ .../Include/Library/SsifInterfaceLib.h | 165 +++++ .../Include/Ppi/IpmiTransport2Ppi.h | 23 + .../Include/Protocol/IpmiTransport2Protocol.h | 30 + .../BmcCommonInterfaceLib.c | 228 +++++++ .../BmcCommonInterfaceLib.inf | 26 + .../BtInterfaceLib/BtInterfaceLib.c | 570 ++++++++++++++++++ .../BtInterfaceLib/BtInterfaceLib.inf | 39 ++ .../IpmbInterfaceLib/DxeIpmbInterfaceLib.c | 94 +++ .../IpmbInterfaceLib/DxeIpmbInterfaceLib.inf | 38 ++ .../IpmbInterfaceLib/IpmbInterfaceLibCommon.c | 351 +++++++++++ .../IpmbInterfaceLib/PeiIpmbInterfaceLib.c | 100 +++ .../IpmbInterfaceLib/PeiIpmbInterfaceLib.inf | 38 ++ .../IpmbInterfaceLib/SmmIpmbInterfaceLib.c | 94 +++ .../IpmbInterfaceLib/SmmIpmbInterfaceLib.inf | 37 ++ .../SsifInterfaceLib/DxeSsifInterfaceLib.c | 131 ++++ .../SsifInterfaceLib/DxeSsifInterfaceLib.inf | 40 ++ .../SsifInterfaceLib/PeiSsifInterfaceLib.c | 123 ++++ .../SsifInterfaceLib/PeiSsifInterfaceLib.inf | 41 ++ .../SsifInterfaceLib/SmmSsifInterfaceLib.c | 148 +++++ .../SsifInterfaceLib/SmmSsifInterfaceLib.inf | 40 ++ .../SsifInterfaceLib/SsifInterfaceLibCommon.c | 546 +++++++++++++++++ 28 files changed, 4233 insertions(+) create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gener= icIpmi/Pei/PeiIpmiHooks.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gener= icIpmi/Pei/PeiIpmiHooks.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/IpmiNetFnAppDefinitions.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/IpmiTransport2Definitions.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/Library/BmcCommonInterfaceLib.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/Library/BtInterfaceLib.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/Library/IpmbInterfaceLib.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/Library/SsifInterfaceLib.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/Ppi/IpmiTransport2Ppi.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/Protocol/IpmiTransport2Protocol.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/BmcCommonInterfaceLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/BmcCommonInterfaceLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/IpmbInterfaceLib/IpmbInterfaceLibCommon.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/BmcInterfaceCommonAccess/SsifInterfaceLib/SsifInterfaceLibCommon.c diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/= Pei/PeiIpmiHooks.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gene= ricIpmi/Pei/PeiIpmiHooks.c new file mode 100644 index 0000000000..bd17cc4a35 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= IpmiHooks.c @@ -0,0 +1,351 @@ +/** @file + IPMI common hook functions + + @copyright + Copyright 1999 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include + +EFI_STATUS +PeiIpmiSendCommand ( + IN PEI_IPMI_TRANSPORT_PPI *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT32 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT32 *ResponseDataSize + ) +/*++ + +Routine Description: + + Send Ipmi Command in the right mode: HECI or KCS, to the + appropiate device, ME or BMC. + +Arguments: + + This - Pointer to IPMI protocol instance + NetFunction - Net Function of command to send + Lun - LUN of command to send + Command - IPMI command to send + CommandData - Pointer to command data buffer, if needed + CommandDataSize - Size of command data buffer + ResponseData - Pointer to response data buffer + ResponseDataSize - Pointer to response data buffer size + +Returns: + + EFI_INVALID_PARAMETER - One of the input values is bad + EFI_DEVICE_ERROR - IPMI command failed + EFI_BUFFER_TOO_SMALL - Response buffer is too small + EFI_UNSUPPORTED - Command is not supported by BMC + EFI_SUCCESS - Command completed successfully + +--*/ +{ + if (This =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // This Will be unchanged ( BMC/KCS style ) + // + return PeiIpmiSendCommandToBmc ( + This, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8 *) ResponseDataSize, + NULL + ); +} // IpmiSendCommand() + +EFI_STATUS +PeiIpmiSendCommand2 ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT32 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT32 *ResponseDataSize + ) +/*++ + +Routine Description: + + This API use the default interface (PcdDefaultSystemInterface) to send I= PMI command + in the right mode to the appropiate device, ME or BMC. + +Arguments: + + This - Pointer to IPMI protocol instance + NetFunction - Net Function of command to send + Lun - LUN of command to send + Command - IPMI command to send + CommandData - Pointer to command data buffer, if needed + CommandDataSize - Size of command data buffer + ResponseData - Pointer to response data buffer + ResponseDataSize - Pointer to response data buffer size + +Returns: + + EFI_INVALID_PARAMETER - One of the input values is bad + EFI_DEVICE_ERROR - IPMI command failed + EFI_BUFFER_TOO_SMALL - Response buffer is too small + EFI_UNSUPPORTED - Command is not supported by BMC + EFI_SUCCESS - Command completed successfully + +--*/ +{ + PEI_IPMI_BMC_INSTANCE_DATA *PeiIpmiInstance; + + if (This =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + PeiIpmiInstance =3D INSTANCE_FROM_PEI_IPMI_TRANSPORT2_THIS(This); + +#if KcsInterfaceSupport + if ((PeiIpmiInstance->IpmiTransport2Ppi.InterfaceType =3D=3D SysInterfac= eKcs) && + (PeiIpmiInstance->IpmiTransport2Ppi.Interface.KcsInterfaceState =3D= =3D IpmiInterfaceInitialized)) { + + return PeiIpmiSendCommand ( + &PeiIpmiInstance->IpmiTransportPpi, + NetFunction, + Lun, + Command, + CommandData, + CommandDataSize, + ResponseData, + ResponseDataSize + ); + } +#endif + +#if BtInterfaceSupport + if ((PeiIpmiInstance->IpmiTransport2Ppi.InterfaceType =3D=3D SysInterfac= eBt) && + (PeiIpmiInstance->IpmiTransport2Ppi.Interface.Bt.InterfaceState =3D= =3D IpmiInterfaceInitialized)) { + + return IpmiBtSendCommandToBmc ( + &PeiIpmiInstance->IpmiTransport2Ppi, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8*) ResponseDataSize, + NULL + ); + } +#endif + +#if SsifInterfaceSupport + if ((PeiIpmiInstance->IpmiTransport2Ppi.InterfaceType =3D=3D SysInterfac= eSsif) && + (PeiIpmiInstance->IpmiTransport2Ppi.Interface.Ssif.InterfaceState = =3D=3D IpmiInterfaceInitialized)) { + return IpmiSsifSendCommandToBmc ( + &PeiIpmiInstance->IpmiTransport2Ppi, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8*) ResponseDataSize, + NULL + ); + } +#endif + +#if IpmbInterfaceSupport + if ((PeiIpmiInstance->IpmiTransport2Ppi.InterfaceType =3D=3D SysInterfac= eIpmb) && + (PeiIpmiInstance->IpmiTransport2Ppi.Interface.Ipmb.InterfaceState = =3D=3D IpmiInterfaceInitialized)) { + return IpmiIpmbSendCommandToBmc ( + &PeiIpmiInstance->IpmiTransport2Ppi, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8*) ResponseDataSize, + NULL + ); + } +#endif + return EFI_UNSUPPORTED; +} // IpmiSendCommand() + +EFI_STATUS +PeiIpmiSendCommand2Ex ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT32 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT32 *ResponseDataSize, + IN SYSTEM_INTERFACE_TYPE InterfaceType + ) +{ +/*++ +Routine Description: + + This API use the specific interface type to send IPMI command + in the right mode to the appropiate device, ME or BMC. + +Arguments: + + This - Pointer to IPMI protocol instance + NetFunction - Net Function of command to send + Lun - LUN of command to send + Command - IPMI command to send + CommandData - Pointer to command data buffer, if needed + CommandDataSize - Size of command data buffer + ResponseData - Pointer to response data buffer + ResponseDataSize - Pointer to response data buffer size + InterfaceType - BMC Interface type. + +Returns: + + EFI_INVALID_PARAMETER - One of the input values is bad + EFI_DEVICE_ERROR - IPMI command failed + EFI_BUFFER_TOO_SMALL - Response buffer is too small + EFI_UNSUPPORTED - Command is not supported by BMC + EFI_SUCCESS - Command completed successfully + +--*/ + + PEI_IPMI_BMC_INSTANCE_DATA *PeiIpmiInstance; + + if (This =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + PeiIpmiInstance =3D INSTANCE_FROM_PEI_IPMI_TRANSPORT2_THIS(This); + +#if KcsInterfaceSupport + if ((InterfaceType =3D=3D SysInterfaceKcs) && + (PeiIpmiInstance->IpmiTransport2Ppi.Interface.KcsInterfaceState =3D= =3D IpmiInterfaceInitialized)) { + + return PeiIpmiSendCommand ( + &PeiIpmiInstance->IpmiTransportPpi, + NetFunction, + Lun, + Command, + CommandData, + CommandDataSize, + ResponseData, + ResponseDataSize + ); + } +#endif + +#if BtInterfaceSupport + + if ((InterfaceType =3D=3D SysInterfaceBt) && + (PeiIpmiInstance->IpmiTransport2Ppi.Interface.Bt.InterfaceState =3D= =3D IpmiInterfaceInitialized)) { + + return IpmiBtSendCommandToBmc ( + &PeiIpmiInstance->IpmiTransport2Ppi, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8*) ResponseDataSize, + NULL + ); + } +#endif + +#if SsifInterfaceSupport + + if ((InterfaceType =3D=3D SysInterfaceSsif) && + (PeiIpmiInstance->IpmiTransport2Ppi.Interface.Ssif.InterfaceState = =3D=3D IpmiInterfaceInitialized)) { + + return IpmiSsifSendCommandToBmc ( + &PeiIpmiInstance->IpmiTransport2Ppi, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8*) ResponseDataSize, + NULL + ); + } +#endif + +#if IpmbInterfaceSupport + if ((InterfaceType =3D=3D SysInterfaceIpmb) && + (PeiIpmiInstance->IpmiTransport2Ppi.Interface.Ipmb.InterfaceState = =3D=3D IpmiInterfaceInitialized)) { + + return IpmiIpmbSendCommandToBmc ( + &PeiIpmiInstance->IpmiTransport2Ppi, + NetFunction, + Lun, + Command, + CommandData, + (UINT8) CommandDataSize, + ResponseData, + (UINT8*) ResponseDataSize, + NULL + ); + } +#endif + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +PeiIpmiBmcStatus ( + IN PEI_IPMI_TRANSPORT_PPI *This, + OUT BMC_STATUS *BmcStatus, + OUT SM_COM_ADDRESS *ComAddress, + IN VOID *Context + ) +/*++ + +Routine Description: + + Updates the BMC status and returns the Com Address + +Arguments: + + This - Pointer to IPMI protocol instance + BmcStatus - BMC status + ComAddress - Com Address + +Returns: + + EFI_SUCCESS - Success + +--*/ +{ + + if ((This =3D=3D NULL) || (BmcStatus =3D=3D NULL) || (ComAddress =3D=3D = NULL)) { + return EFI_INVALID_PARAMETER; + } + + return IpmiBmcStatus ( + This, + BmcStatus, + ComAddress, + NULL + ); +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/= Pei/PeiIpmiHooks.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gene= ricIpmi/Pei/PeiIpmiHooks.h new file mode 100644 index 0000000000..bba61d1e45 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericIpmi/Pei/Pei= IpmiHooks.h @@ -0,0 +1,213 @@ +/** @file + IPMI common hook functions head file + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _IPMI_HOOKS_H +#define _IPMI_HOOKS_H + +#include +#include +#include +#include +#include +#include +#include + +// +// Internal(hook) function list +// + +EFI_STATUS +PeiIpmiSendCommand ( + IN PEI_IPMI_TRANSPORT_PPI *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT32 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT32 *ResponseDataSize + ) +/*++ + +Routine Description: + + Send Ipmi Command in the right mode: HECI or KCS, to the + appropiate device, ME or BMC. + +Arguments: + + This - Pointer to IPMI protocol instance + NetFunction - Net Function of command to send + Lun - LUN of command to send + Command - IPMI command to send + CommandData - Pointer to command data buffer, if needed + CommandDataSize - Size of command data buffer + ResponseData - Pointer to response data buffer + ResponseDataSize - Pointer to response data buffer size + +Returns: + + EFI_INVALID_PARAMETER - One of the input values is bad + EFI_DEVICE_ERROR - IPMI command failed + EFI_BUFFER_TOO_SMALL - Response buffer is too small + EFI_UNSUPPORTED - Command is not supported by BMC + EFI_SUCCESS - Command completed successfully + +--*/ +; + +EFI_STATUS +PeiIpmiSendCommand2 ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT32 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT32 *ResponseDataSize + ) +/*++ + +Routine Description: + + This API use the default interface (PcdDefaultSystemInterface) to send I= PMI command + in the right mode to the appropiate device, ME or BMC. + +Arguments: + + This - Pointer to IPMI protocol instance + NetFunction - Net Function of command to send + Lun - LUN of command to send + Command - IPMI command to send + CommandData - Pointer to command data buffer, if needed + CommandDataSize - Size of command data buffer + ResponseData - Pointer to response data buffer + ResponseDataSize - Pointer to response data buffer size + +Returns: + + EFI_INVALID_PARAMETER - One of the input values is bad + EFI_DEVICE_ERROR - IPMI command failed + EFI_BUFFER_TOO_SMALL - Response buffer is too small + EFI_UNSUPPORTED - Command is not supported by BMC + EFI_SUCCESS - Command completed successfully + +--*/ +; + + +EFI_STATUS +PeiIpmiSendCommand2Ex ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT32 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT32 *ResponseDataSize, + IN SYSTEM_INTERFACE_TYPE InterfaceType + ); [Isaac] There is inconsistent place of semicolons in this file. + +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, [Isaac] There are two instances like the preceding line that are not vertic= ally aligned with other parameters. + OUT SM_COM_ADDRESS *ComAddress, + IN VOID *Context + ) +/*++ + +Routine Description: + + Updates the BMC status and returns the Com Address + +Arguments: + + This - Pointer to IPMI protocol instance + BmcStatus - BMC status + ComAddress - Com Address + Context - Context + +Returns: + + EFI_SUCCESS - Success + +--*/ +; + +EFI_STATUS +IpmiBmcStatus ( + IN PEI_IPMI_TRANSPORT_PPI *This, + OUT BMC_STATUS *BmcStatus, + OUT SM_COM_ADDRESS *ComAddress, + IN VOID *Context + ) +/*++ + +Routine Description: + + Updates the BMC status and returns the Com Address + +Arguments: + + This - Pointer to IPMI protocol instance + BmcStatus - BMC status + ComAddress - Com Address + Context - Context + +Returns: + + EFI_SUCCESS - Success + +--*/ +; +#endif diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ipmi= NetFnAppDefinitions.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/I= nclude/IpmiNetFnAppDefinitions.h new file mode 100644 index 0000000000..ebc98c856a --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiNetFnAp= pDefinitions.h @@ -0,0 +1,239 @@ + +/** @file IpmiNetFnAppDefinitions.h + Ipmi NetFn Application additional commands and its structures. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _IPMI_NETFN_APP_DEFINITIONS_H_ +#define _IPMI_NETFN_APP_DEFINITIONS_H_ + +#include + +#define IPMI_SPEC_VERSION_1_5 0x51 +#define IPMI_SPEC_VERSION_2_0 0x02 +#define IPMI_APP_SELFTEST_RESERVED 0xFF + +#pragma pack(1) +/** + Get Bmc global enables command response. +*/ +typedef struct { + /// Completion code. + UINT8 CompletionCode; + UINT8 ReceiveMsgQueueInterrupt : 1; ///< Receive Message Queue I= nterrupt. + UINT8 EventMsgBufferFullInterrupt : 1; ///< Event Message Buffer Fu= ll Interrupt. + UINT8 EventMsgBuffer : 1; ///< Event Message Buffer. + UINT8 SystemEventLogging : 1; ///< System Event Logging. + UINT8 Reserved : 1; ///< Reserved. + UINT8 OEM0 : 1; ///< OEM0 interrupt. + UINT8 OEM1 : 1; ///< OEM1 interrupt. + UINT8 OEM2 : 1; ///< OEM2 interrupt. +} GET_BMC_GLOBAL_ENABLES_RESPONSE; + +/** + Channel access type. + */ +typedef enum { + ChannelAccessTypeReserved0, ///< Reserved0 + ChannelAccessTypeNonVolatile, ///< NonVolatile + ChannelAccessTypePresentVolatileSetting, ///< PresentVolatileSetting + ChannelAccessTypeReserved1 ///< Reserved1 +} CHANNEL_ACCESS_TYPE; + +/** + Channel access modes. +*/ +typedef enum { + ChannelAccessModeDisabled, ///< Disabled Channel Access Mode. + ChannelAccessModePreBootOnly, ///< Pre-Boot Only Channel Access = Mode. + ChannelAccessModeAlwaysAvailable, ///< Always Available Channel Acce= ss Mode. + ChannelAccessModeShared ///< Shared Channel Access Mode. +} CHANNEL_ACCESS_MODES; + +/** + SSIF read/write support. +*/ +typedef enum { + SsifSinglePartRw, ///< Single Part read-write. + SsifMultiPartRw, ///< Multi Part read-write. + SsifMultiPartRwWithMiddle, ///< Multi Part read-write With Middle. + SsifReserved ///< Reserved. +} SSIF_READ_WRITE_SUPPORT; + +/** + Channnel states. +*/ +typedef enum { + DisbleChannel =3D 0, ///< Disble Channel. + EnableChannel, ///< Enable Channel. + GetChannelState, ///< Get Channel State. + ChannelStateReserved ///< Channel State Reserved. +} CHANNEL_STATE; + +/** + Enable message channel command request structure. +*/ +typedef struct { + UINT8 ChannelNumber : 4; /// Channel Number. + UINT8 Reserved1 : 4; ///< Reserved. + UINT8 ChannelState : 2; ///< Channel State. + UINT8 Reserved2 : 6; ///< Reserved. +} IPMI_ENABLE_MESSAGE_CHANNEL_REQUEST; + +/** + Enable message channel command response structure. +*/ +typedef struct { + UINT8 CompletionCode; /// Completion code. + UINT8 ChannelNumber : 4; ///< Channel Number. + UINT8 Reserved1 : 4; ///< Reserved. + UINT8 ChannelState : 1; ///< Channel State. + UINT8 Reserved2 : 7; ///< Reserved. +} IPMI_ENABLE_MESSAGE_CHANNEL_RESPONSE; + +/** + Set System Info Parameters Command. +*/ +#define IPMI_APP_SET_SYSTEM_INFO 0x58 + +/** + System Info String Encoding. +*/ +typedef enum { + SysInfoAscii, ///< Ascii + SysInfoUtf8, ///< Utf8 + SysInfoUnicode ///< Unicode +} SYSTEM_INFO_STRING_ENCODING; + +/** + System parameter selector. +*/ +typedef enum { + SysInfoSetInProgress, ///< SetInProgress. + SysInfoFirmwareVersion, ///< FirmwareVersion. + SysInfoSystemName, ///< SystemName. + SysInfoPrimaryOsName, ///< PrimaryOsName. + SysInfoPresentOsName, ///< PresentOsName. + SysInfoPresentOsVersion, ///< PresentOsVersion. + SysInfoBmcUrl, ///< BmcUrl. + SysInfoHyperviserUrl, ///< HyperviserUrl. +} SYSTEM_INFO_PARAMETER_SELECTOR; + +/** + System info set state. +*/ +typedef enum { + SysInfoStateSetComplete, ///< SetComplete. + SysInfoStateSetInProgress, ///< SetInProgress. + SysInfoStateCommitWrite, ///< StateCommitWrite. + SysInfoStateReserved, ///< StateReserved. +} SYSTEM_INFO_SET_STATE; + +/** + Set system info parameter command request Structure. +*/ +typedef struct { + UINT8 ParamSelector; /// Parameter selector. + UINT8 SetSelector; ///< Data 1 + UINT8 Data[16]; ///< Data 2:17 +} SET_SYSTEM_INFO_REQUEST; + +/** + Get System Info Parameters Command. +*/ +#define IPMI_APP_GET_SYSTEM_INFO 0x59 + +/** + Get system info Command request Structure. +*/ +typedef struct { + UINT8 Reserved : 7; /// Reserved. + UINT8 GetParam : 1; ///< Get Parameter. + UINT8 ParamSelector; ///< Parameter Selector. + UINT8 SetSelector; ///< Set selector. + UINT8 BlockSelector; ///< Block selector. +} GET_SYSTEM_INFO_REQUEST; + +/** + Get system info command response Structure. +*/ +typedef struct { + UINT8 CompletionCode; /// Completion code. + UINT8 ParamRevision; /// Parameter Revision + union { + struct { + UINT8 State : 2; ///< State. + UINT8 Reserved : 6; ///< Reserved. + }Progress; + UINT8 SetSelector; ///< Set Selector. + }Data1; + UINT8 Data[16]; ///< Data 2:17. +} GET_SYSTEM_INFO_RESPONSE; + +/** + Get system Guid Command response Structure. +*/ +typedef struct { + UINT8 CompletionCode; /// Completion code. + UINT8 Node[6]; ///< Node. + UINT8 Clock[2]; ///< Clock. + UINT16 Time_High; ///< Time High. + UINT16 Time_Mid; ///< Time Middle. + UINT32 Time_Low; ///< Time Low. +} GET_SYSTEM_GUID_RESPONSE; + +/** + Get Bt interface Capability Command response Structure. +*/ +typedef struct { + UINT8 CompletionCode; /// Completion code. + UINT8 OutstaningReq; /// + Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _IPMI_TRANSPORT2_DEFINITIONS_H_ +#define _IPMI_TRANSPORT2_DEFINITIONS_H_ + +typedef struct _IPMI_TRANSPORT2 IPMI_TRANSPORT2; + +/** @internal + BT Interface. +*/ +typedef struct { + UINT8 InterfaceState; /// Interface state. + UINT16 CtrlPort; ///< Control port. + UINT16 ComBuffer; ///< Communication buffer port. + UINT16 IntMaskPort; ///< Interrupt mask port. + UINTN MmioBaseAddress; ///< Mmio base address. + UINTN BaseAddressRange; ///< Mmio base address range to + ///< differentiate port address. + UINT8 AccessType; ///< Access type - IO or MMIO. + UINT32 BtRetryCount; ///< Delay counter for retry. + UINT8 BtSoftErrorCount; ///< Soft error count. + BOOLEAN BtTransportLocked; ///< Interface lock. + UINT8 HosttoBmcBufferSize; ///< Host to Bmc Buffer Size. + UINT8 BmctoHostBufferSize; ///< Bmc to Host Buffer Size. +} BT_SYSTEM_INTERFACE; + +/** @internal + SSIF Interface. +*/ +typedef struct { + UINT8 InterfaceState; /// Interface state. + EFI_GUID SsifInterfaceApiGuid; ///< Smbus instance guid. + UINTN SsifInterfaceApiPtr; ///< Smbus instance pointer. + UINT8 RwSupport; ///< Read-write support. + UINT16 SsifRetryCounter; ///< Retry counter. + BOOLEAN PecSupport; ///< Packet Error Check support. + BOOLEAN SmbAlertSupport; ///< Smbus alert support. + UINT8 SsifSoftErrorCount; ///< Soft error count. + BOOLEAN SsifTransportLocked; ///< Interface lock. +} SSIF_SYSTEM_INTERFACE; + +/** @internal + IPMB Interface. +*/ +typedef struct { + /// Interface state. + UINT8 InterfaceState; + EFI_GUID IpmbInterfaceApiGuid; ///< Ipmb instance guid. + UINTN IpmbInterfaceApiPtr; ///< Ipmb instance pointer. + UINT8 IpmbSoftErrorCount; ///< Soft error count. + BOOLEAN IpmbTransportLocked; ///< Interface lock. +} IPMB_SYSTEM_INTERFACE; + +/** @internal + System Interface. +*/ +typedef struct { + UINT8 KcsInterfaceState; + BT_SYSTEM_INTERFACE Bt; ///< Bt interface. + SSIF_SYSTEM_INTERFACE Ssif; ///< Ssif interface. + IPMB_SYSTEM_INTERFACE Ipmb; +} IPMI_SYSTEM_INTERFACE; + +/** @inrernal [Isaac] Typo above + Ipmi Interface Access Type. +*/ +typedef enum { + IpmiMmioAccess, ///< Mmio Access. + IpmiIoAccess ///< Io Access. +} IPMI_ACCESS_TYPE; + +/** @internal + Host to BMC Interface Type. +*/ +typedef enum { + SysInterfaceUnknown, ///< Unknown interface type. + SysInterfaceKcs, ///< Kcs interface. + SysInterfaceSmic, ///< Smic interface. + SysInterfaceBt, ///< Bt interface. + SysInterfaceSsif, ///< Ssif interface. + SysInterfaceIpmb, ///< Ipmb interface. + SysInterfaceMax ///< Maximum interface type. +} SYSTEM_INTERFACE_TYPE; + +/** @internal + BMC Interface status. +*/ +typedef enum { + BmcStatusOk, ///< Bmc status Ok. + BmcStatusSoftFail, ///< Bmc status Soft fail. + BmcStatusHardFail, ///< Bmc status Hard fail. + BmcStatusUpdateInProgress ///< Bmc status Update in progress. +} BMC_INTERFACE_STATUS; + +/** @internal + Ipmi Interface state. +*/ +typedef enum { + IpmiInterfaceNotReady, ///< Interface Not Ready. + IpmiInterfaceInitialized, ///< Interface Initialized. + IpmiInterfaceInitError, ///< Interface Initialization Error. +} IPMI_INTERFACE_STATE; + +// +// IPMI Function Prototypes +// +typedef +EFI_STATUS +(EFIAPI *IPMI_SEND_COMMAND2) ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT32 CommandDataSize, + OUT UINT8 *ResponseData, + OUT UINT32 *ResponseDataSize + ); + +typedef +EFI_STATUS +(EFIAPI *IPMI_SEND_COMMAND2Ex) ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT32 CommandDataSize, + OUT UINT8 *ResponseData, + OUT UINT32 *ResponseDataSize, + IN SYSTEM_INTERFACE_TYPE InterfaceType + ); + + +struct _IPMI_TRANSPORT2 { + UINT64 Revision; + IPMI_SEND_COMMAND2 IpmiSubmitCommand2; + IPMI_SEND_COMMAND2Ex IpmiSubmitCommand2Ex; + IPMI_SYSTEM_INTERFACE Interface; ///< System interface= . + SYSTEM_INTERFACE_TYPE InterfaceType; ///< Bmc Interface Ty= pe. + BMC_INTERFACE_STATUS IpmiTransport2BmcStatus; + EFI_HANDLE IpmiHandle; + UINT8 CompletionCode; +}; + +#endif diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Libr= ary/BmcCommonInterfaceLib.h b/Features/Intel/OutOfBandManagement/IpmiFeatur= ePkg/Include/Library/BmcCommonInterfaceLib.h new file mode 100644 index 0000000000..49cb1e6008 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/Bmc= CommonInterfaceLib.h @@ -0,0 +1,200 @@ + +/** @file BmcCommonInterfaceLib.h + Bmc Common interface library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _BMC_COMMON_INTERFACE_LIB_H_ +#define _BMC_COMMON_INTERFACE_LIB_H_ + +#include +#include +#include + +#define IPMI_APP_SELFTEST_RESERVED 0xFF + +#define IPMI_GET_SET_IN_PROGRESS_RETRY_COUNT 10 +#define IPMI_BIT_CLEAR 0 +#define IPMI_SELECTOR_NONE 0 +#define IPMI_CLEAR_FLAG 0 +#define IPMI_SET_FLAG 1 +#define IPMI_STALL 1000 +#define MIN_TO_100MS 60 * 10 +#define MAX_BMC_CMD_FAIL_COUNT 10 + +// Completion code macros. +#define IPMI_COMPLETION_CODE_SUCCESS 0x00 +#define IPMI_COMPLETION_CODE_DEVICE_SPECIFIC_START 0x01 +#define IPMI_COMPLETION_CODE_DEVICE_SPECIFIC_END 0x7E +#define IPMI_COMPLETION_CODE_COMMAND_SPECIFIC_START 0x80 +#define IPMI_COMPLETION_CODE_COMMAND_SPECIFIC_END 0xBE +#define IPMI_MAX_SOFT_COUNT 10 + +#define IPMI_MAX_BT_CMD_DATA_SIZE 0xFF + +#define IPMI_ERROR_COMPLETION_CODE(a) !((a =3D=3D IPMI_COMPLETION_CODE_= SUCCESS) || \ + ((a >=3D IPMI_COMPLETION_CODE= _DEVICE_SPECIFIC_START) && \ + (a <=3D IPMI_COMPLETION_CODE= _DEVICE_SPECIFIC_END)) || \ + ((a >=3D IPMI_COMPLETION_CODE= _COMMAND_SPECIFIC_START) && \ + (a <=3D IPMI_COMPLETION_CODE= _COMMAND_SPECIFIC_END)) \ + ) + +#define KcsInterfaceSupport FixedPcdGet8 (PcdKcsInterfaceSupp= ort) =3D=3D 1 +#define BtInterfaceSupport FixedPcdGet8 (PcdBtInterfaceSuppo= rt) =3D=3D 1 +#define SsifInterfaceSupport FixedPcdGet8 (PcdSsifInterfaceSup= port) =3D=3D 1 +#define IpmbInterfaceSupport FixedPcdGet8 (PcdIpmbInterfaceSup= port) =3D=3D 1 + +/** + Read 8 bit data from BMC port based on access type. + + @param[in] AccessType Specifies MMIO or IO access. + @param[in] Address Specifies Address to read. + + @return UINT8 Data read. + +**/ +UINT8 +IpmiBmcRead8 ( + IN UINT8 AccessType, + IN UINTN Address +); + +/** + Write 8 bit data to BMC port based on access type. + + @param[in] AccessType Specifies MMIO or IO access. + @param[in] Address Specifies Address to write. + @param[in] Data Specifies data to be written. + + @return Data written. + +**/ +UINT8 +IpmiBmcWrite8 ( + IN UINT8 AccessType, + IN UINTN Address, + IN UINT8 Data +); + +/** + Acquire the lock to use the IPMI transport. + + @param[out] Lock Pointer to Lock. + + @return VOID Returns nothing. + +**/ +VOID +IpmiTransportAcquireLock ( + OUT BOOLEAN *Lock +); + + +/** + Release the lock of IPMI transport. + + @param[out] Lock Pointer to Lock. + + @return VOID Returns nothing. + +**/ +VOID +IpmiTransportReleaseLock ( + OUT BOOLEAN *Lock +); + + +/** + Returns the Lock state of IPMI transport. + + @param[in] Lock Pointer to Lock. + + @retval TRUE IPMI transport is in lock state. + @retval FALSE IPMI transport is in release state. + +*/ +BOOLEAN +IpmiIsIpmiTransportlocked ( + IN BOOLEAN *Lock +); + +/** + Updates the SoftErrorCount of specific interface based on the BMC Erro= r input. + + @param[in] BmcError BMC Error. + @param[in, out] Interface Interface pointer to update soft error= count. + @param[in] InterfaceType Interface type to communicate. + + @retval EFI_SUCCESS Updated SoftErrorCount of specific int= erface. + @retval EFI_INVALID_PARAMETER Invalid Interface pointer or Interface= type. + +**/ +EFI_STATUS +IpmiUpdateSoftErrorCount ( + IN UINT8 BmcError, + IN OUT IPMI_SYSTEM_INTERFACE *Interface, + IN SYSTEM_INTERFACE_TYPE InterfaceType + ); + +/** + Execute the Self Test command with specific interface + + @param IpmiInstance IpmiInstance Data structure pointer. + @param InterfaceType Interface Type + @param[in] InterfaceType Interface type to communicate. + + @return EFI_STATUS Return Status +**/ +EFI_STATUS +CheckSelfTestByInterfaceType ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2, + IN OUT BMC_INTERFACE_STATUS *BmcStatus, + IN SYSTEM_INTERFACE_TYPE InterfaceType + ); + +/** + Initialize BT interface specific data. + + @param[in, out] Interface System interface pointer. + + @retval EFI_SUCCESS Interface is successfully initialized. + @retval Others Return status while initializing interface. + +**/ +EFI_STATUS +InitBtInterfaceData ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ); + +/** + Initialize SSIF interface specific data. + + @param[in, out] Interface System interface pointer. + + @retval EFI_SUCCESS Interface is successfully initialized. + @retval Others Return status while initializing interface. + +**/ +EFI_STATUS +InitSsifInterfaceData ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ); + +/** @internal + Initialize IPMB interface specific data. + + @param[in, out] Interface System interface pointer. + + @retval EFI_SUCCESS Interface is successfully initialized. + @retval Others Error status while initializing interface. + +**/ +EFI_STATUS +InitIpmbInterfaceData ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ); +#endif diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Libr= ary/BtInterfaceLib.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/In= clude/Library/BtInterfaceLib.h new file mode 100644 index 0000000000..183bfdda69 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/BtI= nterfaceLib.h @@ -0,0 +1,83 @@ + +/** @file BtInterfaceLib.h + BT interface common macros and declarations. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _BT_INTERFACE_LIB_H_ +#define _BT_INTERFACE_LIB_H_ + +#include +#include + +#define IPMI_MAX_BT_CMD_DATA_SIZE 0xFF +#define IPMI_CLR_WR_PTR_BIT 0x01 +#define IPMI_CLR_RD_PTR_BIT 0x02 +#define IPMI_H2B_ATN_BIT 0x04 +#define IPMI_B2H_ATN_BIT 0x08 +#define IPMI_H_BUSY 0x40 +#define IPMI_B_BUSY_BIT 0x80 + +/** + BT interface send command implementation. + + @param[in] Interface Pointer to System interface. + @param[in] NetFunction Net function of the command. + @param[in] Lun Logical Unit Number of the command= . + @param[in] Command Command to be sent to BMC. + @param[in] CommandData Command data to be sent along with + Command. + @param[in] CommandDataSize Command Data size. + @param[out] ResponseData Pointer to the response data buffe= r. + @param[in, out] ResponseDataSize Pointer to the response data size. + @param[out] CompletionCode Pointer to completion code. + @param[in] InterfaceType Interface type. + @param[in] Context NULL here. + + @retval EFI_UNSUPPORTED Interface type is not supported. + @retval EFI_NOT_READY Interface is not initialized. + @retval EFI_ACCESS_DENIED Interface is locked. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_BAD_BUFFER_SIZE Invalid buffer size. + @retval EFI_DEVICE_ERROR Error completion code or data size + retrieved is small. + @retval EFI_BUFFER_TOO_SMALL Buffer is too small to update response + data. + @retval EFI_SUCCESS Command sent successfully. + @return Others Error status returned from BMC while + executing the command. + +**/ +EFI_STATUS +EFIAPI +IpmiBtSendCommandToBmc ( [Isaac] The function parameters do not match the function description comme= nt block above. + 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 ( [Isaac] Parameters don't match function description. + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ); + +#endif diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Libr= ary/IpmbInterfaceLib.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/= Include/Library/IpmbInterfaceLib.h new file mode 100644 index 0000000000..5fc1176130 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/Ipm= bInterfaceLib.h @@ -0,0 +1,92 @@ + +/** @file IpmbInterfaceLib.h + IPMB interface common function declarations and macros. + +*/ + +#ifndef _IPMB_INTERFACE_LIB_H_ +#define _IPMB_INTERFACE_LIB_H_ + +#include +#include +#include + +#define IPMI_MAX_IPMB_CMD_DATA_SIZE 0xFF +#define IPMI_READ_FLAG 1 +#define IPMI_WRITE_FLAG 0 +#define IPMI_SEQ_NO 0 // IPMB Message Sequence Numb= er. + +/** @internal + Locate I2c Ppi/Protocol instance and initialize interface pointer. + + @param[in, out] Interface System interface pointer. + + @return EFI_STATUS Status returned from functions used. + +**/ +EFI_STATUS +IpmiGetI2cApiPtr ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 +); + +/** @internal + Send Ipmi command through Ipmb interface. + + @param[in] Interface Pointer to System interface. + @param[in] SlaveAddress I2C device slave address. + @param[in] RequestPacket Pointer to an EFI_I2C_REQUEST_PACKET + structure describing the I2C transaction. + + @return EFI_STATUS Status of the Send I2c command. + +**/ +EFI_STATUS +IpmiI2cSendCommand ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN UINTN SlaveAddress, + IN EFI_I2C_REQUEST_PACKET *RequestPacket + ); + +/** @internal + IPMB interface send command implementation. + + @param[in] Interface Pointer to System interface. + @param[in] NetFunction Net function of the command. + @param[in] Lun Logical Unit Number of the command= . + @param[in] Command Command to be sent to BMC. + @param[in] CommandData Command data to be sent along with + Command. + @param[in] CommandDataSize Command Data size. + @param[out] ResponseData Pointer to the response data buffe= r. + @param[in, out] ResponseDataSize Pointer to the response data size. + @param[out] CompletionCode Pointer to completion code. + @param[in] InterfaceType Interface type. + @param[in] Context NULL here. + + @retval EFI_UNSUPPORTED Interface type is not supported. + @retval EFI_NOT_READY Interface is not initialized. + @retval EFI_ACCESS_DENIED Interface is locked. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_BAD_BUFFER_SIZE Invalid buffer size. + @retval EFI_DEVICE_ERROR Error completion code or data size + retrieved is small. + @retval EFI_BUFFER_TOO_SMALL Buffer is too small to update response + data. + @retval EFI_SUCCESS Command sent successfully. + @return Others Error status returned from BMC while + executing the command. + +**/ +EFI_STATUS +IpmiIpmbSendCommandToBmc ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT8 CommandDataSize, + OUT UINT8 *ResponseData, + IN OUT UINT8 *ResponseDataSize, + IN VOID *Context ); + +#endif // #ifndef _IPMB_INTERFACE_LIB_H diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Libr= ary/SsifInterfaceLib.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/= Include/Library/SsifInterfaceLib.h new file mode 100644 index 0000000000..992e057385 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/Ssi= fInterfaceLib.h @@ -0,0 +1,165 @@ + +/** @file SsifInterfaceLib.h + SSIF interface common function declarations and macros. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _SSIF_INTERFACE_LIB_H +#define _SSIF_INTERFACE_LIB_H + +#include +#include +#include +#include + +#define IPMI_MAX_SSIF_CMD_DATA_SIZE 0xFF +#define IPMI_SMBUS_BLOCK_LENGTH 0x20 + +// Smbus Write Commands. +#define IPMI_SMBUS_SINGLE_WRITE_CMD 0x2 +#define IPMI_SMBUS_MULTI_WRITE_START_CMD 0x6 +#define IPMI_SMBUS_MULTI_WRITE_MIDDLE_CMD 0x7 +#define IPMI_SMBUS_MULTI_WRITE_END_CMD 0x8 + +// Smbus Read Commands. +#define IPMI_SMBUS_SINGLE_READ_CMD 0x3 +#define IPMI_SMBUS_MULTI_READ_START_CMD SMBUS_SINGLE_READ_CMD +#define IPMI_SMBUS_MULTI_READ_MIDDLE_CMD 0x9 +#define IPMI_SMBUS_MULTI_READ_END_CMD 0x9 +#define IPMI_SMBUS_MULTI_READ_RETRY_CMD 0xA + +#define IPMI_MULTI_READ_ZEROTH_STRT_BIT 0x0 +#define IPMI_MULTI_READ_FIRST_STRT_BIT 0x1 + + +/** + Check the SMBUS alert pin status function + + @param VOID Nothing. + + @retval TRUE Alert pin status is set. + @retval FALSE Alert pin status is not set. + +**/ +typedef BOOLEAN (SSIF_ALERT_PIN_CHECK) ( + VOID +); + +/** + Execute the Get System Interface Capability command and update the RwS= upport + and PecSupport of Ipmi Instance. + + @param IpmiInstance Ipmi Instance Data structure pointer. + + @return EFI_STATUS Return Status + +**/ +VOID +GetSystemInterfaceCapability ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ); + +/** + Execute the Get Global Enable command to get receive message queue int= errupt. + + @return VOID + +**/ +VOID +GetGlobalEnables ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 +); + +/** + Locate Smbus instance and initialize interface pointer. + + @param[in, out] Interface System interface pointer. + + @return EFI_STATUS Status returned while locating smbus instance. + +**/ +EFI_STATUS +IpmiGetSmbusApiPtr ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 +); + +/** + Send Ipmi command through Smbus instance. + + @param[in] Interface Pointer to System interface. + @param[in] SlaveAddress The SMBUS hardware address. + @param[in] Command This command is transmitted by the SMB= us + host controller to the SMBus slave dev= ice. + @param[in] Operation Operation to be performed. + @param[in] PecCheck Defines if Packet Error Code (PEC) + checking is required for this operatio= n. + @param[in, out] Length Signifies the number of bytes that thi= s + operation will do. + @param[in, out] Buffer Contains the value of data to execute = to + the SMBus slave device. The length of + this buffer is identified by Length. + + @retval EFI_NOT_FOUND Smbus instance is not found. + @retval Others Return status of the Smbus Execute operation. + +**/ +EFI_STATUS +IpmiSmbusSendCommand ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer +); + +/** + Ssif interface send command implementation. + + @param[in] Interface Pointer to System interface. + @param[in] NetFunction Net function of the command. + @param[in] Lun Logical Unit Number of the command= . + @param[in] Command Command to be sent to BMC. + @param[in] CommandData Command data to be sent along with + Command. + @param[in] CommandDataSize Command Data size. + @param[out] ResponseData Pointer to the response data buffe= r. + @param[in, out] ResponseDataSize Pointer to the response data size. + @param[out] CompletionCode Pointer to completion code. + @param[in] InterfaceType Interface type. + @param[in] Context NULL here. + + @retval EFI_UNSUPPORTED Interface type is not supported. + @retval EFI_NOT_READY Interface is not initialized. + @retval EFI_ACCESS_DENIED Interface is locked. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_BAD_BUFFER_SIZE Invalid buffer size. + @retval EFI_DEVICE_ERROR Error completion code or data size + retrieved is small. + @retval EFI_BUFFER_TOO_SMALL Buffer is too small to update response + data. + @retval EFI_SUCCESS Command sent successfully. + @return Others Error status returned from BMC while + executing the command. + +**/ +EFI_STATUS +EFIAPI +IpmiSsifSendCommandToBmc ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT8 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT8 *ResponseDataSize, + IN VOID *Context +); + +#endif diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ppi/= IpmiTransport2Ppi.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inc= lude/Ppi/IpmiTransport2Ppi.h new file mode 100644 index 0000000000..e977dd2526 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ppi/IpmiTra= nsport2Ppi.h @@ -0,0 +1,23 @@ +/** @file + IPMI Ttransport2 PPI Header File. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _IPMI_TRANSPORT2_PPI_H_ +#define _IPMI_TRANSPORT2_PPI_H_ + +#include +#include + +#define PEI_IPMI_TRANSPORT2_PPI_GUID \ + { \ + 0x8122CEBD, 0xF4FD, 0x4EA8, 0x97, 0x6C, 0xF0, 0x30, 0xAD, 0xDC, 0x4C, = 0xB4 \ + } + +extern EFI_GUID gPeiIpmiTransport2PpiGuid; + +#endif diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Prot= ocol/IpmiTransport2Protocol.h b/Features/Intel/OutOfBandManagement/IpmiFeat= urePkg/Include/Protocol/IpmiTransport2Protocol.h new file mode 100644 index 0000000000..b4186df303 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Protocol/Ip= miTransport2Protocol.h @@ -0,0 +1,30 @@ + +/** @file IpmiTransport2Protocol.h + IpmiTransport2 Protocol Header File. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _IPMI2_TRANSPORT2_PROTO_H_ +#define _IPMI2_TRANSPORT2_PROTO_H_ + +#include +#include + +#define IPMI_TRANSPORT2_PROTOCOL_GUID \ + { \ + 0x4a1d0e66, 0x5271, 0x4e22, { 0x83, 0xfe, 0x90, 0x92, 0x1b, 0x74, = 0x82, 0x13 } \ + } + +#define SMM_IPMI_TRANSPORT2_PROTOCOL_GUID \ + { \ + 0x1dbd1503, 0xa60, 0x4230, { 0xaa, 0xa3, 0x80, 0x16, 0xd8, 0xc3, 0= xde, 0x2f } \ + } + +extern EFI_GUID gIpmiTransport2ProtocolGuid; +extern EFI_GUID gSmmIpmiTransport2ProtocolGuid; + +#endif diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/BmcCommonInterfaceLib.c b/Features/Intel/OutOfBandMana= gement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BmcCommonInterfaceLi= b.c new file mode 100644 index 0000000000..086582cf0e --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/BmcCommonInterfaceLib.c @@ -0,0 +1,228 @@ +/** @file BmcCommonInterfaceLib.c + BmcCommonInterfaceLib generic functions for all interfaces. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include + +/** + Read 8 bit data from BMC port based on access type. + + @param[in] AccessType Specifies MMIO or IO access. + @param[in] Address Specifies Address to read. + + @return UINT8 Data read. + +**/ +UINT8 +IpmiBmcRead8 ( + IN UINT8 AccessType, + IN UINTN Address +) +{ + if (AccessType =3D=3D IpmiIoAccess) { + return IoRead8 (Address); + } else { + return MmioRead8 (Address); + } +} + +/** + Write 8 bit data to BMC port based on access type. + + @param[in] AccessType Specifies MMIO or IO access. + @param[in] Address Specifies Address to write. + @param[in] Data Specifies data to be written. + + @return Data written. + +**/ +UINT8 +IpmiBmcWrite8 ( + IN UINT8 AccessType, + IN UINTN Address, + IN UINT8 Data +) +{ + if (AccessType =3D=3D IpmiIoAccess) { + return IoWrite8 ( + Address, + Data ); + } else { + return MmioWrite8 ( + Address, + Data ); + } +} + +/** + Acquire the lock to use the IPMI transport. + + @param[out] Lock Pointer to Lock. + + @return VOID Returns nothing. + +**/ +VOID +IpmiTransportAcquireLock ( + OUT BOOLEAN *Lock +) +{ + *Lock =3D TRUE; +} + +/** + Release the lock of IPMI transport. + + @param[out] Lock Pointer to Lock. + + @return VOID Returns nothing. + +**/ +VOID +IpmiTransportReleaseLock ( + OUT BOOLEAN *Lock +) +{ + *Lock =3D FALSE; +} + +/** + Returns the Lock state of IPMI transport. + + @param[in] Lock Pointer to Lock. + + @retval TRUE IPMI transport is in lock state. + @retval FALSE IPMI transport is in release state. + +*/ +BOOLEAN +IpmiIsIpmiTransportlocked ( + IN BOOLEAN *Lock +) +{ + return *Lock; +} + +/** @internal + Updates the SoftErrorCount of specific interface based on the BMC Erro= r input. + + @param[in] BmcError BMC Error. + @param[in, out] Interface Interface pointer to update soft error= count. + @param[in] InterfaceType Interface type to communicate. + + @retval EFI_SUCCESS Updated SoftErrorCount of specific int= erface. + @retval EFI_INVALID_PARAMETER Invalid Interface pointer or Interface= type. + +**/ +EFI_STATUS +IpmiUpdateSoftErrorCount ( + IN UINT8 BmcError, + IN OUT IPMI_SYSTEM_INTERFACE *Interface, + IN SYSTEM_INTERFACE_TYPE InterfaceType + ) +{ + UINT8 Errors[] =3D {0xC0, 0xC3, 0xC4, 0xC9, 0xCE, 0xCF, 0xFF, 0x00}; + UINT8 Index =3D 0; + + if ((Interface =3D=3D NULL) || (InterfaceType <=3D SysInterfaceUnknown= ) || + (InterfaceType >=3D SysInterfaceMax)) { + return EFI_INVALID_PARAMETER; + } + + while (Errors[Index] !=3D 0) { + + if (Errors[Index] =3D=3D BmcError) { + + switch (InterfaceType) { + + case SysInterfaceBt: + Interface->Bt.BtSoftErrorCount++; + break; + + case SysInterfaceSsif: + Interface->Ssif.SsifSoftErrorCount++; + break; + + default : + break; + } + } + Index++; + } + return EFI_SUCCESS; +} + +/** + Updates the SoftErrorCount of specific interface based on the BMC Erro= r input. + + @param[in] BmcError BMC Error. + @param[in, out] Interface Interface pointer to update soft error= count. + @param[in] InterfaceType Interface type to communicate. + + @retval EFI_SUCCESS Updated SoftErrorCount of specific int= erface. + @retval EFI_INVALID_PARAMETER Invalid Interface pointer or Interface= type. + +**/ +EFI_STATUS +CheckSelfTestByInterfaceType ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2, + IN OUT BMC_INTERFACE_STATUS *BmcStatus, + IN SYSTEM_INTERFACE_TYPE InterfaceType + ) +{ + EFI_STATUS Status; + IPMI_SELF_TEST_RESULT_RESPONSE BstStatus; + UINT32 ResponseDataSize; + + if (IpmiTransport2 =3D=3D NULL || BmcStatus =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + ResponseDataSize =3D sizeof(IPMI_SELF_TEST_RESULT_RESPONSE); + + Status =3D IpmiTransport2->IpmiSubmitCommand2Ex ( + IpmiTransport2, + IPMI_NETFN_APP, + BMC_LUN, + IPMI_APP_GET_SELFTEST_RESULTS, + NULL, + 0, + (UINT8 *)&BstStatus, + &ResponseDataSize, + InterfaceType); + if (EFI_ERROR(Status)) { + *BmcStatus =3D BmcStatusHardFail; + return Status; + } + + if (BstStatus.CompletionCode =3D=3D IPMI_COMPLETION_CODE_SUCCESS) { + /* Check the self test results. Cases 55h - 58h are Ipmi defined + test results. Additional Cases are device specific test results= .*/ + switch (BstStatus.Result) { + case IPMI_APP_SELFTEST_NO_ERROR: // 0x55 + case IPMI_APP_SELFTEST_NOT_IMPLEMENTED: // 0x56 + case IPMI_APP_SELFTEST_RESERVED: // 0xFF + *BmcStatus =3D BmcStatusOk; + break; + + case IPMI_APP_SELFTEST_ERROR: // 0x57 + *BmcStatus =3D BmcStatusSoftFail; + break; + + default: // 0x58 and Other Device Specific Hardware Error. + *BmcStatus =3D BmcStatusHardFail; + break; + } + } + + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/BmcCommonInterfaceLib.inf b/Features/Intel/OutOfBandMa= nagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BmcCommonInterface= Lib.inf new file mode 100644 index 0000000000..33bb360c41 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/BmcCommonInterfaceLib.inf @@ -0,0 +1,26 @@ +## @file BmcCommonInterfaceLib.inf +# +# INF description file for BmcCommonInterfaceLib Library. +# +# @copyright +# Copyright 2016 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D BmcCommonInterfaceLib + FILE_GUID =3D D86308F8-5246-4B2F-AC25-E3D17170D6EF + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.1 + LIBRARY_CLASS =3D BmcCommonInterfaceLib + +[Sources] + BmcCommonInterfaceLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IpmiFeaturePkg/IpmiFeaturePkg.dec diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.c b/Features/Intel/OutOf= BandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BtInterfaceL= ib/BtInterfaceLib.c new file mode 100644 index 0000000000..a83620cfaf --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/BtInterfaceLib/BtInterfaceLib.c @@ -0,0 +1,570 @@ +/** @file BtInterfaceLib.c + BT Transport implementation library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include + +#define IPMI_BT_DELAY_PER_RETRY FixedPcdGet32 (PcdBtDelayPerRetry) + +/** + Get the BT interface port addresses based on access type. + + @param[in] Interface Pointer to System interface. + @param[out] BtCtrlPort Pointer to Bt control port. + @param[out] BtComBufferPort Pointer to Bt communication buffer por= t. + + @return VOID Nothing. + +**/ +VOID +GetBtPortAddresses ( + IN IPMI_SYSTEM_INTERFACE *Interface, + OUT UINTN *BtCtrlPort, + OUT UINTN *BtComBufferPort + ) +{ + // Update Bt Ports based on Interface AccessType. + if (Interface->Bt.AccessType =3D=3D IpmiIoAccess) { + *BtCtrlPort =3D (UINTN) Interface->Bt.CtrlPort; + *BtComBufferPort =3D (UINTN) Interface->Bt.ComBuffer; + } else { + *BtCtrlPort =3D Interface->Bt.MmioBaseAddress; + *BtComBufferPort =3D *BtCtrlPort + Interface->Bt.BaseAddressRange; + } +} + +/** + Sends the command to BT interface BMC port. + + @param[in] Interface Pointer to System interface. + @param[in] Context NULL here. + @param[in] Data Pointer to command data that will be sent to B= MC + along with Command. + @param[in] DataSize Size of the command data. + + @retval EFI_NOT_READY Interface is not ready to send data. + @retval EFI_SUCCESS Command sent to BMC successfully. + +**/ +EFI_STATUS +SendDataToBtBmcPort ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN VOID *Context, + IN UINT8 *Data, + IN UINT8 DataSize + ) +{ + UINT8 BtCntlData; + UINT8 Index; + UINT32 Retry; + UINTN BtCtrlPort; + UINTN BtComBufferPort; + IPMI_ACCESS_TYPE AccessType; + UINT8 TempDataSize; + BOOLEAN MultipleDataSend; + UINT32 BtRetryCount; + + MultipleDataSend =3D FALSE; + BtRetryCount =3D Interface->Bt.BtRetryCount; + AccessType =3D Interface->Bt.AccessType; + + // Get Bt Ports addresses. + GetBtPortAddresses ( + Interface, + &BtCtrlPort, + &BtComBufferPort ); + + do { + /* Wait for B_BUSY bit to clear (BMC ready to accept a request). + Default delay for each retry is 15 micro seconds.*/ + for (Retry =3D 0; Retry < BtRetryCount; Retry++) { + BtCntlData =3D IpmiBmcRead8 ( + AccessType, + BtCtrlPort ); + if (!(BtCntlData & IPMI_B_BUSY_BIT)) { + break; + } + MicroSecondDelay (IPMI_BT_DELAY_PER_RETRY); + } + + if (Retry =3D=3D BtRetryCount) { + return EFI_TIMEOUT; + } + + // Wait for H2B_ATN bit to clear (Acknowledgment of previous command= s). + for (Retry =3D 0; Retry < BtRetryCount; Retry++) { + BtCntlData =3D IpmiBmcRead8 ( + AccessType, + BtCtrlPort ); + if (!(BtCntlData & IPMI_H2B_ATN_BIT)) { + break; + } + MicroSecondDelay (IPMI_BT_DELAY_PER_RETRY); + } + + if (Retry =3D=3D BtRetryCount) { + return EFI_TIMEOUT; + } + + // Set CLR_WR_PTR. + BtCntlData =3D IPMI_CLR_WR_PTR_BIT; + IpmiBmcWrite8 ( + AccessType, + BtCtrlPort, + BtCntlData ); + + if (DataSize > Interface->Bt.HosttoBmcBufferSize ) { + TempDataSize =3D Interface->Bt.HosttoBmcBufferSize; + MultipleDataSend =3D TRUE; + } else { + TempDataSize =3D DataSize; + MultipleDataSend =3D FALSE; + } + + // Send each message byte out (write data to HOST2BMC buffer). + for (Index =3D 0; Index < TempDataSize; Index++) { + IpmiBmcWrite8 ( + AccessType, + BtComBufferPort, + *(Data + Index) ); + } + + // Set H2B_ATN bit to inform BMC that data is available. + BtCntlData =3D IPMI_H2B_ATN_BIT; + IpmiBmcWrite8 ( + AccessType, + BtCtrlPort, + BtCntlData ); + + //Command data size greater than available Input buffer size. + if (MultipleDataSend) { + Data =3D Data + TempDataSize; + DataSize -=3D TempDataSize; + + for (Retry =3D 0; Retry < BtRetryCount; Retry++) { + BtCntlData =3D IpmiBmcRead8 ( + AccessType, + BtCtrlPort ); + if ((BtCntlData & IPMI_B_BUSY_BIT)) { + break; + } + MicroSecondDelay (IPMI_BT_DELAY_PER_RETRY); + } + + if (Retry =3D=3D BtRetryCount) { + return EFI_TIMEOUT; + } + } + } while (MultipleDataSend); + + return EFI_SUCCESS; +} + +/** + Receives the Data from BT interface BMC port. + + @param[in] Interface Pointer to System interface. + @param[in] Context NULL here. + @param[out] Data Pointer to response data that is received from= BMC. + @param[out] DataSize Size of the response data. + + @retval EFI_NOT_READY Interface is not ready to receive data= . + @retval EFI_SUCCESS Data received from BMC successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + +**/ +EFI_STATUS +ReceiveBmcDataFromBtPort ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN VOID *Context, + OUT UINT8 *Data, + OUT UINT8 *DataSize + ) +{ + UINT8 BtCntlData; + UINT8 Length ; + UINT8 TempDataSize; + UINT8 Index; + UINT32 Retry; + UINTN BtCtrlPort; + UINTN BtComBufferPort; + IPMI_ACCESS_TYPE AccessType; + BOOLEAN MultipleDataReceive; + UINT32 BtRetryCount; + + Length =3D 0; + MultipleDataReceive =3D FALSE; + BtRetryCount =3D Interface->Bt.BtRetryCount; + AccessType =3D Interface->Bt.AccessType; + + // Get Bt Ports addresses. + GetBtPortAddresses ( + Interface, + &BtCtrlPort, + &BtComBufferPort ); + do { + /* Wait for B2H_ATN bit to be set,signaling data is available for ho= st. + Default delay for each retry is 15 micro seconds.*/ + for (Retry =3D 0; Retry < BtRetryCount; Retry++) { + BtCntlData =3D IpmiBmcRead8 ( + AccessType, + BtCtrlPort ); + if (BtCntlData & IPMI_B2H_ATN_BIT) { + break; + } + MicroSecondDelay (IPMI_BT_DELAY_PER_RETRY); + } + + if (Retry =3D=3D BtRetryCount) { + return EFI_TIMEOUT; + } + + // Set H_BUSY bit, indicating host is in process of reading data fro= m interface. + BtCntlData =3D IpmiBmcRead8 ( + AccessType, + BtCtrlPort ); + if (!(BtCntlData & IPMI_H_BUSY )) { + BtCntlData =3D IPMI_H_BUSY; // most bits are rw1c, so cle= ar them. + IpmiBmcWrite8 ( + AccessType, + BtCtrlPort, + BtCntlData ); + } + + // Clear B2H_ATN bit,to acknowledge receipt of message response. + BtCntlData =3D IPMI_B2H_ATN_BIT; // Most bits are rw1c, so clear= them. + IpmiBmcWrite8 ( + AccessType, + BtCtrlPort, + BtCntlData ); + + // Set CLR_RD_PTR bit. + BtCntlData =3D IPMI_CLR_RD_PTR_BIT; // Most bits are rw1c, so clear= them. + IpmiBmcWrite8 ( + AccessType, + BtCtrlPort, + BtCntlData ); + + if (!Length){ + // Read the data bytes from BMC. + Length =3D IpmiBmcRead8 ( + AccessType, + BtComBufferPort ); + if (Length =3D=3D 0x00) { + return EFI_INVALID_PARAMETER; + } + + IpmiBmcWrite8 ( + AccessType, + BtCtrlPort, + BtCntlData ); + + *DataSize =3D Length; + //Increment Length to include length field + Length++; + } + + if (Length > Interface->Bt.BmctoHostBufferSize) { + TempDataSize =3D Interface->Bt.BmctoHostBufferSize; + MultipleDataReceive =3D TRUE; + } else { + TempDataSize =3D Length; + MultipleDataReceive =3D FALSE; + } + + for (Index =3D 0; Index < TempDataSize; Index++) { + *(Data + Index) =3D IpmiBmcRead8 ( + AccessType, + BtComBufferPort ); + } + + // Clear H_BUSY bit indicating host is done reading data from BMC. + BtCntlData =3D IpmiBmcRead8 ( + AccessType, + BtCtrlPort ); + if (BtCntlData & IPMI_H_BUSY) { + BtCntlData =3D IPMI_H_BUSY; // Most bits are rw1c, so cle= ar them. + IpmiBmcWrite8 ( + AccessType, + BtCtrlPort, + BtCntlData ); + } + + if (MultipleDataReceive) { + Data =3D Data + TempDataSize; + Length -=3D TempDataSize; + } + } while (MultipleDataReceive); + + return EFI_SUCCESS; +} + +/** + BT interface send command implementation. + + @param[in] Interface Pointer to System interface. + @param[in] NetFunction Net function of the command. + @param[in] Lun Logical Unit Number of the command= . + @param[in] Command Command to be sent to BMC. + @param[in] CommandData Command data to be sent along with + Command. + @param[in] CommandDataSize Command Data size. + @param[out] ResponseData Pointer to the response data buffe= r. + @param[in, out] ResponseDataSize Pointer to the response data size. + @param[out] CompletionCode Pointer to completion code. + @param[in] InterfaceType Interface type. + @param[in] Context NULL here. + + @retval EFI_UNSUPPORTED Interface type is not supported. + @retval EFI_NOT_READY Interface is not initialized. + @retval EFI_ACCESS_DENIED Interface is locked. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_BAD_BUFFER_SIZE Invalid buffer size. + @retval EFI_DEVICE_ERROR Error completion code or data size + retrieved is small. + @retval EFI_BUFFER_TOO_SMALL Buffer is too small to update response + data. + @retval EFI_SUCCESS Command sent successfully. + @return Others Error status returned from BMC while + executing the command. + +**/ +EFI_STATUS +EFIAPI +IpmiBtSendCommandToBmc ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT8 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT8 *ResponseDataSize, + IN VOID *Context + ) +{ + + UINT8 DataSize; + EFI_STATUS Status; + UINT8 Seq; + UINT8 CmdDataBuffer[IPMI_MAX_BT_CMD_DATA_SIZE]; + IPMI_SYSTEM_INTERFACE Interface; + + Seq =3D 0; + Interface =3D This->Interface; + + if (Interface.Bt.InterfaceState !=3D IpmiInterfaceInitialized) { + return EFI_NOT_READY; + } + + if (((CommandData =3D=3D NULL) && (CommandDataSize !=3D 0)) || (This =3D= =3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + if ((ResponseDataSize =3D=3D NULL) || ((ResponseData =3D=3D NULL) && *Re= sponseDataSize)) { + return EFI_INVALID_PARAMETER; + } + + if (IpmiIsIpmiTransportlocked (&Interface.Bt.BtTransportLocked)) { + return EFI_ACCESS_DENIED; + } else { + IpmiTransportAcquireLock (&Interface.Bt.BtTransportLocked); + } + + CmdDataBuffer[0] =3D (UINT8)CommandDataSize + 0x03; + CmdDataBuffer[1] =3D (UINT8) ((NetFunction << 2) | (Lun & 0xfc)); + CmdDataBuffer[2] =3D Seq; + CmdDataBuffer[3] =3D Command; + + if (CommandDataSize > 0) { + if (CommandData =3D=3D NULL) { + IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked); + return EFI_INVALID_PARAMETER; + } + + if (CommandDataSize <=3D (IPMI_MAX_BT_CMD_DATA_SIZE - 4) ) { + CopyMem ( + &CmdDataBuffer[4], + CommandData, + CommandDataSize ); + } else { + IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked); + return EFI_BAD_BUFFER_SIZE; + } + } + + Status =3D SendDataToBtBmcPort ( + &Interface, + Context, + CmdDataBuffer, + (UINT8)(CommandDataSize + 4)); + + if (Status !=3D EFI_SUCCESS) { + Interface.Bt.BtSoftErrorCount++; + IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked); + return Status; + } + + DataSize =3D IPMI_MAX_BT_CMD_DATA_SIZE; + + Status =3D ReceiveBmcDataFromBtPort ( + &Interface, + Context, + CmdDataBuffer, + &DataSize); + + if (Status !=3D EFI_SUCCESS) { + Interface.Bt.BtSoftErrorCount++; + IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked); + return Status; + } + + if (IPMI_ERROR_COMPLETION_CODE(CmdDataBuffer[4])) { + + IpmiUpdateSoftErrorCount ( + CmdDataBuffer[4], + &Interface, + This->InterfaceType ); + + // Write completion code into return buffer if ipmi command returns= an error. + if (*ResponseDataSize) { + if (ResponseData) { + *ResponseData =3D CmdDataBuffer[4]; + } + *ResponseDataSize =3D 1; + } + IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked); + return EFI_DEVICE_ERROR; + } + + if (DataSize < 4) { + IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked); + return EFI_DEVICE_ERROR; + } + + if ((DataSize - 3) > *((UINT8 *)ResponseDataSize)) { + *ResponseDataSize =3D (UINT8) (DataSize - 3); + IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked); + return EFI_BUFFER_TOO_SMALL; + } + + // Copying the response data into ResponseData buffer. + CopyMem ( + ResponseData, + &CmdDataBuffer[4], + (DataSize - 3) ); + *ResponseDataSize =3D (UINT8) (DataSize - 3); + + IpmiTransportReleaseLock (&Interface.Bt.BtTransportLocked); + + return EFI_SUCCESS; +} + +/** + Execute the Get BT Interface Capability command and update the input + and output buffer value of Ipmi Instance. + + @param IpmiInstance Data structure pointer. + + @retval VOID +**/ + +VOID +GetBtInterfaceCapability ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ) +{ + EFI_STATUS Status; + IPMI_BT_INTERFACE_CAPABILITY_RES Responsedata; + UINT32 ResponseSize; + + ResponseSize =3D sizeof(IPMI_BT_INTERFACE_CAPABILITY_RES); + + Status =3D IpmiTransport2->IpmiSubmitCommand2 ( + IpmiTransport2, + IPMI_NETFN_APP, + BMC_LUN, + IPMI_APP_GET_BT_INTERFACE_CAPABILITY, + NULL, + 0, + (UINT8*) &Responsedata, + &ResponseSize ); + + if (EFI_ERROR(Status) || Responsedata.CompletionCode) { + DEBUG ((DEBUG_ERROR, " IPMI_APP_GET_BT_INTERFACE_CAPABILITY Status: = %r Completion code: %x\n", Status, Responsedata.CompletionCode)); + return; + } + + IpmiTransport2->Interface.Bt.HosttoBmcBufferSize =3D Responsedata.InputB= uffSize; + IpmiTransport2->Interface.Bt.BmctoHostBufferSize =3D Responsedata.Output= BuffSize; + + DEBUG ((DEBUG_ERROR, " InputBuffSize:%x OutBuffSize%x BtRetry %x Status= %r \n",IpmiTransport2->Interface.Bt.HosttoBmcBufferSize,IpmiTransport2->In= terface.Bt.BmctoHostBufferSize,Responsedata.RecommandedRetires, Status)); + + return; +} + + +/** + Initialize BT interface specific data. + + @param[in, out] Interface System interface pointer. + + @retval EFI_SUCCESS Interface is successfully initialized. + @retval Others Return status while initializing interface. + +**/ +EFI_STATUS +InitBtInterfaceData ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ) +{ + BMC_INTERFACE_STATUS BmcStatus; + EFI_STATUS Status; + + if (IpmiTransport2->Interface.Bt.InterfaceState =3D=3D IpmiInterfaceInit= ialized) { + return EFI_SUCCESS; + } + + IpmiTransport2->Interface.Bt.CtrlPort =3D FixedPcdGet16 (Pc= dBtControlPort); // BT Control Port + IpmiTransport2->Interface.Bt.ComBuffer =3D FixedPcdGet16 (Pc= dBtBufferPort); // BT Buffer Port + IpmiTransport2->Interface.Bt.IntMaskPort =3D FixedPcdGet16 (Pc= dBtInterruptMaskPort); // BT IntMask Port + IpmiTransport2->Interface.Bt.BtRetryCount =3D FixedPcdGet32 (Pc= dBtCommandRetryCounter); // BT retry count + IpmiTransport2->Interface.Bt.HosttoBmcBufferSize =3D FixedPcdGet8 (Pcd= BtBufferSize); // Host to Bmc Buffer Size. + IpmiTransport2->Interface.Bt.BmctoHostBufferSize =3D FixedPcdGet8 (Pcd= BtBufferSize); // Bmc to Host Buffer Size. + + if (FixedPcdGet8 (PcdIpmiDefaultAccessType)) { + IpmiTransport2->Interface.Bt.AccessType =3D IpmiIoAccess; + IpmiTransport2->Interface.Bt.MmioBaseAddress =3D 0; + IpmiTransport2->Interface.Bt.BaseAddressRange =3D 0; + } else { + IpmiTransport2->Interface.Bt.AccessType =3D IpmiMmioAccess; + IpmiTransport2->Interface.Bt.MmioBaseAddress =3D FixedPcdGet64(Pcd= MmioBaseAddress); + IpmiTransport2->Interface.Bt.BaseAddressRange =3D FixedPcdGet64(Pcd= BaseAddressRange); + } + + IpmiTransportReleaseLock (&IpmiTransport2->Interface.Bt.BtTransportLocke= d); + IpmiTransport2->Interface.Bt.InterfaceState =3D IpmiInterfaceInitialized= ; + + Status =3D CheckSelfTestByInterfaceType( + IpmiTransport2, + &BmcStatus, + SysInterfaceBt); + if (EFI_ERROR (Status) || (BmcStatus =3D=3D BmcStatusHardFail)) { + IpmiTransport2->Interface.Bt.InterfaceState =3D IpmiInterfaceInitErr= or; + return Status; + } + + GetBtInterfaceCapability (IpmiTransport2); + + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.inf b/Features/Intel/Out= OfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BtInterfac= eLib/BtInterfaceLib.inf new file mode 100644 index 0000000000..1dd4386204 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/BtInterfaceLib/BtInterfaceLib.inf @@ -0,0 +1,39 @@ +## @file BtInterfaceLib.inf +# +# INF description file for BtInterfaceLib common library. +# +# @copyright +# Copyright 2016 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D BtInterfaceLib + FILE_GUID =3D DAFB6AEE-0275-45E4-A33C-E3348149C5BF + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.1 + LIBRARY_CLASS =3D BtInterfaceLib + +[Sources] + BtInterfaceLib.c + +[Packages] + MdePkg/MdePkg.dec + IpmiFeaturePkg/IpmiFeaturePkg.dec + +[LibraryClasses] + TimerLib + BmcCommonInterfaceLib + +[Pcd] + gIpmiFeaturePkgTokenSpaceGuid.PcdBtCommandRetryCounter + gIpmiFeaturePkgTokenSpaceGuid.PcdBtControlPort + gIpmiFeaturePkgTokenSpaceGuid.PcdBtBufferPort + gIpmiFeaturePkgTokenSpaceGuid.PcdBtDelayPerRetry + gIpmiFeaturePkgTokenSpaceGuid.PcdBtInterruptMaskPort + gIpmiFeaturePkgTokenSpaceGuid.PcdBtBufferSize + gIpmiFeaturePkgTokenSpaceGuid.PcdBaseAddressRange + gIpmiFeaturePkgTokenSpaceGuid.PcdMmioBaseAddress + gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiDefaultAccessType diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.c b/Features/Inte= l/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbI= nterfaceLib/DxeIpmbInterfaceLib.c new file mode 100644 index 0000000000..c0d5ff02c8 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.c @@ -0,0 +1,94 @@ +/** @file DxeIpmbInterfaceLib.c + IPMB Transport Dxe phase Implementation library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include + +/** @internal + Send Ipmi command through Ipmb interface. + + @param[in] Interface Pointer to System interface. + @param[in] SlaveAddress I2C device slave address. + @param[in] RequestPacket Pointer to an EFI_I2C_REQUEST_PACKET + structure describing the I2C transaction. + + @return EFI_STATUS Status of the Send I2c command. + +**/ +EFI_STATUS +IpmiI2cSendCommand ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN UINTN SlaveAddress, + IN EFI_I2C_REQUEST_PACKET *RequestPacket + ) +{ + EFI_STATUS Status =3D EFI_NOT_FOUND; + EFI_I2C_MASTER_PROTOCOL *I2cMasterTransmit =3D NULL; + + I2cMasterTransmit =3D (EFI_I2C_MASTER_PROTOCOL *)Interface->Ipmb.IpmbInt= erfaceApiPtr; + + if (I2cMasterTransmit !=3D NULL) { + Status =3D I2cMasterTransmit->StartRequest ( + I2cMasterTransmit, + SlaveAddress, + RequestPacket, + NULL, + NULL ); + } + + DEBUG ((DEBUG_INFO, "I2cMasterTransmit->StartRequest Status =3D %r\n", S= tatus)); + return Status; +} + +/** @internal + Locate I2c Ppi/Protocol instance and initialize interface pointer. + + @param[in, out] Interface System interface pointer. + + @return EFI_STATUS Status returned from functions used. + +**/ +EFI_STATUS +IpmiGetI2cApiPtr ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ) +{ + EFI_STATUS Status; + EFI_I2C_MASTER_PROTOCOL *I2cMasterTransmit =3D NULL; + BMC_INTERFACE_STATUS BmcStatus; + + IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiGuid =3D gEfiI2cMasterPro= tocolGuid; + + // Locate the I2C DXE Protocol for Communication. + Status =3D gBS->LocateProtocol ( + &gEfiI2cMasterProtocolGuid, + NULL, + (VOID **)&I2cMasterTransmit ); + + if (EFI_ERROR (Status)) { + return Status; + } + + IpmiTransport2->Interface.Ipmb.InterfaceState =3D IpmiInterfaceInitializ= ed; + IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiPtr =3D (UINTN)I2cMasterT= ransmit; + + Status =3D CheckSelfTestByInterfaceType( + IpmiTransport2, + &BmcStatus, + SysInterfaceIpmb); + if (EFI_ERROR (Status) || (BmcStatus =3D=3D BmcStatusHardFail)) { + IpmiTransport2->Interface.Ipmb.InterfaceState =3D IpmiInterfaceInitE= rror; + } + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.inf b/Features/In= tel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Ipm= bInterfaceLib/DxeIpmbInterfaceLib.inf new file mode 100644 index 0000000000..641d7213d4 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.inf @@ -0,0 +1,38 @@ +## @file DxeIpmbInterfaceLib.inf +# +# INF description file for IpmbInterfaceLib Library for DXE and UEFI driv= ers. +# +# @copyright +# Copyright 2016 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D DxeIpmbInterfaceLib + FILE_GUID =3D 9068B213-4E53-427E-863C-8C7423509035 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.1 + LIBRARY_CLASS =3D IpmbInterfaceLib | DXE_DRIVER DXE_RUNTIME_DRIVER U= EFI_DRIVER UEFI_APPLICATION + +[Sources] + DxeIpmbInterfaceLib.c + IpmbInterfaceLibCommon.c + +[Packages] + MdePkg/MdePkg.dec + IpmiFeaturePkg/IpmiFeaturePkg.dec + +[LibraryClasses] + DebugLib + BaseMemoryLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + BmcCommonInterfaceLib + +[Protocols] + gEfiI2cMasterProtocolGuid + +[Pcd] + gIpmiFeaturePkgTokenSpaceGuid.PcdBmcSlaveAddress diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/IpmbInterfaceLib/IpmbInterfaceLibCommon.c b/Features/I= ntel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Ip= mbInterfaceLib/IpmbInterfaceLibCommon.c new file mode 100644 index 0000000000..fd0be85aa5 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/IpmbInterfaceLib/IpmbInterfaceLibCommon.c @@ -0,0 +1,351 @@ +/** @file IpmbInterfaceLibCommon.c + IPMB Transport implementation common library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include + +#define IPMI_BMC_SLAVE_ADDRESS FixedPcdGet32 (PcdBmcSlaveAddress) +/** @internal + Verify the data integrity using checksum of BMC response data. + + @param[in] ResponseData Response data from BMC. + @param[in] ResponseSize Data size of response data. + + @retval EFI_SUCCESS Data integrity is valid. + @retval EFI_INVALID_PARAMETER Invalid parameter. + +**/ +EFI_STATUS +CheckDataValidity ( + IN UINT8 *ResponseData, + IN UINT8 ResponseSize ) +{ + UINT8 Index; + UINT8 CheckSum =3D 0; + UINT8 DataSum =3D 0; + + // Calculate header checksum. + for (Index =3D 0; Index < 2; Index++) { + DataSum +=3D ResponseData[Index]; + } + + // Verify header checksum. + CheckSum =3D (UINT8) (0x100 - DataSum); + if (CheckSum !=3D ResponseData[2]) { + return EFI_INVALID_PARAMETER; + } + + DataSum =3D 0; + + // Calculate information checksum. + for (Index =3D 3; Index < (ResponseSize - 1); Index++) { + DataSum +=3D ResponseData[Index]; + } + + // Verify information checksum. + CheckSum =3D (UINT8) (0x100 - DataSum); + if (CheckSum !=3D ResponseData[ResponseSize - 1]) { + return EFI_INVALID_PARAMETER; + } + return EFI_SUCCESS; +} + +/** @internal + Sends the command/data to Ipmb interface. + + @param[in] Interface Pointer to System interface. + @param[in] Context NULL here. + @param[in] Data Pointer to command data that will be sent to B= MC + along with Command. + @param[in] DataSize Size of the command data. + + @return EFI_STATUS Status returned from I2C send command. + +**/ +EFI_STATUS +SendDataToIpmbBmcPort ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN VOID *Context, + IN UINT8 *Data, + IN UINT8 DataSize ) +{ + EFI_STATUS Status; + EFI_I2C_REQUEST_PACKET Packet; + + // Pack command data. + Packet.Operation[0].Buffer =3D Data; + Packet.Operation[0].LengthInBytes =3D DataSize; + Packet.Operation[0].Flags =3D IPMI_WRITE_FLAG; + + // Call the StartRequest function. + Status =3D IpmiI2cSendCommand ( + Interface, + IPMI_BMC_SLAVE_ADDRESS, + &Packet ); + + return Status; +} + +/** @internal + Receives the data from Ipmb interface. + + @param[in] Interface Pointer to System interface. + @param[in] Context NULL here. + @param[out] Data Pointer to response data that is received from= BMC. + @param[out] DataSize Size of the response data. + + @return EFI_STATUS Status returned from I2C send command. + +**/ +EFI_STATUS +ReceiveBmcDataFromIpmbPort ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN VOID *Context, + OUT UINT8 *Data, + OUT UINT8 *DataSize ) +{ + EFI_STATUS Status; + EFI_I2C_REQUEST_PACKET Packet; + + // Pack command data. + Packet.Operation[0].Buffer =3D Data; + Packet.Operation[0].Flags =3D IPMI_READ_FLAG; + + // Call the StartRequest function. + Status =3D IpmiI2cSendCommand ( + Interface, + IPMI_BMC_SLAVE_ADDRESS, + &Packet ); + + if (!EFI_ERROR(Status)) { + *DataSize =3D (UINT8)Packet.Operation[0].LengthInBytes; + } + return Status; +} + +/** @internal + IPMB interface send command implementation. + + @param[in] Interface Pointer to System interface. + @param[in] NetFunction Net function of the command. + @param[in] Lun Logical Unit Number of the command= . + @param[in] Command Command to be sent to BMC. + @param[in] CommandData Command data to be sent along with + Command. + @param[in] CommandDataSize Command Data size. + @param[out] ResponseData Pointer to the response data buffe= r. + @param[in, out] ResponseDataSize Pointer to the response data size. + @param[out] CompletionCode Pointer to completion code. + @param[in] InterfaceType Interface type. + @param[in] Context NULL here. + + @retval EFI_UNSUPPORTED Interface type is not supported. + @retval EFI_NOT_READY Interface is not initialized. + @retval EFI_ACCESS_DENIED Interface is locked. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_BAD_BUFFER_SIZE Invalid buffer size. + @retval EFI_DEVICE_ERROR Error completion code or data size + retrieved is small. + @retval EFI_BUFFER_TOO_SMALL Buffer is too small to update response + data. + @retval EFI_SUCCESS Command sent successfully. + @return Others Error status returned from BMC while + executing the command. + +**/ +EFI_STATUS +IpmiIpmbSendCommandToBmc ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT8 CommandDataSize, + OUT UINT8 *ResponseData, + IN OUT UINT8 *ResponseDataSize, + IN VOID *Context ) +{ + EFI_STATUS Status; + UINT8 DataSize; + UINT8 DataSum =3D 0; + UINT8 CheckSum =3D 0; + UINT8 Index; + UINT8 CmdDataBuffer[IPMI_MAX_IPMB_CMD_DATA_SIZE]; + IPMI_SYSTEM_INTERFACE Interface; + + Interface =3D This->Interface; + + if (Interface.Ipmb.InterfaceState !=3D IpmiInterfaceInitialized) { + return EFI_NOT_READY; + } + + if (!ResponseDataSize || (!ResponseData && *ResponseDataSize)) { + return EFI_INVALID_PARAMETER; + } + + if (IpmiIsIpmiTransportlocked (&Interface.Ipmb.IpmbTransportLocked)) { + return EFI_ACCESS_DENIED; + } else { + IpmiTransportAcquireLock (&Interface.Ipmb.IpmbTransportLocked); + } + + if (Interface.Ipmb.IpmbSoftErrorCount >=3D MAX_BMC_CMD_FAIL_COUNT) { + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return EFI_NOT_READY; + } + + /* Request Packet format. + | Slave Address | Netfun/Lun | CheckSum (Check Sum of previous data) + | Slave Address | Seq No | Command | Data 1..N + | CheckSum (Check Sum of previous data).*/ + CmdDataBuffer[0] =3D IPMI_BMC_SLAVE_ADDRESS; + CmdDataBuffer[1] =3D (UINT8) ((NetFunction << 2) | (Lun & 0x03)); + + DataSum +=3D CmdDataBuffer[1] + IPMI_BMC_SLAVE_ADDRESS; + CheckSum =3D (UINT8) (0x100 - DataSum); + DataSum =3D 0; + + CmdDataBuffer[2] =3D CheckSum; + + CmdDataBuffer[3] =3D IPMI_BMC_SLAVE_ADDRESS; + DataSum +=3D IPMI_BMC_SLAVE_ADDRESS; + + CmdDataBuffer[4] =3D IPMI_SEQ_NO; + DataSum +=3D IPMI_SEQ_NO; + + CmdDataBuffer[5] =3D Command; + DataSum +=3D Command; + + if (CommandDataSize > 0) { + if (CommandData =3D=3D NULL) { + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return EFI_INVALID_PARAMETER; + } + //Last data will be Checksum so limiting the Max command data to < I= PMI_MAX_IPMB_CMD_DATA_SIZE - 6 + if (CommandDataSize < (IPMI_MAX_IPMB_CMD_DATA_SIZE - 6)) { + CopyMem ( + &CmdDataBuffer[6], + CommandData, + CommandDataSize ); + } else { + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return EFI_BAD_BUFFER_SIZE; + } + for(Index =3D 0; Index < CommandDataSize; Index++) { + DataSum +=3D CmdDataBuffer[6 + Index]; + } + } + CheckSum =3D (UINT8) (0x100 - DataSum); // Find the checksum for the pa= cking data. + CmdDataBuffer[6] =3D CheckSum; // Update the checksum. + + if ((Status =3D SendDataToIpmbBmcPort ( + &Interface, + Context, + CmdDataBuffer, + (UINT8) (CommandDataSize + 7) ) ) !=3D EFI_SUCCESS) { + Interface.Ipmb.IpmbSoftErrorCount++; + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return Status; + } + + DataSize =3D IPMI_MAX_IPMB_CMD_DATA_SIZE; + if ((Status =3D ReceiveBmcDataFromIpmbPort ( + &Interface, + Context, + CmdDataBuffer, + &DataSize )) !=3D EFI_SUCCESS) { + Interface.Ipmb.IpmbSoftErrorCount++; + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return Status; + } + + /* Response Packet format. + | Slave Address | Netfun/Lun | CheckSum (Check Sum of previous data) + | Slave Address | Seq No | Command | Completion code| Data 1..N + | CheckSum (Check Sum of previous data).*/ + + // Calculate and verify checksum. + Status =3D CheckDataValidity ( + CmdDataBuffer, + DataSize ); + if (EFI_ERROR(Status)) { + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return Status; + } + + if (IPMI_ERROR_COMPLETION_CODE(CmdDataBuffer[6])) { + IpmiUpdateSoftErrorCount ( + CmdDataBuffer[6], + &Interface, + This->InterfaceType ); + // Write completion code into return buffer if an IPMI command retur= ns an error + if (*ResponseDataSize) { + if (ResponseData) { + *ResponseData =3D CmdDataBuffer[6]; + } + *ResponseDataSize =3D 1; + } + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return EFI_DEVICE_ERROR; + } + + if (DataSize < 8) { + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return EFI_DEVICE_ERROR; + } + if ((DataSize - 7) > *((UINT8 *)ResponseDataSize)) { + *ResponseDataSize =3D (UINT8) (DataSize - 7); + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return EFI_BUFFER_TOO_SMALL; + } + + // Copying the response data into ResponseData buffer. + CopyMem ( + ResponseData, + &CmdDataBuffer[6], + (DataSize - 7) ); + *ResponseDataSize =3D (UINT8) (DataSize - 7); + + IpmiTransportReleaseLock (&Interface.Ipmb.IpmbTransportLocked); + return EFI_SUCCESS; +} + +/** @internal + Initialize IPMB interface specific data. + + @param[in, out] Interface System interface pointer. + + @retval EFI_SUCCESS Interface is successfully initialized. + @retval Others Error status while initializing interface. + +**/ +EFI_STATUS +InitIpmbInterfaceData ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ) +{ + EFI_STATUS Status =3D EFI_SUCCESS; + + if (IpmiTransport2->Interface.Ipmb.InterfaceState =3D=3D IpmiInterfaceIn= itialized) { + return Status; + } + + Status =3D IpmiGetI2cApiPtr (IpmiTransport2); + + if (EFI_ERROR(Status)) { + IpmiTransport2->Interface.Ipmb.InterfaceState =3D IpmiInterfaceInitE= rror; + return Status; + } + + IpmiTransportReleaseLock (&IpmiTransport2->Interface.Ipmb.IpmbTransportL= ocked); + IpmiTransport2->Interface.Ipmb.InterfaceState =3D IpmiInterfaceInitializ= ed; + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.c b/Features/Inte= l/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbI= nterfaceLib/PeiIpmbInterfaceLib.c new file mode 100644 index 0000000000..e4db0b4b13 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.c @@ -0,0 +1,100 @@ +/** @file PeiIpmbInterfaceLib.c + IPMB Transport Pei phase implementation library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include + +/** @internal + Send Ipmi command through Ipmb interface. + + @param[in] Interface Pointer to System interface. + @param[in] SlaveAddress I2C device slave address. + @param[in] RequestPacket Pointer to an EFI_I2C_REQUEST_PACKET + structure describing the I2C transaction. + + @return EFI_STATUS Status of the Send I2c command. + +**/ +EFI_STATUS +IpmiI2cSendCommand ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN UINTN SlaveAddress, + IN EFI_I2C_REQUEST_PACKET *RequestPacket ) [Isaac] Put ) on a new line +{ + EFI_STATUS Status =3D EFI_NOT_FOUND; + EFI_PEI_I2C_MASTER_PPI *I2cMasterTransmit =3D NULL; + + I2cMasterTransmit =3D (EFI_PEI_I2C_MASTER_PPI *)Interface->Ipmb.IpmbIn= terfaceApiPtr; + + if (I2cMasterTransmit !=3D NULL) { + Status =3D I2cMasterTransmit->StartRequest ( + I2cMasterTransmit, + SlaveAddress, + RequestPacket ); + } + + DEBUG ((DEBUG_INFO, "%a I2cMasterTransmit->StartRequest Status =3D %r\= n", __FUNCTION__, Status)); + + return Status; +} + +/** @internal + Locate I2c Ppi/Protocol instance and initialize interface pointer. + + @param[in, out] Interface System interface pointer. + + @return EFI_STATUS Status returned from functions used. + +**/ +EFI_STATUS +IpmiGetI2cApiPtr ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 +) +{ + EFI_STATUS Status; + CONST EFI_PEI_SERVICES **PeiServices; + EFI_PEI_I2C_MASTER_PPI *I2cMasterTransmit =3D NULL; + BMC_INTERFACE_STATUS BmcStatus; + + PeiServices =3D GetPeiServicesTablePointer (); + + IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiGuid =3D gEfiPeiI2cMaster= PpiGuid; + + // Locate the I2C PPI for Communication. + Status =3D (*PeiServices)->LocatePpi ( + PeiServices, + &gEfiPeiI2cMasterPpiGuid, + 0, + NULL, + (VOID **)&I2cMasterTransmit ); + + DEBUG ((DEBUG_INFO, "%a (*PeiServices)->LocatePpi gEfiPeiI2cMasterPpiGui= d Status =3D %r\n", __FUNCTION__, Status)); + + if (EFI_ERROR (Status)) { + return Status; + } + + IpmiTransport2->Interface.Ipmb.InterfaceState =3D IpmiInterfaceInitializ= ed; + IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiPtr =3D (UINTN)I2cMasterT= ransmit; + + Status =3D CheckSelfTestByInterfaceType( + IpmiTransport2, + &BmcStatus, + SysInterfaceIpmb); + + if (EFI_ERROR (Status) || (BmcStatus =3D=3D BmcStatusHardFail)) { + IpmiTransport2->Interface.Ipmb.InterfaceState =3D IpmiInterfaceInitE= rror; + } + + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.inf b/Features/In= tel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Ipm= bInterfaceLib/PeiIpmbInterfaceLib.inf new file mode 100644 index 0000000000..85b19d74c8 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/IpmbInterfaceLib/PeiIpmbInterfaceLib.inf @@ -0,0 +1,38 @@ +## @file PeiIpmbInterfaceLib.inf +# +# INF description file for IpmbInterfacePeiLib Library for PEIMs. +# +# @copyright +# Copyright 2016 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PeiIpmbInterfaceLib + FILE_GUID =3D 843DBE4E-4750-4335-9094-58645D897D62 + MODULE_TYPE =3D PEIM + VERSION_STRING =3D 1.1 + LIBRARY_CLASS =3D IpmbInterfaceLib | PEIM + +[Sources] + PeiIpmbInterfaceLib.c + IpmbInterfaceLibCommon.c + +[Packages] + MdePkg/MdePkg.dec + IpmiFeaturePkg/IpmiFeaturePkg.dec + +[LibraryClasses] + HobLib + DebugLib + BaseMemoryLib + PeiServicesTablePointerLib + BmcCommonInterfaceLib + +[Ppis] + gEfiPeiI2cMasterPpiGuid + +[Pcd] + gIpmiFeaturePkgTokenSpaceGuid.PcdBmcSlaveAddress diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.c b/Features/Inte= l/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbI= nterfaceLib/SmmIpmbInterfaceLib.c new file mode 100644 index 0000000000..2293e3154a --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.c @@ -0,0 +1,94 @@ +/** @file SmmIpmbInterfaceLib.c + IPMB Transport Smm phase implementation library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include + +/** @internal + Send Ipmi command through Ipmb interface. + + @param[in] Interface Pointer to System interface. + @param[in] SlaveAddress I2C device slave address. + @param[in] RequestPacket Pointer to an EFI_I2C_REQUEST_PACKET + structure describing the I2C transaction. + + @return EFI_STATUS Status of the Send I2c command. + +**/ +EFI_STATUS +IpmiI2cSendCommand ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN UINTN SlaveAddress, + IN EFI_I2C_REQUEST_PACKET *RequestPacket ) [Isaac] Put ) on a new line +{ + EFI_STATUS Status =3D EFI_NOT_FOUND; + EFI_I2C_MASTER_PROTOCOL *I2cMasterTransmit =3D NULL; + + I2cMasterTransmit =3D (EFI_I2C_MASTER_PROTOCOL *)Interface->Ipmb.IpmbI= nterfaceApiPtr; + + if (I2cMasterTransmit !=3D NULL) { + Status =3D I2cMasterTransmit->StartRequest ( + I2cMasterTransmit, + SlaveAddress, + RequestPacket, + NULL, + NULL ); + } + + DEBUG ((DEBUG_INFO, "%a I2cMasterTransmit->StartRequest Status =3D %r\= n", __FUNCTION__, Status)); + + return Status; +} + +/** @internal + Locate I2c Ppi/Protocol instance and initialize interface pointer. + + @param[in, out] Interface System interface pointer. + + @return EFI_STATUS Status returned from functions used. + +**/ +EFI_STATUS +IpmiGetI2cApiPtr ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 +) +{ + EFI_STATUS Status; + EFI_I2C_MASTER_PROTOCOL *I2cMasterTransmit =3D NULL; + BMC_INTERFACE_STATUS BmcStatus; + + IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiGuid =3D gEfiI2cMasterP= rotocolGuid; + + // Locate the I2C SMM Protocol for Communication. + Status =3D gSmst->SmmLocateProtocol ( + &gEfiI2cMasterProtocolGuid, + NULL, + (VOID **)&I2cMasterTransmit ); + + DEBUG ((DEBUG_INFO, "%a SmmLocateProtocol gEfiI2cMasterProtocolGuid St= atus =3D %r\n", __FUNCTION__, Status)); + + if (EFI_ERROR(Status)) { + return Status; + } + + IpmiTransport2->Interface.Ipmb.InterfaceState =3D IpmiInterfaceInitial= ized; + IpmiTransport2->Interface.Ipmb.IpmbInterfaceApiPtr =3D (UINTN)I2cMaste= rTransmit; + + Status =3D CheckSelfTestByInterfaceType( + IpmiTransport2, + &BmcStatus, + SysInterfaceIpmb); + if (EFI_ERROR (Status) || (BmcStatus =3D=3D BmcStatusHardFail)) { + IpmiTransport2->Interface.Ipmb.InterfaceState =3D IpmiInterfaceIni= tError; + } + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.inf b/Features/In= tel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Ipm= bInterfaceLib/SmmIpmbInterfaceLib.inf new file mode 100644 index 0000000000..2d3c089ef2 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.inf @@ -0,0 +1,37 @@ +## @file SmmAmiIpmbInterfaceLib.inf +# +# INF description file for SmmAmiIpmbInterfaceLib Library for DXE SMM dri= vers. +# +# @copyright +# Copyright 2016 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SmmIpmbInterfaceLib + FILE_GUID =3D C39F9DC3-37C7-41C1-BE05-8C1524493947 + MODULE_TYPE =3D DXE_SMM_DRIVER + VERSION_STRING =3D 1.1 + LIBRARY_CLASS =3D IpmbInterfaceLib | DXE_SMM_DRIVER + +[Sources] + SmmIpmbInterfaceLib.c + IpmbInterfaceLibCommon.c + +[Packages] + MdePkg/MdePkg.dec + IpmiFeaturePkg/IpmiFeaturePkg.dec + +[LibraryClasses] + DebugLib + BaseMemoryLib + SmmServicesTableLib + BmcCommonInterfaceLib + +[Protocols] + gEfiI2cMasterProtocolGuid + +[Pcd] + gIpmiFeaturePkgTokenSpaceGuid.PcdBmcSlaveAddress diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.c b/Features/Inte= l/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifI= nterfaceLib/DxeSsifInterfaceLib.c new file mode 100644 index 0000000000..60b2b8e016 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.c @@ -0,0 +1,131 @@ +/** @file DxeSsifInterfaceLib.c + SSIF Transport Dxe phase Implementation library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Send Ipmi command through Smbus instance. + + @param[in] Interface Pointer to System interface. + @param[in] SlaveAddress The SMBUS hardware address. + @param[in] Command This command is transmitted by the SMB= us + host controller to the SMBus slave dev= ice. + @param[in] Operation Operation to be performed. + @param[in] PecCheck Defines if Packet Error Code (PEC) + checking is required for this operatio= n. + @param[in, out] Length Signifies the number of bytes that thi= s + operation will do. + @param[in, out] Buffer Contains the value of data to execute = to + the SMBus slave device. The length of + this buffer is identified by Length. + + @retval EFI_NOT_FOUND Smbus instance is not found. + @retval Others Return status of the Smbus Execute operation. + +**/ +EFI_STATUS +IpmiSmbusSendCommand ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + EFI_SMBUS_HC_PROTOCOL *EfiSmbusHcProtocol; + + Status =3D EFI_NOT_FOUND; + EfiSmbusHcProtocol =3D (EFI_SMBUS_HC_PROTOCOL *)Interface->Ssif.SsifInte= rfaceApiPtr; + + if (EfiSmbusHcProtocol !=3D NULL) { + Status =3D EfiSmbusHcProtocol->Execute ( + EfiSmbusHcProtocol, + SlaveAddress, + Command, + Operation, + PecCheck, + Length, + Buffer ); + } + + DEBUG ((DEBUG_INFO, "EfiSmbusHcProtocol->Execute Status =3D %r\n", Statu= s)); + return Status; +} + +/** + Locate Smbus instance and initialize interface pointer. + + @param[in, out] Interface System interface pointer. + + @return EFI_STATUS Status returned while locating smbus instance. + +**/ +EFI_STATUS +IpmiGetSmbusApiPtr ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ) +{ + EFI_STATUS Status; + EFI_SMBUS_HC_PROTOCOL *EfiSmbusHcProtocol; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + UINTN Index; + BMC_INTERFACE_STATUS BmcStatus; + + IpmiTransport2->Interface.Ssif.SsifInterfaceApiGuid =3D gEfiSmbusHcProto= colGuid; + + Status =3D gBS->LocateHandleBuffer( + ByProtocol, + &gEfiSmbusHcProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + for (Index =3D 0; Index < HandleCount; Index++) { + Status =3D gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiSmbusHcProtocolGuid, + (VOID **)&EfiSmbusHcProtocol ); + if (EFI_ERROR (Status)) { + continue; + } + + IpmiTransport2->Interface.Ssif.InterfaceState =3D IpmiInterfaceInit= ialized; + IpmiTransport2->Interface.Ssif.SsifInterfaceApiPtr =3D (UINTN)EfiSm= busHcProtocol; + + Status =3D CheckSelfTestByInterfaceType( + IpmiTransport2, + &BmcStatus, + SysInterfaceSsif); + if (EFI_ERROR (Status) || (BmcStatus =3D=3D BmcStatusHardFail)) { + IpmiTransport2->Interface.Ssif.InterfaceState =3D IpmiInterface= InitError; + continue; + } + + GetSystemInterfaceCapability (IpmiTransport2); + GetGlobalEnables (IpmiTransport2); + break; + } + + FreePool(HandleBuffer); + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.inf b/Features/In= tel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Ssi= fInterfaceLib/DxeSsifInterfaceLib.inf new file mode 100644 index 0000000000..d9120b220c --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.inf @@ -0,0 +1,40 @@ +## @file DxeSsifInterfaceLib.inf +# +# INF description file for SsifInterfaceLib Library for DXE and UEFI driv= ers. +# +# @copyright +# Copyright 2016 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D DxeSsifInterfaceLib + FILE_GUID =3D AD66E7C3-FE13-4849-970E-118347FFE857 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.1 + LIBRARY_CLASS =3D SsifInterfaceLib | DXE_DRIVER DXE_RUNTIME_DRIVER U= EFI_DRIVER UEFI_APPLICATION + +[Sources] + DxeSsifInterfaceLib.c + SsifInterfaceLibCommon.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IpmiFeaturePkg/IpmiFeaturePkg.dec + +[LibraryClasses] + UefiLib + MemoryAllocationLib + BmcCommonInterfaceLib + +[Protocols] + gEfiSmbusHcProtocolGuid + +[Pcd] + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifSlaveAddress + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifCommandtRetryCounter + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.c b/Features/Inte= l/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifI= nterfaceLib/PeiSsifInterfaceLib.c new file mode 100644 index 0000000000..0cb7e4afd1 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.c @@ -0,0 +1,123 @@ +/** @file PeiSsifInterfaceLib.c + SSIF Transport Pei phase Implementation library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include + +/** + Send Ipmi command through Smbus instance. + + @param[in] Interface Pointer to System interface. + @param[in] SlaveAddress The SMBUS hardware address. + @param[in] Command This command is transmitted by the SMB= us + host controller to the SMBus slave dev= ice. + @param[in] Operation Operation to be performed. + @param[in] PecCheck Defines if Packet Error Code (PEC) + checking is required for this operatio= n. + @param[in, out] Length Signifies the number of bytes that thi= s + operation will do. + @param[in, out] Buffer Contains the value of data to execute = to + the SMBus slave device. The length of + this buffer is identified by Length. + + @retval EFI_NOT_FOUND Smbus instance is not found. + @retval Others Return status of the Smbus Execute operation. + +**/ +EFI_STATUS +IpmiSmbusSendCommand ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + EFI_PEI_SMBUS2_PPI *EfiPeiSmbus2Ppi; + + Status =3D EFI_NOT_FOUND; + EfiPeiSmbus2Ppi =3D (EFI_PEI_SMBUS2_PPI *)Interface->Ssif.SsifInterfaceA= piPtr; + + if (EfiPeiSmbus2Ppi !=3D NULL) { + Status =3D EfiPeiSmbus2Ppi->Execute ( + EfiPeiSmbus2Ppi, + SlaveAddress, + Command, + Operation, + PecCheck, + Length, + Buffer ); + } + + DEBUG ((DEBUG_INFO, "%a EfiPeiSmbus2Ppi->Execute Status =3D %r\n", __FUN= CTION__, Status)); + return Status; +} + +/** + Locate Smbus instance and initialize interface pointer. + + @param[in, out] Interface System interface pointer. + + @return EFI_STATUS Status returned while locating smbus instance. + +**/ +EFI_STATUS +IpmiGetSmbusApiPtr ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 +) +{ + EFI_STATUS Status; + UINTN Instance; + CONST EFI_PEI_SERVICES **PeiServices; + EFI_PEI_SMBUS2_PPI *EfiPeiSmbus2Ppi; + BMC_INTERFACE_STATUS BmcStatus; + + PeiServices =3D GetPeiServicesTablePointer (); + + IpmiTransport2->Interface.Ssif.SsifInterfaceApiGuid =3D gEfiPeiSmbus2Pp= iGuid; + + // Traverse all Smbus2 PPI instances and find the right instance for SSI= F. + for (Instance =3D 0; ; Instance++) { + // Locate the Smbus Ppi. + Status =3D (*PeiServices)->LocatePpi ( + PeiServices, + &gEfiPeiSmbus2PpiGuid, + Instance, + NULL, + (VOID **)&EfiPeiSmbus2Ppi ); + if (EFI_ERROR (Status)) { + break; + } + + IpmiTransport2->Interface.Ssif.InterfaceState =3D IpmiInterfaceInit= ialized; + IpmiTransport2->Interface.Ssif.SsifInterfaceApiPtr =3D (UINTN)EfiPe= iSmbus2Ppi; + + Status =3D CheckSelfTestByInterfaceType( + IpmiTransport2, + &BmcStatus, + SysInterfaceSsif); + if (EFI_ERROR (Status) || (BmcStatus =3D=3D BmcStatusHardFail)) { + IpmiTransport2->Interface.Ssif.InterfaceState =3D IpmiInterface= InitError; + continue; + } + + GetSystemInterfaceCapability (IpmiTransport2); + GetGlobalEnables (IpmiTransport2); + break; + } + + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.inf b/Features/In= tel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Ssi= fInterfaceLib/PeiSsifInterfaceLib.inf new file mode 100644 index 0000000000..b3aad43671 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/PeiSsifInterfaceLib.inf @@ -0,0 +1,41 @@ +## @file PeiSsifInterfaceLib.inf +# +# INF description file for SsifInterfaceLib Library for PEIMs. +# +# @copyright +# Copyright 2016 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PeiSsifInterfaceLib + FILE_GUID =3D EDA631E3-DC66-4120-BADF-B6BA73B6ABD4 + MODULE_TYPE =3D PEIM + VERSION_STRING =3D 1.1 + LIBRARY_CLASS =3D SsifInterfaceLib | PEIM + +[Sources] + PeiSsifInterfaceLib.c + SsifInterfaceLibCommon.c + +[Packages] + MdePkg/MdePkg.dec + IpmiFeaturePkg/IpmiFeaturePkg.dec + +[LibraryClasses] + DebugLib + TimerLib + BaseMemoryLib + PeiServicesTablePointerLib + BmcCommonInterfaceLib + +[Ppis] + gEfiPeiSmbus2PpiGuid + +[Pcd] + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifSlaveAddress + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifCommandtRetryCounter + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.c b/Features/Inte= l/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifI= nterfaceLib/SmmSsifInterfaceLib.c new file mode 100644 index 0000000000..4fb4a889ed --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.c @@ -0,0 +1,148 @@ +/** @file SmmSsifInterfaceLib.c + SSIF Transport SMM phase Implementation library functions. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Send Ipmi command through Smbus instance. + + @param[in] Interface Pointer to System interface. + @param[in] SlaveAddress The SMBUS hardware address. + @param[in] Command This command is transmitted by the SMB= us + host controller to the SMBus slave dev= ice. + @param[in] Operation Operation to be performed. + @param[in] PecCheck Defines if Packet Error Code (PEC) + checking is required for this operatio= n. + @param[in, out] Length Signifies the number of bytes that thi= s + operation will do. + @param[in, out] Buffer Contains the value of data to execute = to + the SMBus slave device. The length of + this buffer is identified by Length. + + @retval EFI_NOT_FOUND Smbus instance is not found. + @retval Others Return status of the Smbus Execute operation. + +**/ +EFI_STATUS +IpmiSmbusSendCommand ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + EFI_SMBUS_HC_PROTOCOL *EfiSmbusHcProtocol; + + Status =3D EFI_NOT_FOUND; + EfiSmbusHcProtocol =3D (EFI_SMBUS_HC_PROTOCOL *)Interface->Ssif.SsifInte= rfaceApiPtr; + + if (EfiSmbusHcProtocol !=3D NULL) { + Status =3D EfiSmbusHcProtocol->Execute ( + EfiSmbusHcProtocol, + SlaveAddress, + Command, + Operation, + PecCheck, + Length, + Buffer ); + } + + DEBUG ((DEBUG_INFO, "%a EfiSmbusHcProtocol->Execute Status =3D %r\n", __= FUNCTION__, Status)); + + return Status; +} + +/** + Locate Smbus instance and initialize interface pointer. + + @param[in, out] Interface System interface pointer. + + @return EFI_STATUS Status returned while locating smbus instance. + +**/ +EFI_STATUS +IpmiGetSmbusApiPtr ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 +) +{ + EFI_STATUS Status; + EFI_SMBUS_HC_PROTOCOL *EfiSmbusHcProtocol; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer =3D NULL; + UINTN Index; + BMC_INTERFACE_STATUS BmcStatus; + + IpmiTransport2->Interface.Ssif.SsifInterfaceApiGuid =3D gEfiSmbusHcProto= colGuid; + HandleCount =3D 0; + + Status =3D gSmst->SmmLocateHandle ( + ByProtocol, + &gEfiSmbusHcProtocolGuid, + NULL, + &HandleCount, + HandleBuffer ); + if (EFI_ERROR (Status) && Status =3D=3D EFI_BUFFER_TOO_SMALL) { + // Allocate memory for Handle buffer + HandleBuffer =3D AllocateZeroPool (HandleCount); + if (HandleBuffer =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + Status =3D gSmst->SmmLocateHandle ( + ByProtocol, + &gEfiSmbusHcProtocolGuid, + NULL, + &HandleCount, + HandleBuffer ); + if (EFI_ERROR (Status)) { + // Free HandleBuffer memory + FreePool(HandleBuffer); + return EFI_NOT_FOUND; + } + } + + for (Index =3D 0; Index < HandleCount; Index++) { + Status =3D gSmst->SmmHandleProtocol ( + HandleBuffer[Index], + &gEfiSmbusHcProtocolGuid, + (VOID **)&EfiSmbusHcProtocol ); + if (EFI_ERROR (Status)) { + continue; + } + IpmiTransport2->Interface.Ssif.InterfaceState =3D IpmiInterfaceInit= ialized; + IpmiTransport2->Interface.Ssif.SsifInterfaceApiPtr =3D (UINTN)EfiSm= busHcProtocol; + + Status =3D CheckSelfTestByInterfaceType( + IpmiTransport2, + &BmcStatus, + SysInterfaceSsif); + if (EFI_ERROR (Status) || (BmcStatus =3D=3D BmcStatusHardFail)) { + IpmiTransport2->Interface.Ssif.InterfaceState =3D IpmiInterface= InitError; + continue; + } + + GetSystemInterfaceCapability (IpmiTransport2); + GetGlobalEnables (IpmiTransport2); + break; + } + + FreePool(HandleBuffer); + return Status; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.inf b/Features/In= tel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Ssi= fInterfaceLib/SmmSsifInterfaceLib.inf new file mode 100644 index 0000000000..a7e25647e2 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.inf @@ -0,0 +1,40 @@ +## @file SmmSsifInterfaceLib.inf +# +# INF description file for SsifInterfaceLib Library for DXE SMM drivers. +# +# @copyright +# Copyright 2016 - 2021 Intel Corporation.
+# Copyright (c) 1985 - 2023, American Megatrends International LLC.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SmmSsifInterfaceLib + FILE_GUID =3D DB817B63-FA26-44FA-BF84-8D48596F982B + MODULE_TYPE =3D DXE_SMM_DRIVER + VERSION_STRING =3D 1.1 + LIBRARY_CLASS =3D SsifInterfaceLib | DXE_SMM_DRIVER + +[Sources] + SmmSsifInterfaceLib.c + SsifInterfaceLibCommon.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IpmiFeaturePkg/IpmiFeaturePkg.dec + +[LibraryClasses] + SmmServicesTableLib + MemoryAllocationLib + BmcCommonInterfaceLib + +[Protocols] + gEfiSmbusHcProtocolGuid + +[Pcd] + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifSlaveAddress + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifCommandtRetryCounter + gIpmiFeaturePkgTokenSpaceGuid.PcdSsifRequestRetriesDelay diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcI= nterfaceCommonAccess/SsifInterfaceLib/SsifInterfaceLibCommon.c b/Features/I= ntel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Ss= ifInterfaceLib/SsifInterfaceLibCommon.c new file mode 100644 index 0000000000..5b6feb194f --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/BmcInterfac= eCommonAccess/SsifInterfaceLib/SsifInterfaceLibCommon.c @@ -0,0 +1,546 @@ +/** @file SsifInterfaceLibCommon.c + SSIF Transport Implementation common functions and variables. + + @copyright + Copyright 2016 - 2021 Intel Corporation.
+ Copyright (c) 1985 - 2023, American Megatrends International LLC.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include + +SSIF_ALERT_PIN_CHECK *gSsifAlertPinCheckHookList[] =3D +{ + NULL +}; + +/** + Check the SMBUS alert pin status function + + @param VOID Nothing. + + @retval TRUE Alert pin status is set. + @retval FALSE Alert pin status is not set. + +**/ +BOOLEAN +CheckAlertPinHook ( + VOID + ) +{ + BOOLEAN CheckAlertSignal =3D FALSE; + UINTN Index; + + for (Index =3D 0; gSsifAlertPinCheckHookList[Index]; Index++) { + CheckAlertSignal =3D gSsifAlertPinCheckHookList[Index](); + } + + return CheckAlertSignal; +} + +/** + Sends the command/data to Ssif interface. + + @param[in] Interface Pointer to System interface. + @param[in] Context NULL here. + @param[in] Data Pointer to command data that will be sent to B= MC + along with Command. + @param[in] DataSize Size of the command data. + + @return EFI_STATUS Status returned from Smbus send command. + +**/ +EFI_STATUS +SendDataToSsifBmcPort ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN VOID *Context, + IN UINT8 *Data, + IN UINT8 DataSize + ) +{ + EFI_STATUS Status; + EFI_SMBUS_DEVICE_ADDRESS BmcAddress; + UINTN IpmiWriteCommand; + UINT8 IpmiData[IPMI_SMBUS_BLOCK_LENGTH]; + UINTN DataLength; + UINT8 DataIndex; + BOOLEAN PECSupport; + UINT8 RetryCount; + UINT8 OriginalDataSize; + + DataLength =3D DataSize; + DataIndex =3D 0; + RetryCount =3D 0; + OriginalDataSize =3D DataSize; + PECSupport =3D Interface->Ssif.PecSupport; + BmcAddress.SmbusDeviceAddress =3D FixedPcdGet16 (PcdSsifSlaveAddress); + ZeroMem (IpmiData, sizeof(IpmiData)); + + do { + if (OriginalDataSize =3D=3D DataSize) { + if (DataSize <=3D IPMI_SMBUS_BLOCK_LENGTH) { + // Working single writes start. + DataLength =3D DataSize; + IpmiWriteCommand =3D IPMI_SMBUS_SINGLE_WRITE_CMD; + CopyMem ( + IpmiData, + &Data[DataIndex*IPMI_SMBUS_BLOCK_LENGTH], + DataLength ); + } else { + // Working multi-part writes start. + IpmiWriteCommand =3D IPMI_SMBUS_MULTI_WRITE_START_CMD; + DataLength =3D IPMI_SMBUS_BLOCK_LENGTH; + CopyMem ( + IpmiData, + &Data[DataIndex*IPMI_SMBUS_BLOCK_LENGTH], + DataLength ); + } + } else { + if (DataSize > IPMI_SMBUS_BLOCK_LENGTH) { + // Working multi-part writes middle. + IpmiWriteCommand =3D IPMI_SMBUS_MULTI_WRITE_MIDDLE_CMD; + DataLength =3D IPMI_SMBUS_BLOCK_LENGTH; + CopyMem ( + IpmiData, + &Data[DataIndex*IPMI_SMBUS_BLOCK_LENGTH], + DataLength ); + } else { + // Working multi-part writes end. + IpmiWriteCommand =3D IPMI_SMBUS_MULTI_WRITE_END_CMD; + DataLength =3D DataSize; + CopyMem ( + IpmiData, + &Data[DataIndex*IPMI_SMBUS_BLOCK_LENGTH], + DataLength ); + } + } + + Status =3D IpmiSmbusSendCommand ( + Interface, + BmcAddress, + IpmiWriteCommand, + EfiSmbusWriteBlock, + PECSupport, + &DataLength, + IpmiData ); + if (!EFI_ERROR(Status)) { + if (DataSize >=3D IPMI_SMBUS_BLOCK_LENGTH) { + RetryCount =3D 0; + DataSize -=3D IPMI_SMBUS_BLOCK_LENGTH; + DataIndex++; + } else { + DataSize =3D 0; + } + } else { + if (RetryCount =3D=3D Interface->Ssif.SsifRetryCounter) { + break; + } else { + RetryCount++; + // Failed retries delay about 60ms to 250ms. + MicroSecondDelay (FixedPcdGet32 (PcdSsifRequestRetriesDelay)= ); + /* If the Multi-part write fails, then try to write the + data from the beginning.*/ + if (IpmiWriteCommand !=3D IPMI_SMBUS_SINGLE_WRITE_CMD) { + DataSize =3D OriginalDataSize; + DataIndex =3D 0; + } + } + } + + } while (DataSize); + return Status; +} + +/** + Receives the Data from BMC port + + @param[in] Interface Pointer to System interface. + @param[in] Context NULL here. + @param[out] Data Pointer to response data that is received from + BMC. + @param[out] DataSize Size of the response data. + + @retval EFI_SUCCESS Data received from BMC successfully. + @retval Others Status of the Receiving data to BMC port. + + @return EFI_STATUS Status returned from Smbus send command. + +**/ +EFI_STATUS +ReceiveBmcDataFromSsifPort ( + IN IPMI_SYSTEM_INTERFACE *Interface, + IN VOID *Context, + OUT UINT8 *Data, + OUT UINT8 *DataSize + ) +{ + EFI_STATUS Status; + EFI_SMBUS_DEVICE_ADDRESS BmcAddress; + UINTN IpmiReadCommand; + UINT8 IpmiData[IPMI_SMBUS_BLOCK_LENGTH]; + UINTN DataLength; + BOOLEAN PECSupport; + UINT8 RetryCount; + UINT8 OriginalDataSize; + + DataLength =3D *DataSize; + RetryCount =3D 0; + OriginalDataSize =3D *DataSize; + PECSupport =3D Interface->Ssif.PecSupport; + BmcAddress.SmbusDeviceAddress =3D FixedPcdGet16 (PcdSsifSlaveAddress); + IpmiReadCommand =3D IPMI_SMBUS_SINGLE_READ_CMD; + + while (RetryCount <=3D Interface->Ssif.SsifRetryCounter) { + + Status =3D IpmiSmbusSendCommand ( + Interface, + BmcAddress, + IpmiReadCommand, + EfiSmbusReadBlock, + PECSupport, + &DataLength, + (VOID *)IpmiData ); + if (EFI_ERROR(Status)) { + RetryCount++; + // Failed retries delay about 60ms to 250ms. + MicroSecondDelay (FixedPcdGet32 (PcdSsifRequestRetriesDelay)); + /* If the Multi-part Read command fails, then try to read the + data from the beginning.*/ + if (IpmiReadCommand !=3D IPMI_SMBUS_SINGLE_READ_CMD) { + IpmiReadCommand =3D IPMI_SMBUS_SINGLE_READ_CMD; + } + DataLength =3D OriginalDataSize; + continue; + } + + if (IpmiReadCommand =3D=3D IPMI_SMBUS_SINGLE_READ_CMD) { + if ((IpmiData[0] =3D=3D IPMI_MULTI_READ_ZEROTH_STRT_BIT) && + (IpmiData[1] =3D=3D IPMI_MULTI_READ_FIRST_STRT_BIT)) { + // Working multi-part reads start. + CopyMem ( + Data, + &IpmiData[2], + DataLength-2 ); + *DataSize =3D (UINT8)DataLength-2; + IpmiReadCommand =3D IPMI_SMBUS_MULTI_READ_MIDDLE_CMD; + } else { + // Working single reads start. + CopyMem ( + Data, + IpmiData, + DataLength ); + *DataSize =3D (UINT8)DataLength; + break; + } + } else { + if(IpmiData[0] =3D=3D 0xFF) { + // Working multi-part reads end. + CopyMem ( + &Data[*DataSize], + &IpmiData[1], + DataLength-1 ); + *DataSize +=3D (UINT8)DataLength-1; + break; + } else { + // Working multi-part reads middle. + CopyMem ( + &Data[*DataSize], + &IpmiData[1], + DataLength-1 ); + *DataSize +=3D (UINT8)DataLength-1; + IpmiReadCommand =3D IPMI_SMBUS_MULTI_READ_MIDDLE_CMD; + } + } + } + + return Status; +} + +/** @internal + SSIF interface Ipmi send command Implementation + + @param[in] Interface Pointer to System interface. + @param[in] NetFunction Net function of the command. + @param[in] Lun Logical Unit Number of the command= . + @param[in] Command Command to be sent to BMC. + @param[in] CommandData Command data to be sent along with + Command. + @param[in] CommandDataSize Command Data size. + @param[out] ResponseData Pointer to the response data buffe= r. + @param[in, out] ResponseDataSize Pointer to the response data size. + @param[out] CompletionCode Pointer to completion code. + @param[in] InterfaceType Interface type. + @param[in] Context NULL here. + + @retval EFI_UNSUPPORTED Interface type is not supported. + @retval EFI_NOT_READY Interface is not initialized. + @retval EFI_ACCESS_DENIED Interface is locked. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_BAD_BUFFER_SIZE Invalid buffer size. + @retval EFI_DEVICE_ERROR Error completion code or data size + retrieved is small. + @retval EFI_BUFFER_TOO_SMALL Buffer is too small to update + response data. + @retval EFI_SUCCESS Command sent successfully. + @return Others Error status returned from BMC while + executing the command. + +**/ +EFI_STATUS +EFIAPI +IpmiSsifSendCommandToBmc ( + IN IPMI_TRANSPORT2 *This, + IN UINT8 NetFunction, + IN UINT8 Lun, + IN UINT8 Command, + IN UINT8 *CommandData, + IN UINT8 CommandDataSize, + IN OUT UINT8 *ResponseData, + IN OUT UINT8 *ResponseDataSize, + IN VOID *Context +) +{ + EFI_STATUS Status; + UINT8 DataSize; + UINT8 CmdDataBuffer[IPMI_MAX_SSIF_CMD_DATA_SIZE]; + IPMI_SYSTEM_INTERFACE Interface; + + Interface =3D This->Interface; + + if (Interface.Ssif.InterfaceState !=3D IpmiInterfaceInitialized) { + return EFI_NOT_READY; + } + + if (((CommandData =3D=3D NULL) && (CommandDataSize!=3D 0)) || (This =3D= =3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + if ((ResponseDataSize =3D=3D NULL) || ((ResponseData =3D=3D NULL) && *Re= sponseDataSize)) { + return EFI_INVALID_PARAMETER; + } + + if (IpmiIsIpmiTransportlocked (&Interface.Ssif.SsifTransportLocked)) { + return EFI_ACCESS_DENIED; + } else { + IpmiTransportAcquireLock (&Interface.Ssif.SsifTransportLocked); + } + + // Check the SSIF interface multi-part reads/writes supported. + // Block length include Command data, NetFn, and Command parameter. + if (((Interface.Ssif.RwSupport =3D=3D SsifSinglePartRw) && + ((CommandDataSize + 2) > IPMI_SMBUS_BLOCK_LENGTH)) || + ((Interface.Ssif.RwSupport =3D=3D SsifMultiPartRw) && + ((CommandDataSize + 2) > (2*IPMI_SMBUS_BLOCK_LENGTH))) || + ((Interface.Ssif.RwSupport =3D=3D SsifMultiPartRwWithMiddle) && + ((CommandDataSize + 2) > IPMI_MAX_SSIF_CMD_DATA_SIZE))) { + + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_INVALID_PARAMETER; + } + + if (Interface.Ssif.SsifSoftErrorCount >=3D MAX_BMC_CMD_FAIL_COUNT) { + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_NOT_READY; + } + + CmdDataBuffer[0] =3D (UINT8) ((NetFunction << 2) | (Lun & 0x03)); + CmdDataBuffer[1] =3D Command; + + if (CommandDataSize > 0) { + if (CommandData =3D=3D NULL) { + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_INVALID_PARAMETER; + } + if (CommandDataSize <=3D (IPMI_MAX_SSIF_CMD_DATA_SIZE - 2) ) { + CopyMem ( + &CmdDataBuffer[2], + CommandData, + CommandDataSize ); + } else { + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_BAD_BUFFER_SIZE; + } + } + + Status =3D SendDataToSsifBmcPort ( + &Interface, + Context, + CmdDataBuffer, + (UINT8)(CommandDataSize + 2)); + + if (Status !=3D EFI_SUCCESS) { + Interface.Ssif.SsifSoftErrorCount++; + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return Status; + } + + // Hook to check smbus alert pin. + if (Interface.Ssif.SmbAlertSupport) { + if (!CheckAlertPinHook()) { + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_DEVICE_ERROR; + } + } else { + MicroSecondDelay(FixedPcdGet32 (PcdSsifRequestRetriesDelay)); + } + DataSize =3D IPMI_SMBUS_BLOCK_LENGTH; + + Status =3D ReceiveBmcDataFromSsifPort ( + &Interface, + Context, + CmdDataBuffer, + &DataSize); + if (Status !=3D EFI_SUCCESS) { + Interface.Ssif.SsifSoftErrorCount++; + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return Status; + } + + if (IPMI_ERROR_COMPLETION_CODE(CmdDataBuffer[2])) { + IpmiUpdateSoftErrorCount ( + CmdDataBuffer[2], + &Interface, + This->InterfaceType ); + // Write completion code into return buffer if ipmi command returns = an error. + if (*ResponseDataSize) { + if (ResponseData) { + *ResponseData =3D CmdDataBuffer[2]; + } + *ResponseDataSize =3D 1; + } + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_DEVICE_ERROR; + } + + if (DataSize < 3) { + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_DEVICE_ERROR; + } + + if ((DataSize - 2) > *((UINT8 *)ResponseDataSize)) { + *ResponseDataSize =3D (UINT8) (DataSize - 3); + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_BUFFER_TOO_SMALL; + } + + // Copying the response data into ResponseData buffer. + CopyMem ( + ResponseData, + &CmdDataBuffer[2], + (DataSize - 2) ); + *ResponseDataSize =3D (UINT8) (DataSize - 2); + + IpmiTransportReleaseLock (&Interface.Ssif.SsifTransportLocked); + return EFI_SUCCESS; +} + +/** + Execute the Get System Interface Capability command and update the RwS= upport + and PecSupport of Ipmi Instance. + + @param IpmiInstance Ipmi Instance Data structure pointer. + + @return EFI_STATUS Return Status + +**/ +VOID +GetSystemInterfaceCapability ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ) +{ + EFI_STATUS Status; + IPMI_GET_SYSTEM_INTERFACE_CAPABILITY_REQ GetSystemInterfaceCapabi= lityCmd; + IPMI_GET_SYSTEM_INTERFACE_CAPABILITY_RES GetSsifInterfaceCapabili= ty; + UINT32 DataSize =3D sizeof (Get= SsifInterfaceCapability); + + GetSystemInterfaceCapabilityCmd.SystemInterfaceType =3D 0x0; // SSIF + GetSystemInterfaceCapabilityCmd.Reserved =3D 0x0; + + Status =3D IpmiTransport2->IpmiSubmitCommand2 ( + IpmiTransport2, + IPMI_NETFN_APP, + BMC_LUN, + IPMI_APP_GET_SYSTEM_INTERFACE_CA= PABILITIES, + (UINT8*) &GetSystemInterfaceCapa= bilityCmd, + sizeof (GetSystemInterfaceCapabi= lityCmd), + (UINT8*) &GetSsifInterfaceCapabi= lity, + &DataSize); + if (!EFI_ERROR (Status)) { + IpmiTransport2->Interface.Ssif.RwSupport =3D GetSsifInterfaceCapabil= ity.TransactionSupport; + IpmiTransport2->Interface.Ssif.PecSupport =3D GetSsifInterfaceCapabi= lity.PecSupport; + } +} + +/** + Execute the Get Global Enable command to get receive message queue int= errupt. + + @return VOID + +**/ +VOID +GetGlobalEnables ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 +) +{ + EFI_STATUS Status; + IPMI_BMC_GLOBAL_ENABLES_RES BmcGlobalEnables; + UINT32 ResponseDataSize =3D sizeof (BmcGlob= alEnables); + + // + // Get Global Enable Information. + // + Status =3D IpmiTransport2->IpmiSubmitCommand2( + IpmiTransport2, + IPMI_NETFN_APP, + BMC_LUN, + IPMI_APP_GET_BMC_GLOBAL_ENABLES, + NULL, + 0, + (UINT8 *) (&BmcGlobalEnables), + &ResponseDataSize ); + if (!EFI_ERROR(Status)) { + // + // Set Smb alert pin based on ReceiveMsgQueueInterrupt bit + // + IpmiTransport2->Interface.Ssif.SmbAlertSupport =3D BmcGlobalEnables.= ReceiveMsgQueueInterrupt; + } +} + +/** + Initialize SSIF interface specific data. + + @param[in, out] Interface System interface pointer. + + @retval EFI_SUCCESS Interface is successfully initialized. + @retval Others Return status while initializing interface. + +**/ +EFI_STATUS +InitSsifInterfaceData ( + IN OUT IPMI_TRANSPORT2 *IpmiTransport2 + ) +{ + EFI_STATUS Status =3D EFI_SUCCESS; + + if (IpmiTransport2->Interface.Ssif.InterfaceState =3D=3D IpmiInterfaceIn= itialized) { + return Status; + } + + IpmiTransport2->Interface.Ssif.SsifRetryCounter =3D FixedPcdGet16 (Pc= dSsifCommandtRetryCounter); + IpmiTransport2->Interface.Ssif.PecSupport =3D FALSE; + IpmiTransport2->Interface.Ssif.RwSupport =3D 0x0; // SSIF mu= lti-part reads/writes support. + IpmiTransport2->Interface.Ssif.SmbAlertSupport =3D FALSE; // SMB ale= rt pin support. + + Status =3D IpmiGetSmbusApiPtr (IpmiTransport2); + if (EFI_ERROR(Status)) { + IpmiTransport2->Interface.Ssif.InterfaceState =3D IpmiInterfaceInitE= rror; + return Status; + } + + IpmiTransportReleaseLock (&IpmiTransport2->Interface.Ssif.SsifTransportL= ocked); + return Status; +} -- 2.38.1.windows.1 -The information contained in this message may be confidential and propriet= ary to American Megatrends (AMI). This communication is intended to be read= only by the individual or entity to whom it is addressed or by their desig= nee. If the reader of this message is not the intended recipient, you are o= n notice that any distribution of this message, in any form, is strictly pr= ohibited. Please promptly notify the sender by reply e-mail or by telephone= at 770-246-8600, and then delete or destroy all copies of the transmission= .