From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=40.107.4.72; helo=eur03-db5-obe.outbound.protection.outlook.com; envelope-from=girish.pathak@arm.com; receiver=edk2-devel@lists.01.org Received: from EUR03-DB5-obe.outbound.protection.outlook.com (mail-eopbgr40072.outbound.protection.outlook.com [40.107.4.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 3712521F0DB01 for ; Mon, 23 Apr 2018 09:06:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector1-arm-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=AavC5iWMPPHfiMYxUa4nZAggLO2AJruvO+mWx0TFDog=; b=LpHEuL0dWtejF+3NLcCt+eQU1G1Lo1/r478XS79G2e4a6EJpSBEVy6jss3QmE/UMkNaLuLm5GN9Omueq9ZSxLZXcHeCRFmDOfU6IQ+0joLdra6cn4Fa6PwbOdcWuO+Tq1+v/beFUR2u3F6AwjWS3/3mbOn4rvHgXYaHnCly1lB8= Received: from AM4PR08MB0995.eurprd08.prod.outlook.com (10.166.134.10) by AM4PR08MB1186.eurprd08.prod.outlook.com (10.167.92.18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.696.13; Mon, 23 Apr 2018 16:06:44 +0000 Received: from AM4PR08MB0995.eurprd08.prod.outlook.com ([fe80::d94d:5186:b1c6:e46b]) by AM4PR08MB0995.eurprd08.prod.outlook.com ([fe80::d94d:5186:b1c6:e46b%3]) with mapi id 15.20.0696.017; Mon, 23 Apr 2018 16:06:43 +0000 From: Girish Pathak To: Leif Lindholm CC: "edk2-devel@lists.01.org" , "ard.biesheuvel@linaro.org" , Matteo Carlini , Stephanie Hughes-Fitt , nd Thread-Topic: [PATCH v3 16/16] ArmPkg: Introduce SCMI protocol Thread-Index: AQHT2vbiuaqgDC0omUaczEnSWEYez6QOZA5Q Date: Mon, 23 Apr 2018 16:06:43 +0000 Message-ID: References: <20180320161212.79120-1-girish.pathak@arm.com> <20180320161212.79120-17-girish.pathak@arm.com> <20180423113150.6dgqzp23ersamcrh@bivouac.eciton.net> In-Reply-To: <20180423113150.6dgqzp23ersamcrh@bivouac.eciton.net> Accept-Language: en-GB, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: linaro.org; dkim=none (message not signed) header.d=none;linaro.org; dmarc=none action=none header.from=arm.com; x-originating-ip: [217.140.96.140] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; AM4PR08MB1186; 7:qC/B/lzFMH/jSxixRVHgLSKaTDsGti+3r5vWVpUJ+4hS7vKUqbzYf1NRuekG/xC92bHnszriEJKOsggDWFHbhbFrr/cPEYEhyu9yZv98ZgtiiZGdrlw0f8+bFzG3tGP/9spYlBsYdgpRMuh7LSNIJ/JCOeJzcjDB2Xz8ClHHAE2jNHAqmSj9dLhqvPSJdzL6Ep1feXvtYM1TzaDvjvPbeYQzULGZjBMyHiqPFZxgofZLmP1ZUBa4+gkQAuDjuDMC x-ms-exchange-antispam-srfa-diagnostics: SOS;SOR; x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(48565401081)(5600026)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020); SRVR:AM4PR08MB1186; x-ms-traffictypediagnostic: AM4PR08MB1186: nodisclaimer: True x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(180628864354917)(131327999870524)(788757137089)(162533806227266); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(3002001)(3231232)(944501410)(52105095)(93006095)(93001095)(10201501046)(6055026)(6041310)(20161123564045)(20161123560045)(20161123558120)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(6072148)(201708071742011); SRVR:AM4PR08MB1186; BCL:0; PCL:0; RULEID:; SRVR:AM4PR08MB1186; x-forefront-prvs: 06515DA04B x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(396003)(39860400002)(366004)(39380400002)(376002)(346002)(13464003)(54906003)(53936002)(478600001)(55016002)(316002)(72206003)(53946003)(4326008)(575784001)(966005)(86362001)(8936002)(7696005)(53376002)(6246003)(8676002)(9686003)(6306002)(6436002)(476003)(81166006)(76176011)(11346002)(59450400001)(26005)(3280700002)(3846002)(66066001)(5250100002)(16799955002)(446003)(186003)(6116002)(15188155005)(2906002)(5660300001)(305945005)(7736002)(229853002)(25786009)(102836004)(53546011)(3660700001)(2900100001)(33656002)(6916009)(74316002)(6506007)(579004)(559001); DIR:OUT; SFP:1101; SCL:1; SRVR:AM4PR08MB1186; H:AM4PR08MB0995.eurprd08.prod.outlook.com; FPR:; SPF:None; LANG:en; MLV:sfv; x-microsoft-antispam-message-info: yBaIzgsp/OkqS/Vv7Q51bbLYFHiCQyQEDtMKbq9NpidVOTV+xdrQNIKkOjU9KF2NoGmKJWA80bM0dlOusrbkW0C25qet9EbrdIi3pym+x+OeVlg/cE2OLsNlAf5jz0C7M0T76jDAFC/bdAOocY9TOd58jT7l4Bf8xvFMW/tZ19Oqcrl8K6+7bTYlRzbTF3Au spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: f8eb1f8f-6d94-4d19-a646-08d5a9343544 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-Network-Message-Id: f8eb1f8f-6d94-4d19-a646-08d5a9343544 X-MS-Exchange-CrossTenant-originalarrivaltime: 23 Apr 2018 16:06:43.8315 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR08MB1186 Subject: Re: [PATCH v3 16/16] ArmPkg: Introduce SCMI protocol X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 Apr 2018 16:06:51 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi Leif, > -----Original Message----- > From: Leif Lindholm > Sent: 23 April 2018 12:32 > To: Girish Pathak > Cc: edk2-devel@lists.01.org; ard.biesheuvel@linaro.org; Matteo Carlini > ; Stephanie Hughes-Fitt Fitt@arm.com>; nd > Subject: Re: [PATCH v3 16/16] ArmPkg: Introduce SCMI protocol >=20 > Hmm, I did find a few minor things below that I need to hear back on > before pushing. Thanks for your comments, We can incorporate all the changes suggested, sha= ll I tidy this up and resubmit the patch series ? Regards, Girish >=20 > On Tue, Mar 20, 2018 at 04:12:12PM +0000, Girish Pathak wrote: > > This change introduces a new SCMI protocol driver for > > Arm systems. The driver currently supports only clock > > and performance management protocols. Other protocols > > will be added as and when needed. > > > > Clock management protocol is used to configure various clocks > > available on the platform e.g. HDLCD clock on the Juno platforms. > > > > Whereas performance management protocol allows adjustment > > of various performance domains. Currently this is used to evaluate > > performance of the Juno platform. > > > > Contributed-under: TianoCore Contribution Agreement 1.1 > > Signed-off-by: Girish Pathak > > Signed-off-by: Evan Lloyd > > --- > > > > Notes: > > v3: > > - Please rename ArmMtl.h to ArmMtlLibi.h, and > > declare it as a library class in the package file. [Ard] > > > > Done, however ArmMtlLib.h is now part of earlier commit [Giri= sh] > > > > - Move ArmScmiDxe to ArmPkg from ArmPlatformPkg [Ard] > > > > Done [Giri= sh] > > > > - Declare gArmScmiBaseProtocolGuid and similar > > protocols Guids in ArmPkg.dec [Ard] > > > > Done [Giri= sh] > > > > - Replace flexible array member [] with [1] [Ard] > > > > Done [Giri= sh] > > > > - Move protocol init function which are not part of > > of protocol like ScmiBaseProtocolInit elsewhere [Ard] > > > > Done [Giri= sh] > > > > - Please don't put stuff in Include/Drivers. [Ard] > > > > Moved headers to Include/Protocol. [Giri= sh] > > > > ArmPkg/ArmPkg.dec | 13 + > > ArmPkg/ArmPkg.dsc | 6 +- > > ArmPkg/Drivers/ArmScmiDxe/ArmScmiBaseProtocolPrivate.h | 46 ++ > > ArmPkg/Drivers/ArmScmiDxe/ArmScmiClockProtocolPrivate.h | 84 > ++++ > > ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf | 53 ++= + > > ArmPkg/Drivers/ArmScmiDxe/ArmScmiPerformanceProtocolPrivate.h | > 55 +++ > > ArmPkg/Drivers/ArmScmiDxe/Scmi.c | 262 ++= +++++++++ > > ArmPkg/Drivers/ArmScmiDxe/ScmiBaseProtocol.c | 318 > ++++++++++++++ > > ArmPkg/Drivers/ArmScmiDxe/ScmiClockProtocol.c | 418 > ++++++++++++++++++ > > ArmPkg/Drivers/ArmScmiDxe/ScmiDxe.c | 138 ++= ++++ > > ArmPkg/Drivers/ArmScmiDxe/ScmiDxe.h | 41 ++ > > ArmPkg/Drivers/ArmScmiDxe/ScmiPerformanceProtocol.c | 457 > ++++++++++++++++++++ > > ArmPkg/Drivers/ArmScmiDxe/ScmiPrivate.h | 174 ++= ++++++ > > ArmPkg/Include/Protocol/ArmScmi.h | 27 ++ > > ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h | 174 > ++++++++ > > ArmPkg/Include/Protocol/ArmScmiClockProtocol.h | 218 > ++++++++++ > > ArmPkg/Include/Protocol/ArmScmiPerformanceProtocol.h | 265 > ++++++++++++ > > 17 files changed, 2748 insertions(+), 1 deletion(-) > > > > diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec > > index > 881751d81c6384a3eb0b4c180c76d01a58266a74..16f7e40046429142b44b52604 > 3b61a3d5e089d2c 100644 > > --- a/ArmPkg/ArmPkg.dec > > +++ b/ArmPkg/ArmPkg.dec > > @@ -51,6 +51,19 @@ [Guids.common] > > > > gArmGicDxeFileGuid =3D { 0xde371f7c, 0xdec4, 0x4d21, { 0xad, 0xf1, 0= x59, > 0x3a, 0xbc, 0xc1, 0x58, 0x82 } } > > > > +[Protocols.common] > > + ## Arm System Control and Management Interface(SCMI) Base protocol > > + ## ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h > > + gArmScmiBaseProtocolGuid =3D { 0xd7e5abe9, 0x33ab, 0x418e, { 0x9f, 0= x91, > 0x72, 0xda, 0xe2, 0xba, 0x8e, 0x2f } } > > + > > + ## Arm System Control and Management Interface(SCMI) Clock > management protocol > > + ## ArmPkg/Include/Protocol/ArmScmiClockProtocol.h > > + gArmScmiClockProtocolGuid =3D { 0x91ce67a8, 0xe0aa, 0x4012, { 0xb9, = 0x9f, > 0xb6, 0xfc, 0xf3, 0x4, 0x8e, 0xaa } } > > + > > + ## Arm System Control and Management Interface(SCMI) Clock > management protocol > > + ## ArmPkg/Include/Protocol/ArmScmiPerformanceProtocol.h > > + gArmScmiPerformanceProtocolGuid =3D { 0x9b8ba84, 0x3dd3, 0x49a6, > { 0xa0, 0x5a, 0x31, 0x34, 0xa5, 0xf0, 0x7b, 0xad } } > > + > > [Ppis] > > ## Include/Ppi/ArmMpCoreInfo.h > > gArmMpCoreInfoPpiGuid =3D { 0x6847cc74, 0xe9ec, 0x4f8f, {0xa2, 0x9d, > 0xab, 0x44, 0xe7, 0x54, 0xa8, 0xfc} } > > diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc > > index > 526909458e0d80dbc5a65c8ad12ec1095dda48d2..22332090db7111e0668607a1 > 6288cefc1bace926 100644 > > --- a/ArmPkg/ArmPkg.dsc > > +++ b/ArmPkg/ArmPkg.dsc > > @@ -2,7 +2,7 @@ > > # ARM processor package. > > # > > # Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.
> > -# Copyright (c) 2011 - 2015, ARM Ltd. All rights reserved.
> > +# Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.
> > # Copyright (c) 2016, Linaro Ltd. All rights reserved.
> > # > > # This program and the accompanying materials > > @@ -87,6 +87,8 @@ [LibraryClasses.common] > > ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf > > ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf > > > > + ArmMtlLib|ArmPkg/Library/ArmMtlNullLib/ArmMtlNullLib.inf > > + > > [LibraryClasses.common.PEIM] > > HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf > > PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf > > @@ -144,5 +146,7 @@ [Components.common] > > > ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf > > ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf > > > > + ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf > > + > > [Components.AARCH64] > > ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf > > diff --git a/ArmPkg/Drivers/ArmScmiDxe/ArmScmiBaseProtocolPrivate.h > b/ArmPkg/Drivers/ArmScmiDxe/ArmScmiBaseProtocolPrivate.h > > new file mode 100644 > > index > 0000000000000000000000000000000000000000..79c057d44128008ec276e3d58 > d8f1098c6a779b2 > > --- /dev/null > > +++ b/ArmPkg/Drivers/ArmScmiDxe/ArmScmiBaseProtocolPrivate.h > > @@ -0,0 +1,46 @@ > > +/** @file > > + > > + Copyright (c) 2017-2018, Arm Limited. All rights reserved. > > + > > + This program and the accompanying materials > > + are licensed and made available under the terms and conditions of th= e > BSD License > > + which accompanies this distribution. The full text of the license m= ay be > found at > > + http://opensource.org/licenses/bsd-license.php > > + > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > > + > > + System Control and Management Interface V1.0 > > + http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ > > + DEN0056A_System_Control_and_Management_Interface.pdf > > +**/ > > + > > +#ifndef ARM_SCMI_BASE_PROTOCOL_PRIVATE_H_ > > +#define ARM_SCMI_BASE_PROTOCOL_PRIVATE_H_ > > + > > +// Return values of BASE_DISCOVER_LIST_PROTOCOLS command. > > +typedef struct { > > + UINT32 NumProtocols; > > + > > + // Array of four protocols in each element > > + // Total elements =3D 1 + (NumProtocols-1)/4 > > + > > + // NOTE: Since EDK2 does not allow flexible array member [] we decla= re > > + // here array of 1 element length. However below is used as a variab= le > > + // length array. > > + UINT8 Protocols[1]; > > +} BASE_DISCOVER_LIST; > > + > > +/** Initialize Base protocol and install protocol on a given handle. > > + > > + @param[in] Handle Handle to install Base protocol. > > + > > + @retval EFI_SUCCESS Base protocol interface installed > > + successfully. > > +**/ > > +EFI_STATUS > > +ScmiBaseProtocolInit ( > > + IN OUT EFI_HANDLE* Handle > > + ); > > + > > +#endif /* ARM_SCMI_BASE_PROTOCOL_PRIVATE_H_ */ > > diff --git a/ArmPkg/Drivers/ArmScmiDxe/ArmScmiClockProtocolPrivate.h > b/ArmPkg/Drivers/ArmScmiDxe/ArmScmiClockProtocolPrivate.h > > new file mode 100644 > > index > 0000000000000000000000000000000000000000..71245c16475d4d38d6dc66571 > b3fe3520c1cf1da > > --- /dev/null > > +++ b/ArmPkg/Drivers/ArmScmiDxe/ArmScmiClockProtocolPrivate.h > > @@ -0,0 +1,84 @@ > > +/** @file > > + > > + Copyright (c) 2017-2018, Arm Limited. All rights reserved. > > + > > + This program and the accompanying materials > > + are licensed and made available under the terms and conditions of th= e > BSD License > > + which accompanies this distribution. The full text of the license m= ay be > found at > > + http://opensource.org/licenses/bsd-license.php > > + > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > > + > > + System Control and Management Interface V1.0 > > + http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ > > + DEN0056A_System_Control_and_Management_Interface.pdf > > +**/ > > + > > +#ifndef ARM_SCMI_CLOCK_PROTOCOL_PRIVATE_H_ > > +#define ARM_SCMI_CLOCK_PROTOCOL_PRIVATE_H_ > > + > > +#pragma pack(1) > > + > > +// Clock rate in two 32bit words. > > +typedef struct { > > + UINT32 Low; > > + UINT32 High; > > +} CLOCK_RATE_DWORD; > > + > > +// Format of the returned rate array. Linear or Non-linear,.RatesFlag = Bit[12] > > +#define RATE_FORMAT_SHIFT 12 > > +#define RATE_FORMAT_MASK 0x0001 > > +#define RATE_FORMAT(RatesFlags) ((RatesFlags >> > RATE_FORMAT_SHIFT) \ > > + & RATE_FORMAT_MASK) >=20 > I'll decrease indentation of above line by one unless someone objects? >=20 > > + > > +// Number of remaining rates after a call to the SCP, RatesFlag Bits[3= 1:16] > > +#define NUM_REMAIN_RATES_SHIFT 16 > > +#define NUM_REMAIN_RATES(RatesFlags) ((RatesFlags >> > NUM_REMAIN_RATES_SHIFT)) > > + > > +// Number of rates that are returned by a call.to the SCP, RatesFlag > Bits[11:0] > > +#define NUM_RATES_MASK 0x0FFF > > +#define NUM_RATES(RatesFlags) (RatesFlags & NUM_RATES_MASK) > > + > > +// Return values for the CLOCK_DESCRIBER_RATE command. > > +typedef struct { > > + UINT32 NumRatesFlags; > > + > > + // NOTE: Since EDK2 does not allow flexible array member [] we decla= re > > + // here array of 1 element length. However below is used as a variab= le > > + // length array. > > + CLOCK_RATE_DWORD Rates[1]; > > +} CLOCK_DESCRIBE_RATES; > > + > > +#define CLOCK_SET_DEFAULT_FLAGS 0 > > + > > +// Message parameters for CLOCK_RATE_SET command. > > +typedef struct { > > + UINT32 Flags; > > + UINT32 ClockId; > > + CLOCK_RATE_DWORD Rate; > > +} CLOCK_RATE_SET_ATTRIBUTES; > > + > > +// if ClockAttr Bit[0] is set then clock device is enabled. > > +#define CLOCK_ENABLE_MASK 0x1 > > +#define CLOCK_ENABLED(ClockAttr) ((ClockAttr & CLOCK_ENABLE_MASK) > =3D=3D 1) > > + > > +typedef struct { > > + UINT32 Attributes; > > + UINT8 ClockName[SCMI_MAX_STR_LEN]; > > +} CLOCK_ATTRIBUTES; > > + > > +#pragma pack() > > + > > +/** Initialize clock management protocol and install protocol on a giv= en > handle. > > + > > + @param[in] Handle Handle to install clock management pr= otocol. > > + > > + @retval EFI_SUCCESS Clock protocol interface installed su= ccessfully. > > +**/ > > +EFI_STATUS > > +ScmiClockProtocolInit ( > > + IN EFI_HANDLE *Handle > > + ); > > + > > +#endif /* ARM_SCMI_CLOCK_PROTOCOL_PRIVATE_H_ */ > > diff --git a/ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf > b/ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf > > new file mode 100644 > > index > 0000000000000000000000000000000000000000..05ce9c04ce468d74e5c6d3873 > 9f9056f3fc48694 > > --- /dev/null > > +++ b/ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf > > @@ -0,0 +1,53 @@ > > +#/** @file > > +# > > +# Copyright (c) 2017-2018, Arm Limited. All rights reserved. > > +# > > +# This program and the accompanying materials > > +# are licensed and made available under the terms and conditions of t= he > BSD License > > +# which accompanies this distribution. The full text of the license = may be > found at > > +# http://opensource.org/licenses/bsd-license.php > > +# > > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > > +# > > +# System Control and Management Interface V1.0 > > +# http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ > > +# DEN0056A_System_Control_and_Management_Interface.pdf > > +#**/ > > + > > +[Defines] > > + INF_VERSION =3D 0x00010019 > > + BASE_NAME =3D ArmScmiDxe > > + FILE_GUID =3D 9585984C-F027-45E9-AFDF-ADAA6DFAA= AC7 > > + MODULE_TYPE =3D DXE_DRIVER > > + VERSION_STRING =3D 1.0 > > + ENTRY_POINT =3D ArmScmiDxeEntryPoint > > + > > +[Sources.common] > > + Scmi.c > > + ScmiBaseProtocol.c > > + ScmiClockProtocol.c > > + ScmiDxe.c > > + ScmiPerformanceProtocol.c > > + > > +[Packages] > > + ArmPkg/ArmPkg.dec > > + ArmPlatformPkg/ArmPlatformPkg.dec > > + MdePkg/MdePkg.dec > > + > > +[LibraryClasses] > > + ArmLib > > + ArmMtlLib > > + DebugLib > > + IoLib > > + UefiBootServicesTableLib > > + UefiDriverEntryPoint > > + > > +[Protocols] > > + gArmScmiBaseProtocolGuid > > + gArmScmiClockProtocolGuid > > + gArmScmiPerformanceProtocolGuid > > + > > +[Depex] > > + TRUE > > + > > diff --git > a/ArmPkg/Drivers/ArmScmiDxe/ArmScmiPerformanceProtocolPrivate.h > b/ArmPkg/Drivers/ArmScmiDxe/ArmScmiPerformanceProtocolPrivate.h > > new file mode 100644 > > index > 0000000000000000000000000000000000000000..4514f45a9f5dd960d2844a19b5 > 7a91b93149f1b9 > > --- /dev/null > > +++ > b/ArmPkg/Drivers/ArmScmiDxe/ArmScmiPerformanceProtocolPrivate.h > > @@ -0,0 +1,55 @@ > > +/** @file > > + > > + Copyright (c) 2017-2018, Arm Limited. All rights reserved. > > + > > + This program and the accompanying materials > > + are licensed and made available under the terms and conditions of th= e > BSD License > > + which accompanies this distribution. The full text of the license m= ay be > found at > > + http://opensource.org/licenses/bsd-license.php > > + > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > > + > > + System Control and Management Interface V1.0 > > + http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ > > + DEN0056A_System_Control_and_Management_Interface.pdf > > +**/ > > + > > +#ifndef ARM_SCMI_PERFORMANCE_PROTOCOL_PRIVATE_H_ > > +#define ARM_SCMI_PERFORMANCE_PROTOCOL_PRIVATE_H_ > > + > > +#include > > + > > +// Number of performance levels returned by a call to the SCP, Lvls > Bits[11:0] > > +#define NUM_PERF_LEVELS_MASK 0x0FFF > > +#define NUM_PERF_LEVELS(Lvls) (Lvls & NUM_PERF_LEVELS_MASK) > > + > > +// Number of performance levels remaining after a call to the SCP, Lvl= s > Bits[31:16] > > +#define NUM_REMAIN_PERF_LEVELS_SHIFT 16 > > +#define NUM_REMAIN_PERF_LEVELS(Lvls) (Lvls >> > NUM_REMAIN_PERF_LEVELS_SHIFT) > > + > > +/** Return values for > SCMI_MESSAGE_ID_PERFORMANCE_DESCRIBE_LEVELS command. > > + SCMI Spec ? 4.5.2.5 > > +**/ > > +typedef struct { > > + UINT32 NumLevels; > > + > > + // NOTE: Since EDK2 does not allow flexible array member [] we decla= re > > + // here array of 1 element length. However below is used as a variab= le > > + // length array. > > + SCMI_PERFORMANCE_LEVEL PerfLevel[1]; // Offset to array of > performance levels > > +} PERF_DESCRIBE_LEVELS; > > + > > +/** Initialize performance management protocol and install on a given > Handle. > > + > > + @param[in] Handle Handle to install performance managem= ent > > + protocol. > > + > > + @retval EFI_SUCCESS Performance protocol installed succes= sfully. > > +**/ > > +EFI_STATUS > > +ScmiPerformanceProtocolInit ( > > + IN EFI_HANDLE* Handle > > + ); > > + > > +#endif /* ARM_SCMI_PERFORMANCE_PROTOCOL_PRIVATE_H_ */ > > diff --git a/ArmPkg/Drivers/ArmScmiDxe/Scmi.c > b/ArmPkg/Drivers/ArmScmiDxe/Scmi.c > > new file mode 100644 > > index > 0000000000000000000000000000000000000000..1e279f69cf615428dbb6477b8a > c7de3258628df3 > > --- /dev/null > > +++ b/ArmPkg/Drivers/ArmScmiDxe/Scmi.c > > @@ -0,0 +1,262 @@ > > +/** @file > > + > > + Copyright (c) 2017-2018, Arm Limited. All rights reserved. > > + > > + This program and the accompanying materials > > + are licensed and made available under the terms and conditions of th= e > BSD License > > + which accompanies this distribution. The full text of the license m= ay be > found at > > + http://opensource.org/licenses/bsd-license.php > > + > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > > + > > + System Control and Management Interface V1.0 > > + http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ > > + DEN0056A_System_Control_and_Management_Interface.pdf > > +**/ > > + > > +#include > > +#include > > +#include > > +#include > > + > > +#include "ScmiPrivate.h" > > + > > +// SCMI Specification 1.0 > > +#define MAX_PROTOCOLS 6 > > + > > +#define PROTOCOL_MASK 0xF > > + > > +// Arbitrary timeout value 20ms. > > +#define RESPONSE_TIMEOUT 20000 > > + > > +/** Return a pointer to the message payload. > > + > > + @param[out] Payload Holds pointer to the message payload. > > + > > + @retval EFI_SUCCESS Payload holds a valid message payload po= inter. > > + @retval EFI_TIMEOUT Time out error if MTL channel is busy. > > + @retval EFI_UNSUPPORTED If MTL channel is unsupported. > > +**/ > > +EFI_STATUS > > +ScmiCommandGetPayload ( > > + OUT UINT32** Payload > > + ) > > +{ > > + EFI_STATUS Status; > > + MTL_CHANNEL *Channel; > > + > > + // Get handle to the Channel. > > + Status =3D MtlGetChannel (MTL_CHANNEL_TYPE_LOW, &Channel); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + // Payload will not be populated until channel is free. > > + Status =3D MtlWaitUntilChannelFree (Channel, RESPONSE_TIMEOUT); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + // Get the address of the payload. > > + *Payload =3D MtlGetChannelPayload (Channel); > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** Execute a SCMI command and receive a response. > > + > > + This function uses a MTL channel to transfer message to SCP > > + and waits for a response. > > + > > + @param[in] Command Pointer to the SCMI command (Protocol ID > > + and Message ID) > > + > > + @param[in,out] PayloadLength SCMI command message length. > > + > > + @param[out] OPTIONAL ReturnValues Pointer to SCMI response. > > + > > + @retval OUT EFI_SUCCESS Command sent and message received > successfully. > > + @retval OUT EFI_UNSUPPORTED Channel not supported. > > + @retval OUT EFI_TIMEOUT Timeout on the channel. > > + @retval OUT EFI_DEVICE_ERROR Channel not ready. > > + @retval OUT EFI_DEVICE_ERROR Message Header corrupted. > > + @retval OUT EFI_DEVICE_ERROR SCMI error. > > +**/ > > +EFI_STATUS > > +ScmiCommandExecute ( > > + IN SCMI_COMMAND *Command, > > + IN OUT UINT32 *PayloadLength, > > + OUT UINT32 **ReturnValues OPTIONAL > > + ) > > +{ > > + EFI_STATUS Status; > > + SCMI_MESSAGE_RESPONSE *Response; > > + UINT32 MessageHeader; > > + UINT32 ResponseHeader; > > + MTL_CHANNEL *Channel; > > + > > + ASSERT (PayloadLength !=3D NULL); > > + > > + Status =3D MtlGetChannel (MTL_CHANNEL_TYPE_LOW, &Channel); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + // Fill in message header. > > + MessageHeader =3D SCMI_MESSAGE_HEADER ( > > + Command->MessageId, > > + SCMI_MESSAGE_TYPE_COMMAND, > > + Command->ProtocolId > > + ); > > + > > + // Send payload using MTL channel. > > + Status =3D MtlSendMessage ( > > + Channel, > > + MessageHeader, > > + *PayloadLength > > + ); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + // Wait for the response on the channel. > > + Status =3D MtlReceiveMessage (Channel, &ResponseHeader, > PayloadLength); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + // SCMI must return MessageHeader unmodified. > > + if (MessageHeader !=3D ResponseHeader) { > > + ASSERT (FALSE); > > + return EFI_DEVICE_ERROR; > > + } > > + > > + Response =3D (SCMI_MESSAGE_RESPONSE*)MtlGetChannelPayload > (Channel); > > + > > + if (Response->Status !=3D SCMI_SUCCESS) { > > + DEBUG ((DEBUG_ERROR, "SCMI error: ProtocolId =3D 0x%x, MessageId = =3D > 0x%x, error =3D %d\n", > > + Command->ProtocolId, > > + Command->MessageId, > > + Response->Status > > + )); > > + > > + ASSERT (FALSE); > > + return EFI_DEVICE_ERROR; > > + } > > + > > + if (ReturnValues !=3D NULL) { > > + *ReturnValues =3D Response->ReturnValues; > > + } > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** Internal common function useful for common protocol discovery > messages. > > + > > + @param[in] ProtocolId Protocol Id of the the protocol. > > + @param[in] MesaageId Message Id of the message. > > + > > + @param[out] ReturnValues SCMI response return values. > > + > > + @retval EFI_SUCCESS Success with valid return values. > > + @retval EFI_DEVICE_ERROR SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +STATIC > > +EFI_STATUS > > +ScmiProtocolDiscoveryCommon ( > > + IN SCMI_PROTOCOL_ID ProtocolId, > > + IN SCMI_MESSAGE_ID MessageId, > > + OUT UINT32 **ReturnValues > > + ) > > +{ > > + SCMI_COMMAND Command; > > + UINT32 PayloadLength =3D 0; > > + > > + Command.ProtocolId =3D ProtocolId; > > + Command.MessageId =3D MessageId; > > + > > + return ScmiCommandExecute ( > > + &Command, > > + &PayloadLength, > > + ReturnValues > > + ); > > +} > > + > > +/** Return protocol version from SCP for a given protocol ID. > > + > > + @param[in] Protocol ID Protocol ID. > > + @param[out] Version Pointer to version of the protocol. > > + > > + @retval EFI_SUCCESS Version holds a valid version received > > + from the SCP. > > + @retval EFI_DEVICE_ERROR SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +EFI_STATUS > > +ScmiGetProtocolVersion ( > > + IN SCMI_PROTOCOL_ID ProtocolId, > > + OUT UINT32 *Version > > + ) > > +{ > > + EFI_STATUS Status; > > + UINT32 *ProtocolVersion; > > + > > + Status =3D ScmiProtocolDiscoveryCommon ( > > + ProtocolId, > > + SCMI_MESSAGE_ID_PROTOCOL_VERSION, > > + (UINT32**)&ProtocolVersion > > + ); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + *Version =3D *ProtocolVersion; > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** Return protocol attributes from SCP for a given protocol ID. > > + > > + @param[in] Protocol ID Protocol ID. > > + @param[out] ReturnValues Pointer to attributes of the protocol. > > + > > + @retval EFI_SUCCESS ReturnValues points to protocol attributes= . > > + @retval EFI_DEVICE_ERROR SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +EFI_STATUS > > +ScmiGetProtocolAttributes ( > > + IN SCMI_PROTOCOL_ID ProtocolId, > > + OUT UINT32 **ReturnValues > > + ) > > +{ > > + return ScmiProtocolDiscoveryCommon ( > > + ProtocolId, > > + SCMI_MESSAGE_ID_PROTOCOL_ATTRIBUTES, > > + ReturnValues > > + ); > > +} > > + > > +/** Return protocol message attributes from SCP for a given protocol I= D. > > + > > + @param[in] Protocol ID Protocol ID. > > + @param[out] Attributes Pointer to attributes of the protocol. > > + > > + @retval EFI_SUCCESS ReturnValues points to protocol message > attributes. > > + @retval EFI_DEVICE_ERROR SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +EFI_STATUS > > +ScmiGetProtocolMessageAttributes ( > > + IN SCMI_PROTOCOL_ID ProtocolId, > > + OUT UINT32 **ReturnValues > > + ) > > +{ > > + return ScmiProtocolDiscoveryCommon ( > > + ProtocolId, > > + SCMI_MESSAGE_ID_PROTOCOL_MESSAGE_ATTRIBUTES, > > + ReturnValues > > + ); > > +} > > diff --git a/ArmPkg/Drivers/ArmScmiDxe/ScmiBaseProtocol.c > b/ArmPkg/Drivers/ArmScmiDxe/ScmiBaseProtocol.c > > new file mode 100644 > > index > 0000000000000000000000000000000000000000..0829438c82ec5723cfbbf9c411 > d10fcf22a22d89 > > --- /dev/null > > +++ b/ArmPkg/Drivers/ArmScmiDxe/ScmiBaseProtocol.c > > @@ -0,0 +1,318 @@ > > +/** @file > > + > > + Copyright (c) 2017-2018, Arm Limited. All rights reserved. > > + > > + This program and the accompanying materials > > + are licensed and made available under the terms and conditions of th= e > BSD License > > + which accompanies this distribution. The full text of the license m= ay be > found at > > + http://opensource.org/licenses/bsd-license.php > > + > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > > + > > + System Control and Management Interface V1.0 > > + http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ > > + DEN0056A_System_Control_and_Management_Interface.pdf > > +**/ > > + > > +#include > > +#include > > +#include > > +#include > > + > > +#include "ArmScmiBaseProtocolPrivate.h" > > +#include "ScmiPrivate.h" > > + > > +/** Return version of the Base protocol supported by SCP firmware. > > + > > + @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. > > + > > + @param[out] Version Version of the supported SCMI Base protocol. > > + > > + @retval EFI_SUCCESS The version of the protocol is returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +STATIC > > +EFI_STATUS > > +BaseGetVersion ( > > + IN SCMI_BASE_PROTOCOL *This, > > + OUT UINT32 *Version > > + ) > > +{ > > + return ScmiGetProtocolVersion (SCMI_PROTOCOL_ID_BASE, Version); > > +} > > + > > +/** Return total number of SCMI protocols supported by the SCP > firmware. > > + > > + @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. > > + > > + @param[out] TotalProtocols Total number of SCMI protocols supported. > > + > > + @retval EFI_SUCCESS Total number of protocols supported are > returned. > > + @retval EFI_DEVICE_ERROR SCP returns a SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +STATIC > > +EFI_STATUS > > +BaseGetTotalProtocols ( > > + IN SCMI_BASE_PROTOCOL *This, > > + OUT UINT32 *TotalProtocols > > + ) > > +{ > > + EFI_STATUS Status; > > + UINT32 *ReturnValues; > > + > > + Status =3D ScmiGetProtocolAttributes (SCMI_PROTOCOL_ID_BASE, > &ReturnValues); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + *TotalProtocols =3D SCMI_TOTAL_PROTOCOLS (ReturnValues[0]); > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** Common function which returns vendor details. > > + > > + @param[in] MessageId > SCMI_MESSAGE_ID_BASE_DISCOVER_VENDOR > > + OR > > + SCMI_MESSAGE_ID_BASE_DISCOVER_SUB_VENDOR > > + > > + @param[out] VendorIdentifier ASCII name of the vendor/subvendor. > > + > > + @retval EFI_SUCCESS VendorIdentifier is returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +STATIC > > +EFI_STATUS > > +BaseDiscoverVendorDetails ( > > + IN SCMI_MESSAGE_ID_BASE MessageId, > > + OUT UINT8 VendorIdentifier[SCMI_MAX_STR_LEN] > > + ) > > +{ > > + EFI_STATUS Status; > > + UINT32 *ReturnValues; > > + SCMI_COMMAND Cmd; > > + UINT32 PayloadLength; > > + > > + Cmd.ProtocolId =3D SCMI_PROTOCOL_ID_BASE; > > + Cmd.MessageId =3D MessageId; > > + > > + PayloadLength =3D 0; > > + > > + Status =3D ScmiCommandExecute ( > > + &Cmd, > > + &PayloadLength, > > + &ReturnValues > > + ); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + AsciiStrCpyS ( > > + (CHAR8*)VendorIdentifier, > > + SCMI_MAX_STR_LEN, > > + (CONST CHAR8*)ReturnValues > > + ); > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** Return vendor name. > > + > > + @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. > > + > > + @param[out] VendorIdentifier Null terminated ASCII string of up to > > + 16 bytes with a vendor name. > > + > > + @retval EFI_SUCCESS VendorIdentifier is returned. > > + @retval EFI_DEVICE_ERROR SCP returns a SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +STATIC > > +EFI_STATUS > > +BaseDiscoverVendor ( > > + IN SCMI_BASE_PROTOCOL *This, > > + OUT UINT8 VendorIdentifier[SCMI_MAX_STR_LEN] > > + ) > > +{ > > + return BaseDiscoverVendorDetails ( > > + SCMI_MESSAGE_ID_BASE_DISCOVER_VENDOR, > > + VendorIdentifier > > + ); > > +} > > + > > +/** Return sub vendor name. > > + > > + @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. > > + > > + @param[out] VendorIdentifier Null terminated ASCII string of up to > > + 16 bytes with a sub vendor name. > > + > > + @retval EFI_SUCCESS VendorIdentifier is returned. > > + @retval EFI_DEVICE_ERROR SCP returns a SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +EFI_STATUS > > +BaseDiscoverSubVendor ( > > + IN SCMI_BASE_PROTOCOL *This, > > + OUT UINT8 VendorIdentifier[SCMI_MAX_STR_LEN] > > + ) > > +{ > > + return BaseDiscoverVendorDetails ( > > + SCMI_MESSAGE_ID_BASE_DISCOVER_SUB_VENDOR, > > + VendorIdentifier > > + ); > > +} > > + > > +/** Return implementation version. > > + > > + @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. > > + > > + @param[out] ImplementationVersion Vendor specific implementation > version. > > + > > + @retval EFI_SUCCESS Implementation version is returned. > > + @retval EFI_DEVICE_ERROR SCP returns a SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +STATIC > > +EFI_STATUS > > +BaseDiscoverImplVersion ( > > + IN SCMI_BASE_PROTOCOL *This, > > + OUT UINT32 *ImplementationVersion > > + ) > > +{ > > + EFI_STATUS Status; > > + UINT32 *ReturnValues; > > + SCMI_COMMAND Cmd; > > + UINT32 PayloadLength; > > + > > + Cmd.ProtocolId =3D SCMI_PROTOCOL_ID_BASE; > > + Cmd.MessageId =3D > SCMI_MESSAGE_ID_BASE_DISCOVER_IMPLEMENTATION_VERSION; > > + > > + PayloadLength =3D 0; > > + > > + Status =3D ScmiCommandExecute ( > > + &Cmd, > > + &PayloadLength, > > + &ReturnValues > > + ); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + *ImplementationVersion =3D ReturnValues[0]; > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** Return list of protocols. > > + > > + @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. > > + > > + @param[out] ProtocolListSize Size of the ProtocolList. > > + > > + @param[out] ProtocolList Protocol list. > > + > > + @retval EFI_SUCCESS List of protocols is returned. > > + @retval EFI_BUFFER_TOO_SMALL ProtocolListSize is too small for the > result. > > + It has been updated to the size needed= . > > + @retval EFI_DEVICE_ERROR SCP returns a SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +STATIC > > +EFI_STATUS > > +BaseDiscoverListProtocols ( > > + IN SCMI_BASE_PROTOCOL *This, > > + IN OUT UINT32 *ProtocolListSize, > > + OUT UINT8 *ProtocolList > > + ) > > +{ > > + EFI_STATUS Status; > > + UINT32 TotalProtocols; > > + UINT32 *MessageParams; > > + BASE_DISCOVER_LIST *DiscoverList; > > + UINT32 Skip; > > + UINT32 Index; > > + SCMI_COMMAND Cmd; > > + UINT32 PayloadLength; > > + UINT32 RequiredSize; > > + > > + Status =3D BaseGetTotalProtocols (This, &TotalProtocols); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + Status =3D ScmiCommandGetPayload (&MessageParams); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + RequiredSize =3D sizeof (UINT8) * TotalProtocols; > > + if (*ProtocolListSize < RequiredSize) { > > + *ProtocolListSize =3D RequiredSize; > > + return EFI_BUFFER_TOO_SMALL; > > + } > > + > > + Cmd.ProtocolId =3D SCMI_PROTOCOL_ID_BASE; > > + Cmd.MessageId =3D > SCMI_MESSAGE_ID_BASE_DISCOVER_LIST_PROTOCOLS; > > + > > + Skip =3D 0; > > + > > + while (Skip < TotalProtocols) { > > + > > + *MessageParams =3D Skip; > > + > > + // Note PayloadLength is a IN/OUT parameter. > > + PayloadLength =3D sizeof (Skip); > > + > > + Status =3D ScmiCommandExecute ( > > + &Cmd, > > + &PayloadLength, > > + (UINT32**)&DiscoverList > > + ); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + for (Index =3D 0; Index < DiscoverList->NumProtocols; Index++) { > > + ProtocolList[Skip++] =3D DiscoverList->Protocols[Index]; > > + } > > + } > > + > > + *ProtocolListSize =3D RequiredSize; > > + > > + return EFI_SUCCESS; > > +} > > + > > +// Instance of the SCMI Base protocol. > > +STATIC CONST SCMI_BASE_PROTOCOL BaseProtocol =3D { > > + BaseGetVersion, > > + BaseGetTotalProtocols, > > + BaseDiscoverVendor, > > + BaseDiscoverSubVendor, > > + BaseDiscoverImplVersion, > > + BaseDiscoverListProtocols > > +}; > > + > > +/** Initialize Base protocol and install protocol on a given handle. > > + > > + @param[in] Handle Handle to install Base protocol. > > + > > + @retval EFI_SUCCESS Base protocol interface installed > > + successfully. > > +**/ > > +EFI_STATUS > > +ScmiBaseProtocolInit ( > > + IN OUT EFI_HANDLE* Handle > > + ) > > +{ > > + return gBS->InstallMultipleProtocolInterfaces ( > > + Handle, > > + &gArmScmiBaseProtocolGuid, > > + &BaseProtocol, > > + NULL > > + ); > > +} > > diff --git a/ArmPkg/Drivers/ArmScmiDxe/ScmiClockProtocol.c > b/ArmPkg/Drivers/ArmScmiDxe/ScmiClockProtocol.c > > new file mode 100644 > > index > 0000000000000000000000000000000000000000..fe7edd2a8c8b7761fb3008e66 > d192ef1ee1ade2e > > --- /dev/null > > +++ b/ArmPkg/Drivers/ArmScmiDxe/ScmiClockProtocol.c > > @@ -0,0 +1,418 @@ > > +/** @file > > + > > + Copyright (c) 2017-2018, Arm Limited. All rights reserved. > > + > > + This program and the accompanying materials > > + are licensed and made available under the terms and conditions of th= e > BSD License > > + which accompanies this distribution. The full text of the license m= ay be > found at > > + http://opensource.org/licenses/bsd-license.php > > + > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > > + > > + System Control and Management Interface V1.0 > > + http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ > > + DEN0056A_System_Control_and_Management_Interface.pdf > > +**/ > > + > > +#include > > +#include > > +#include > > +#include > > + > > +#include "ArmScmiClockProtocolPrivate.h" > > +#include "ScmiPrivate.h" > > + > > +/** Convert to 64 bit value from two 32 bit words. > > + > > + @param[in] Low Lower 32 bits. > > + @param[in] High Higher 32 bits. > > + > > + @retval UINT64 64 bit value. > > +**/ > > +STATIC > > +UINT64 > > +ConvertTo64Bit ( > > + IN UINT32 Low, > > + IN UINT32 High > > + ) > > +{ > > + return (Low | ((UINT64)High << 32)); > > +} >=20 > Suggestion for future improvement: make this a macro in Base.h > The SIGNATURE_64 macro in there would already benefit from it. >=20 > > + > > +/** Return version of the clock management protocol supported by SCP > firmware. > > + > > + @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance. > > + > > + @param[out] Version Version of the supported SCMI Clock > management protocol. > > + > > + @retval EFI_SUCCESS The version is returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +STATIC > > +EFI_STATUS > > +ClockGetVersion ( > > + IN SCMI_CLOCK_PROTOCOL *This, > > + OUT UINT32 *Version > > + ) > > +{ > > + return ScmiGetProtocolVersion (SCMI_PROTOCOL_ID_CLOCK, Version); > > +} > > + > > +/** Return total number of clock devices supported by the clock > management > > + protocol. > > + > > + @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance. > > + > > + @param[out] TotalClocks Total number of clocks supported. > > + > > + @retval EFI_SUCCESS Total number of clocks supported is return= ed. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +STATIC > > +EFI_STATUS > > +ClockGetTotalClocks ( > > + IN SCMI_CLOCK_PROTOCOL *This, > > + OUT UINT32 *TotalClocks > > + ) > > +{ > > + EFI_STATUS Status; > > + UINT32 *ReturnValues; > > + > > + Status =3D ScmiGetProtocolAttributes (SCMI_PROTOCOL_ID_CLOCK, > &ReturnValues); > > + if (EFI_ERROR (Status)) { > > + return Status; >=20 > Missing space (will add before committing). >=20 > > + } > > + > > + *TotalClocks =3D SCMI_CLOCK_PROTOCOL_TOTAL_CLKS (ReturnValues[0]); > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** Return attributes of a clock device. > > + > > + @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance. > > + @param[in] ClockId Identifier for the clock device. > > + > > + @param[out] Enabled If TRUE, the clock device is enabled. > > + @param[out] ClockAsciiName A NULL terminated ASCII string with the > clock > > + name, of up to 16 bytes. > > + > > + @retval EFI_SUCCESS Clock device attributes are returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +STATIC > > +EFI_STATUS > > +ClockGetClockAttributes ( > > + IN SCMI_CLOCK_PROTOCOL *This, > > + IN UINT32 ClockId, > > + OUT BOOLEAN *Enabled, > > + OUT CHAR8 *ClockAsciiName > > + ) > > +{ > > + EFI_STATUS Status; > > + > > + UINT32 *MessageParams; > > + CLOCK_ATTRIBUTES *ClockAttributes; > > + SCMI_COMMAND Cmd; > > + UINT32 PayloadLength; > > + > > + Status =3D ScmiCommandGetPayload (&MessageParams); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + *MessageParams =3D ClockId; > > + > > + Cmd.ProtocolId =3D SCMI_PROTOCOL_ID_CLOCK; > > + Cmd.MessageId =3D SCMI_MESSAGE_ID_CLOCK_ATTRIBUTES; > > + > > + PayloadLength =3D sizeof (ClockId); > > + > > + Status =3D ScmiCommandExecute ( > > + &Cmd, > > + &PayloadLength, > > + (UINT32**)&ClockAttributes > > + ); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + // TRUE if bit 0 of ClockAttributes->Attributes is set. > > + *Enabled =3D CLOCK_ENABLED (ClockAttributes->Attributes); > > + > > + AsciiStrCpyS ( > > + ClockAsciiName, > > + SCMI_MAX_STR_LEN, > > + (CONST CHAR8*)ClockAttributes->ClockName > > + ); > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** Return list of rates supported by a given clock device. > > + > > + @param[in] This A pointer to SCMI_CLOCK_PROTOCOL Instance. > > + @param[in] ClockId Identifier for the clock device. > > + > > + @param[out] Format SCMI_CLOCK_RATE_FORMAT_DISCRETE: Clock > device > > + supports range of clock rates which are non-= linear. > > + > > + SCMI_CLOCK_RATE_FORMAT_LINEAR: Clock device = supports > > + range of linear clock rates from Min to Max = in steps. > > + > > + @param[out] TotalRates Total number of rates. > > + > > + @param[in,out] RateArraySize Size of the RateArray. > > + > > + @param[out] RateArray List of clock rates. > > + > > + @retval EFI_SUCCESS List of clock rates is returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval EFI_BUFFER_TOO_SMALL RateArraySize is too small for the > result. > > + It has been updated to the size needed. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +STATIC > > +EFI_STATUS > > +ClockDescribeRates ( > > + IN SCMI_CLOCK_PROTOCOL *This, > > + IN UINT32 ClockId, > > + OUT SCMI_CLOCK_RATE_FORMAT *Format, > > + OUT UINT32 *TotalRates, > > + IN OUT UINT32 *RateArraySize, > > + OUT SCMI_CLOCK_RATE *RateArray > > + ) > > +{ > > + EFI_STATUS Status; > > + > > + UINT32 PayloadLength; > > + SCMI_COMMAND Cmd; > > + UINT32 *MessageParams; > > + CLOCK_DESCRIBE_RATES *DescribeRates; > > + CLOCK_RATE_DWORD *Rate; > > + > > + UINT32 RequiredArraySize =3D 0; > > + UINT32 RateIndex =3D 0; > > + UINT32 RateNo; > > + UINT32 RateOffset; > > + > > + *TotalRates =3D 0; > > + > > + Status =3D ScmiCommandGetPayload (&MessageParams); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + Cmd.ProtocolId =3D SCMI_PROTOCOL_ID_CLOCK; > > + Cmd.MessageId =3D SCMI_MESSAGE_ID_CLOCK_DESCRIBE_RATES; > > + > > + *MessageParams++ =3D ClockId; > > + > > + do { > > + > > + *MessageParams =3D RateIndex; > > + > > + // Set Payload length, note PayloadLength is a IN/OUT parameter. > > + PayloadLength =3D sizeof (ClockId) + sizeof (RateIndex); > > + > > + // Execute and wait for response on a SCMI channel. > > + Status =3D ScmiCommandExecute ( > > + &Cmd, > > + &PayloadLength, > > + (UINT32**)&DescribeRates > > + ); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + if (*TotalRates =3D=3D 0) { > > + // In the first iteration we will get number of returned rates a= nd > number > > + // of remaining rates. With this information calculate required = size > > + // for rate array. If provided RateArraySize is less, return an > > + // error. > > + > > + *Format =3D RATE_FORMAT (DescribeRates->NumRatesFlags); > > + > > + *TotalRates =3D NUM_RATES (DescribeRates->NumRatesFlags) > > + + NUM_REMAIN_RATES (DescribeRates->NumRatesFlags); > > + > > + if (*Format =3D=3D SCMI_CLOCK_RATE_FORMAT_DISCRETE) { > > + RequiredArraySize =3D (*TotalRates) * sizeof (UINT64); > > + } else { > > + // We need to return triplet of 64 bit value for each rate > > + RequiredArraySize =3D (*TotalRates) * 3 * sizeof (UINT64); > > + } > > + > > + if (RequiredArraySize > (*RateArraySize)) { > > + *RateArraySize =3D RequiredArraySize; > > + return EFI_BUFFER_TOO_SMALL; > > + } > > + } > > + > > + RateOffset =3D 0; > > + > > + if (*Format =3D=3D SCMI_CLOCK_RATE_FORMAT_DISCRETE) { > > + for (RateNo =3D 0; RateNo < NUM_RATES (DescribeRates- > >NumRatesFlags); RateNo++) { > > + Rate =3D &DescribeRates->Rates[RateOffset++]; > > + // Non-linear discrete rates. > > + RateArray[RateIndex++].Rate =3D ConvertTo64Bit (Rate->Low, Rat= e- > >High); > > + } > > + } else { > > + for (RateNo =3D 0; RateNo < NUM_RATES (DescribeRates- > >NumRatesFlags); RateNo++) { > > + // Linear clock rates from minimum to maximum in steps > > + // Minimum clock rate. > > + Rate =3D &DescribeRates->Rates[RateOffset++]; > > + RateArray[RateIndex].Min =3D ConvertTo64Bit (Rate->Low, Rate->= High); > > + > > + Rate =3D &DescribeRates->Rates[RateOffset++]; > > + // Maximum clock rate. > > + RateArray[RateIndex].Max =3D ConvertTo64Bit (Rate->Low, Rate->= High); > > + > > + Rate =3D &DescribeRates->Rates[RateOffset++]; > > + // Step. > > + RateArray[RateIndex++].Step =3D ConvertTo64Bit (Rate->Low, Rat= e- > >High); > > + } > > + } > > + } while (NUM_REMAIN_RATES (DescribeRates->NumRatesFlags) !=3D 0); > > + > > + // Update RateArraySize with RequiredArraySize. > > + *RateArraySize =3D RequiredArraySize; > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** Get clock rate. > > + > > + @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance. > > + @param[in] ClockId Identifier for the clock device. > > + > > + @param[out] Rate Clock rate. > > + > > + @retval EFI_SUCCESS Clock rate is returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +STATIC > > +EFI_STATUS > > +ClockRateGet ( > > + IN SCMI_CLOCK_PROTOCOL *This, > > + IN UINT32 ClockId, > > + OUT UINT64 *Rate > > + ) > > +{ > > + EFI_STATUS Status; > > + > > + UINT32 *MessageParams; > > + CLOCK_RATE_DWORD *ClockRate; > > + SCMI_COMMAND Cmd; > > + > > + UINT32 PayloadLength; > > + > > + Status =3D ScmiCommandGetPayload (&MessageParams); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + // Fill arguments for clock protocol command. > > + *MessageParams =3D ClockId; > > + > > + Cmd.ProtocolId =3D SCMI_PROTOCOL_ID_CLOCK; > > + Cmd.MessageId =3D SCMI_MESSAGE_ID_CLOCK_RATE_GET; > > + > > + PayloadLength =3D sizeof (ClockId); > > + > > + // Execute and wait for response on a SCMI channel. > > + Status =3D ScmiCommandExecute ( > > + &Cmd, > > + &PayloadLength, > > + (UINT32**)&ClockRate > > + ); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + *Rate =3D ((UINT64)ClockRate->High << 32) | ClockRate->Low; >=20 > Should this not use the helper function? > I could fix that up before committing, but would like confirmation on tha= t. >=20 > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** Set clock rate. > > + > > + @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance. > > + @param[in] ClockId Identifier for the clock device. > > + @param[in] Rate Clock rate. > > + > > + @retval EFI_SUCCESS Clock rate set success. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +STATIC > > +EFI_STATUS > > +ClockRateSet ( > > + IN SCMI_CLOCK_PROTOCOL *This, > > + IN UINT32 ClockId, > > + IN UINT64 Rate > > + ) > > +{ > > + EFI_STATUS Status; > > + CLOCK_RATE_SET_ATTRIBUTES *ClockRateSetAttributes; > > + SCMI_COMMAND Cmd; > > + UINT32 PayloadLength; > > + > > + Status =3D ScmiCommandGetPayload > ((UINT32**)&ClockRateSetAttributes); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + // Fill arguments for clock protocol command. > > + ClockRateSetAttributes->ClockId =3D ClockId; > > + ClockRateSetAttributes->Flags =3D CLOCK_SET_DEFAULT_FLAGS; > > + ClockRateSetAttributes->Rate.Low =3D (UINT32)Rate; > > + ClockRateSetAttributes->Rate.High =3D (UINT32)(Rate >> 32); > > + > > + Cmd.ProtocolId =3D SCMI_PROTOCOL_ID_CLOCK; > > + Cmd.MessageId =3D SCMI_MESSAGE_ID_CLOCK_RATE_SET; > > + > > + PayloadLength =3D sizeof (CLOCK_RATE_SET_ATTRIBUTES); > > + > > + // Execute and wait for response on a SCMI channel. > > + Status =3D ScmiCommandExecute ( > > + &Cmd, > > + &PayloadLength, > > + NULL > > + ); > > + > > + return Status; > > +} > > + > > +// Instance of the SCMI clock management protocol. > > +STATIC CONST SCMI_CLOCK_PROTOCOL ScmiClockProtocol =3D { > > + ClockGetVersion, > > + ClockGetTotalClocks, > > + ClockGetClockAttributes, > > + ClockDescribeRates, > > + ClockRateGet, > > + ClockRateSet > > + }; > > + > > +/** Initialize clock management protocol and install protocol on a giv= en > handle. > > + > > + @param[in] Handle Handle to install clock management pr= otocol. > > + > > + @retval EFI_SUCCESS Clock protocol interface installed su= ccessfully. > > +**/ > > +EFI_STATUS > > +ScmiClockProtocolInit ( > > + IN EFI_HANDLE* Handle > > + ) > > +{ > > + return gBS->InstallMultipleProtocolInterfaces ( > > + Handle, > > + &gArmScmiClockProtocolGuid, > > + &ScmiClockProtocol, > > + NULL > > + ); > > +} > > diff --git a/ArmPkg/Drivers/ArmScmiDxe/ScmiDxe.c > b/ArmPkg/Drivers/ArmScmiDxe/ScmiDxe.c > > new file mode 100644 > > index > 0000000000000000000000000000000000000000..2920c6f6f33c5bb8ac00c903a0 > b199ba5f06f4de > > --- /dev/null > > +++ b/ArmPkg/Drivers/ArmScmiDxe/ScmiDxe.c > > @@ -0,0 +1,138 @@ > > +/** @file > > + > > + Copyright (c) 2017-2018, Arm Limited. All rights reserved. > > + > > + This program and the accompanying materials > > + are licensed and made available under the terms and conditions of th= e > BSD License > > + which accompanies this distribution. The full text of the license m= ay be > found at > > + http://opensource.org/licenses/bsd-license.php > > + > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > > + > > + System Control and Management Interface V1.0 > > + http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ > > + DEN0056A_System_Control_and_Management_Interface.pdf > > +**/ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include "ArmScmiBaseProtocolPrivate.h" > > +#include "ArmScmiClockProtocolPrivate.h" > > +#include "ArmScmiPerformanceProtocolPrivate.h" > > +#include "ScmiDxe.h" > > +#include "ScmiPrivate.h" > > + > > +STATIC CONST SCMI_PROTOCOL_INIT_TABLE > ProtocolInitFxns[MAX_PROTOCOLS] =3D { > > + { ScmiBaseProtocolInit }, > > + { NULL }, > > + { NULL }, > > + { ScmiPerformanceProtocolInit }, > > + { ScmiClockProtocolInit }, > > + { NULL } > > +}; > > + > > +/** ARM SCMI driver entry point function. > > + > > + This function installs the SCMI Base protocol and a list of other > > + protocols is queried using the Base protocol. If protocol is support= ed, > > + driver will call each protocol init function to install the protocol= on > > + the ImageHandle. > > + > > + @param[in] ImageHandle Handle to this EFI Image which will be us= ed > to > > + install Base, Clock and Performance proto= cols. > > + @param[in] SystemTable A pointer to boot time system table. > > + > > + @retval EFI_SUCCESS Driver initalized successfully. > > + @retval EFI_UNSUPPORTED If SCMI base protocol version is not > supported. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +EFI_STATUS > > +EFIAPI > > +ArmScmiDxeEntryPoint ( > > + IN EFI_HANDLE ImageHandle, > > + IN EFI_SYSTEM_TABLE *SystemTable > > + ) > > +{ > > + EFI_STATUS Status; > > + SCMI_BASE_PROTOCOL *BaseProtocol; > > + UINT32 Version; > > + UINT32 Index; > > + UINT32 NumProtocols; > > + UINT32 ProtocolNo; > > + UINT8 SupportedList[MAX_PROTOCOLS]; > > + UINT32 SupportedListSize =3D sizeof (SupportedList); > > + > > + ProtocolNo =3D SCMI_PROTOCOL_ID_BASE & PROTOCOL_ID_MASK; > > + > > + // Every SCMI implementation must implement the base protocol. > > + Status =3D ProtocolInitFxns[ProtocolNo].Init (&ImageHandle); > > + if (EFI_ERROR (Status)) { > > + ASSERT (FALSE); > > + return Status; > > + } > > + > > + Status =3D gBS->LocateProtocol ( > > + &gArmScmiBaseProtocolGuid, > > + NULL, > > + (VOID**)&BaseProtocol > > + ); > > + if (EFI_ERROR (Status)) { > > + ASSERT (FALSE); > > + return Status; > > + } > > + > > + // Get SCMI Base protocol version. > > + Status =3D BaseProtocol->GetVersion (BaseProtocol, &Version); > > + if (EFI_ERROR (Status)) { > > + ASSERT (FALSE); > > + return Status; > > + } > > + > > + if (Version !=3D BASE_PROTOCOL_VERSION) { > > + ASSERT (FALSE); > > + return EFI_UNSUPPORTED; > > + } > > + > > + // Apart from Base protocol, SCMI may implement various other > protocols, > > + // query total protocols implemented by the SCP firmware. > > + NumProtocols =3D 0; > > + Status =3D BaseProtocol->GetTotalProtocols (BaseProtocol, > &NumProtocols); > > + if (EFI_ERROR (Status)) { > > + ASSERT (FALSE); > > + return Status; > > + } > > + > > + ASSERT (NumProtocols !=3D 0); > > + > > + // Get the list of protocols supported by SCP firmware on the platfo= rm. > > + Status =3D BaseProtocol->DiscoverListProtocols ( > > + BaseProtocol, > > + &SupportedListSize, > > + SupportedList > > + ); > > + if (EFI_ERROR (Status)) { > > + ASSERT (FALSE); > > + return Status; > > + } > > + > > + // Install supported protocol on ImageHandle. > > + for (Index =3D 0; Index < NumProtocols; Index++) { > > + ProtocolNo =3D SupportedList[Index] & PROTOCOL_ID_MASK; > > + if (ProtocolInitFxns[ProtocolNo].Init !=3D NULL) { > > + Status =3D ProtocolInitFxns[ProtocolNo].Init (&ImageHandle); > > + if (EFI_ERROR (Status)) { > > + ASSERT (FALSE); > > + return Status; > > + } > > + } > > + } > > + > > + return EFI_SUCCESS; > > +} > > diff --git a/ArmPkg/Drivers/ArmScmiDxe/ScmiDxe.h > b/ArmPkg/Drivers/ArmScmiDxe/ScmiDxe.h > > new file mode 100644 > > index > 0000000000000000000000000000000000000000..29cdde173659c701116b021a3 > c437a92b473e4e5 > > --- /dev/null > > +++ b/ArmPkg/Drivers/ArmScmiDxe/ScmiDxe.h > > @@ -0,0 +1,41 @@ > > +/** @file > > + > > + Copyright (c) 2017-2018, Arm Limited. All rights reserved. > > + > > + This program and the accompanying materials > > + are licensed and made available under the terms and conditions of th= e > BSD License > > + which accompanies this distribution. The full text of the license m= ay be > found at > > + http://opensource.org/licenses/bsd-license.php > > + > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > > + > > + System Control and Management Interface V1.0 > > + http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ > > + DEN0056A_System_Control_and_Management_Interface.pdf > > +**/ > > +#ifndef SCMI_DXE_H_ > > +#define SCMI_DXE_H_ > > + > > +#define MAX_PROTOCOLS 6 > > +#define PROTOCOL_ID_MASK 0xF > > +#define MAX_VENDOR_LEN SCMI_MAX_STR_LEN > > + > > +/** Pointer to protocol initialization function. > > + > > + @param[in] Handle A pointer to the EFI_HANDLE on which the protoco= l > > + interface is to be installed. > > + > > + @retval EFI_SUCCESS Protocol interface installed successfully. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_PROTOCOL_INIT_FXN)( > > + IN EFI_HANDLE *Handle > > + ); > > + > > +typedef struct { > > + SCMI_PROTOCOL_INIT_FXN Init; > > +} SCMI_PROTOCOL_INIT_TABLE; > > + > > +#endif /* SCMI_DXE_H_ */ > > diff --git a/ArmPkg/Drivers/ArmScmiDxe/ScmiPerformanceProtocol.c > b/ArmPkg/Drivers/ArmScmiDxe/ScmiPerformanceProtocol.c > > new file mode 100644 > > index > 0000000000000000000000000000000000000000..ac32442ad838040721fd62faa8 > 06e82184f2b288 > > --- /dev/null > > +++ b/ArmPkg/Drivers/ArmScmiDxe/ScmiPerformanceProtocol.c > > @@ -0,0 +1,457 @@ > > +/** @file > > + > > + Copyright (c) 2017-2018, Arm Limited. All rights reserved. > > + > > + This program and the accompanying materials > > + are licensed and made available under the terms and conditions of th= e > BSD License > > + which accompanies this distribution. The full text of the license m= ay be > found at > > + http://opensource.org/licenses/bsd-license.php > > + > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > > + > > + System Control and Management Interface V1.0 > > + http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ > > + DEN0056A_System_Control_and_Management_Interface.pdf > > +**/ > > + > > +#include > > +#include > > +#include > > + > > +#include "ArmScmiPerformanceProtocolPrivate.h" > > +#include "ScmiPrivate.h" > > + > > +/** Return version of the performance management protocol supported > by SCP. > > + firmware. > > + > > + @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL > Instance. > > + > > + @param[out] Version Version of the supported SCMI performance > management > > + protocol. > > + > > + @retval EFI_SUCCESS The version is returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +STATIC > > +EFI_STATUS > > +PerformanceGetVersion ( > > + IN SCMI_PERFORMANCE_PROTOCOL *This, > > + OUT UINT32 *Version > > + ) > > +{ > > + return ScmiGetProtocolVersion (SCMI_PROTOCOL_ID_PERFORMANCE, > Version); > > +} > > + > > +/** Return protocol attributes of the performance management protocol. > > + > > + @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL > Instance. > > + > > + @param[out] Attributes Protocol attributes. > > + > > + @retval EFI_SUCCESS Protocol attributes are returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +STATIC > > +EFI_STATUS > > +PerformanceGetAttributes ( > > + IN SCMI_PERFORMANCE_PROTOCOL *This, > > + OUT SCMI_PERFORMANCE_PROTOCOL_ATTRIBUTES *Attributes > > + ) > > +{ > > + EFI_STATUS Status; > > + UINT32* ReturnValues; > > + > > + Status =3D ScmiGetProtocolAttributes ( > > + SCMI_PROTOCOL_ID_PERFORMANCE, > > + &ReturnValues > > + ); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + memcpy ( >=20 > Urgh, missed this one on previous passes. > Surely this should be CopyMem? >=20 > > + Attributes, > > + ReturnValues, > > + sizeof (SCMI_PERFORMANCE_PROTOCOL_ATTRIBUTES) > > + ); > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** Return performance domain attributes. > > + > > + @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL > Instance. > > + @param[in] DomainId Identifier for the performance domain. > > + > > + @param[out] Attributes Performance domain attributes. > > + > > + @retval EFI_SUCCESS Domain attributes are returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +STATIC > > +EFI_STATUS > > +PerformanceDomainAttributes ( > > + IN SCMI_PERFORMANCE_PROTOCOL *This, > > + IN UINT32 DomainId, > > + OUT SCMI_PERFORMANCE_DOMAIN_ATTRIBUTES *DomainAttributes > > + ) > > +{ > > + EFI_STATUS Status; > > + UINT32 *MessageParams; > > + UINT32 *ReturnValues; > > + UINT32 PayloadLength; > > + SCMI_COMMAND Cmd; > > + > > + Status =3D ScmiCommandGetPayload (&MessageParams); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + *MessageParams =3D DomainId; > > + > > + Cmd.ProtocolId =3D SCMI_PROTOCOL_ID_PERFORMANCE; > > + Cmd.MessageId =3D > SCMI_MESSAGE_ID_PERFORMANCE_DOMAIN_ATTRIBUTES; > > + > > + PayloadLength =3D sizeof (DomainId); > > + > > + Status =3D ScmiCommandExecute ( > > + &Cmd, > > + &PayloadLength, > > + &ReturnValues > > + ); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + memcpy ( >=20 > CopyMem? >=20 > > + DomainAttributes, > > + ReturnValues, > > + sizeof (SCMI_PERFORMANCE_DOMAIN_ATTRIBUTES) > > + ); > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** Return list of performance domain levels of a given domain. > > + > > + @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL > Instance. > > + @param[in] DomainId Identifier for the performance domain. > > + > > + @param[out] NumLevels Total number of levels a domain can support. > > + > > + @param[in,out] LevelArraySize Size of the performance level array. > > + > > + @param[out] LevelArray Array of the performance levels. > > + > > + @retval EFI_SUCCESS Domain levels are returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval EFI_BUFFER_TOO_SMALL LevelArraySize is too small for the > result. > > + It has been updated to the size needed. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +STATIC > > +EFI_STATUS > > +PerformanceDescribeLevels ( > > + IN SCMI_PERFORMANCE_PROTOCOL *This, > > + IN UINT32 DomainId, > > + OUT UINT32 *NumLevels, > > + IN OUT UINT32 *LevelArraySize, > > + OUT SCMI_PERFORMANCE_LEVEL *LevelArray > > + ) > > +{ > > + EFI_STATUS Status; > > + UINT32 PayloadLength; > > + SCMI_COMMAND Cmd; > > + UINT32* MessageParams; > > + UINT32 LevelIndex; > > + UINT32 RequiredSize; > > + UINT32 LevelNo; > > + UINT32 ReturnNumLevels; > > + UINT32 ReturnRemainNumLevels; > > + > > + PERF_DESCRIBE_LEVELS *Levels; > > + > > + Status =3D ScmiCommandGetPayload (&MessageParams); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + LevelIndex =3D 0; > > + RequiredSize =3D 0; > > + > > + *MessageParams++ =3D DomainId; > > + > > + Cmd.ProtocolId =3D SCMI_PROTOCOL_ID_PERFORMANCE; > > + Cmd.MessageId =3D > SCMI_MESSAGE_ID_PERFORMANCE_DESCRIBE_LEVELS; > > + > > + do { > > + > > + *MessageParams =3D LevelIndex; > > + > > + // Note, PayloadLength is an IN/OUT parameter. > > + PayloadLength =3D sizeof (DomainId) + sizeof (LevelIndex); > > + > > + Status =3D ScmiCommandExecute ( > > + &Cmd, > > + &PayloadLength, > > + (UINT32**)&Levels > > + ); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + ReturnNumLevels =3D NUM_PERF_LEVELS (Levels->NumLevels); > > + ReturnRemainNumLevels =3D NUM_REMAIN_PERF_LEVELS (Levels- > >NumLevels); > > + > > + if (RequiredSize =3D=3D 0) { > > + *NumLevels =3D ReturnNumLevels + ReturnRemainNumLevels; > > + > > + RequiredSize =3D (*NumLevels) * sizeof (SCMI_PERFORMANCE_LEVEL)= ; > > + if (RequiredSize > (*LevelArraySize)) { > > + // Update LevelArraySize with required size. > > + *LevelArraySize =3D RequiredSize; > > + return EFI_BUFFER_TOO_SMALL; > > + } > > + } > > + > > + for (LevelNo =3D 0; LevelNo < ReturnNumLevels; LevelNo++) { > > + memcpy ( >=20 > CopyMem? >=20 > / > Leif >=20 > > + &LevelArray[LevelIndex++], > > + &Levels->PerfLevel[LevelNo], > > + sizeof (SCMI_PERFORMANCE_LEVEL) > > + ); > > + } > > + > > + } while (ReturnRemainNumLevels !=3D 0); > > + > > + *LevelArraySize =3D RequiredSize; > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** Set performance limits of a domain. > > + > > + @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL > Instance. > > + @param[in] DomainId Identifier for the performance domain. > > + @param[in] Limit Performance limit to set. > > + > > + @retval EFI_SUCCESS Performance limits set successfully. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +EFI_STATUS > > +PerformanceLimitsSet ( > > + IN SCMI_PERFORMANCE_PROTOCOL *This, > > + IN UINT32 DomainId, > > + IN SCMI_PERFORMANCE_LIMITS *Limits > > + ) > > +{ > > + EFI_STATUS Status; > > + UINT32 PayloadLength; > > + SCMI_COMMAND Cmd; > > + UINT32 *MessageParams; > > + > > + Status =3D ScmiCommandGetPayload (&MessageParams); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + *MessageParams++ =3D DomainId; > > + *MessageParams++ =3D Limits->RangeMax; > > + *MessageParams =3D Limits->RangeMin; > > + > > + Cmd.ProtocolId =3D SCMI_PROTOCOL_ID_PERFORMANCE; > > + Cmd.MessageId =3D SCMI_MESSAGE_ID_PERFORMANCE_LIMITS_SET; > > + > > + PayloadLength =3D sizeof (DomainId) + sizeof > (SCMI_PERFORMANCE_LIMITS); > > + > > + Status =3D ScmiCommandExecute ( > > + &Cmd, > > + &PayloadLength, > > + NULL > > + ); > > + > > + return Status; > > +} > > + > > +/** Get performance limits of a domain. > > + > > + @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL > Instance. > > + @param[in] DomainId Identifier for the performance domain. > > + > > + @param[out] Limit Performance Limits of the domain. > > + > > + @retval EFI_SUCCESS Performance limits are returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +EFI_STATUS > > +PerformanceLimitsGet ( > > + SCMI_PERFORMANCE_PROTOCOL *This, > > + UINT32 DomainId, > > + SCMI_PERFORMANCE_LIMITS *Limits > > + ) > > +{ > > + EFI_STATUS Status; > > + UINT32 PayloadLength; > > + SCMI_COMMAND Cmd; > > + UINT32 *MessageParams; > > + > > + SCMI_PERFORMANCE_LIMITS *ReturnValues; > > + > > + Status =3D ScmiCommandGetPayload (&MessageParams); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + *MessageParams =3D DomainId; > > + > > + Cmd.ProtocolId =3D SCMI_PROTOCOL_ID_PERFORMANCE; > > + Cmd.MessageId =3D SCMI_MESSAGE_ID_PERFORMANCE_LIMITS_GET; > > + > > + PayloadLength =3D sizeof (DomainId); > > + > > + Status =3D ScmiCommandExecute ( > > + &Cmd, > > + &PayloadLength, > > + (UINT32**)&ReturnValues > > + ); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + Limits->RangeMax =3D ReturnValues->RangeMax; > > + Limits->RangeMin =3D ReturnValues->RangeMin; > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** Set performance level of a domain. > > + > > + @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL > Instance. > > + @param[in] DomainId Identifier for the performance domain. > > + @param[in] Level Performance level of the domain. > > + > > + @retval EFI_SUCCESS Performance level set successfully. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +EFI_STATUS > > +PerformanceLevelSet ( > > + IN SCMI_PERFORMANCE_PROTOCOL *This, > > + IN UINT32 DomainId, > > + IN UINT32 Level > > + ) > > +{ > > + EFI_STATUS Status; > > + UINT32 PayloadLength; > > + SCMI_COMMAND Cmd; > > + UINT32 *MessageParams; > > + > > + Status =3D ScmiCommandGetPayload (&MessageParams); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + *MessageParams++ =3D DomainId; > > + *MessageParams =3D Level; > > + > > + Cmd.ProtocolId =3D SCMI_PROTOCOL_ID_PERFORMANCE; > > + Cmd.MessageId =3D SCMI_MESSAGE_ID_PERFORMANCE_LEVEL_SET; > > + > > + PayloadLength =3D sizeof (DomainId) + sizeof (Level); > > + > > + Status =3D ScmiCommandExecute ( > > + &Cmd, > > + &PayloadLength, > > + NULL > > + ); > > + > > + return Status; > > +} > > + > > +/** Get performance level of a domain. > > + > > + @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL > Instance. > > + @param[in] DomainId Identifier for the performance domain. > > + > > + @param[out] Level Performance level of the domain. > > + > > + @retval EFI_SUCCESS Performance level got successfully. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +EFI_STATUS > > +PerformanceLevelGet ( > > + IN SCMI_PERFORMANCE_PROTOCOL *This, > > + IN UINT32 DomainId, > > + OUT UINT32 *Level > > + ) > > +{ > > + EFI_STATUS Status; > > + UINT32 PayloadLength; > > + SCMI_COMMAND Cmd; > > + UINT32 *ReturnValues; > > + UINT32 *MessageParams; > > + > > + Status =3D ScmiCommandGetPayload (&MessageParams); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + *MessageParams =3D DomainId; > > + > > + Cmd.ProtocolId =3D SCMI_PROTOCOL_ID_PERFORMANCE; > > + Cmd.MessageId =3D SCMI_MESSAGE_ID_PERFORMANCE_LEVEL_GET; > > + > > + PayloadLength =3D sizeof (DomainId); > > + > > + Status =3D ScmiCommandExecute ( > > + &Cmd, > > + &PayloadLength, > > + &ReturnValues > > + ); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + *Level =3D *ReturnValues; > > + > > + return EFI_SUCCESS; > > +} > > + > > +// Instance of the SCMI performance management protocol. > > +STATIC CONST SCMI_PERFORMANCE_PROTOCOL PerformanceProtocol =3D > { > > + PerformanceGetVersion, > > + PerformanceGetAttributes, > > + PerformanceDomainAttributes, > > + PerformanceDescribeLevels, > > + PerformanceLimitsSet, > > + PerformanceLimitsGet, > > + PerformanceLevelSet, > > + PerformanceLevelGet > > +}; > > + > > +/** Initialize performance management protocol and install on a given > Handle. > > + > > + @param[in] Handle Handle to install performance managem= ent > > + protocol. > > + > > + @retval EFI_SUCCESS Performance protocol installed succes= sfully. > > +**/ > > +EFI_STATUS > > +ScmiPerformanceProtocolInit ( > > + IN EFI_HANDLE* Handle > > + ) > > +{ > > + return gBS->InstallMultipleProtocolInterfaces ( > > + Handle, > > + &gArmScmiPerformanceProtocolGuid, > > + &PerformanceProtocol, > > + NULL > > + ); > > +} > > diff --git a/ArmPkg/Drivers/ArmScmiDxe/ScmiPrivate.h > b/ArmPkg/Drivers/ArmScmiDxe/ScmiPrivate.h > > new file mode 100644 > > index > 0000000000000000000000000000000000000000..df03655b8b021fe5fd63ceab0 > dd414906d2fb248 > > --- /dev/null > > +++ b/ArmPkg/Drivers/ArmScmiDxe/ScmiPrivate.h > > @@ -0,0 +1,174 @@ > > +/** @file > > + > > + Copyright (c) 2017-2018, Arm Limited. All rights reserved. > > + > > + This program and the accompanying materials > > + are licensed and made available under the terms and conditions of th= e > BSD License > > + which accompanies this distribution. The full text of the license m= ay be > found at > > + http://opensource.org/licenses/bsd-license.php > > + > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > > + > > + System Control and Management Interface V1.0 > > + http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ > > + DEN0056A_System_Control_and_Management_Interface.pdf > > +**/ > > +#ifndef SCMI_PRIVATE_H_ > > +#define SCMI_PRIVATE_H_ > > + > > +// SCMI protocol IDs. > > +typedef enum { > > + SCMI_PROTOCOL_ID_BASE =3D 0x10, > > + SCMI_PROTOCOL_ID_POWER_DOMAIN =3D 0x11, > > + SCMI_PROTOCOL_ID_SYSTEM_POWER =3D 0x12, > > + SCMI_PROTOCOL_ID_PERFORMANCE =3D 0x13, > > + SCMI_PROTOCOL_ID_CLOCK =3D 0x14, > > + SCMI_PROTOCOL_ID_SENSOR =3D 0x15 > > +} SCMI_PROTOCOL_ID; > > + > > +// SCMI message types. > > +typedef enum { > > + SCMI_MESSAGE_TYPE_COMMAND =3D 0, > > + SCMI_MESSAGE_TYPE_DELAYED_RESPONSE =3D 2, // Skipping 1 is > deliberate. > > + SCMI_MESSAGE_TYPE_NOTIFICATION =3D 3 > > +} SCMI_MESSAGE_TYPE; > > + > > +// SCMI response error codes. > > +typedef enum { > > + SCMI_SUCCESS =3D 0, > > + SCMI_NOT_SUPPORTED =3D -1, > > + SCMI_INVALID_PARAMETERS =3D -2, > > + SCMI_DENIED =3D -3, > > + SCMI_NOT_FOUND =3D -4, > > + SCMI_OUT_OF_RANGE =3D -5, > > + SCMI_BUSY =3D -6, > > + SCMI_COMMS_ERROR =3D -7, > > + SCMI_GENERIC_ERROR =3D -8, > > + SCMI_HARDWARE_ERROR =3D -9, > > + SCMI_PROTOCOL_ERROR =3D -10 > > +} SCMI_STATUS; > > + > > +// SCMI message IDs common to all protocols. > > +typedef enum { > > + SCMI_MESSAGE_ID_PROTOCOL_VERSION =3D 0x0, > > + SCMI_MESSAGE_ID_PROTOCOL_ATTRIBUTES =3D 0x1, > > + SCMI_MESSAGE_ID_PROTOCOL_MESSAGE_ATTRIBUTES =3D 0x2 > > +} SCMI_MESSAGE_ID; > > + > > +// Not defined in SCMI specification but will help to identify a messa= ge. > > +typedef struct { > > + SCMI_PROTOCOL_ID ProtocolId; > > + UINT32 MessageId; > > +} SCMI_COMMAND; > > + > > +#pragma pack(1) > > + > > +// Response to a SCMI command. > > +typedef struct { > > + INT32 Status; > > + UINT32 ReturnValues[]; > > +} SCMI_MESSAGE_RESPONSE; > > + > > +// Message header. MsgId[7:0], MsgType[9:8], ProtocolId[17:10] > > +#define MESSAGE_TYPE_SHIFT 8 > > +#define PROTOCOL_ID_SHIFT 10 > > +#define SCMI_MESSAGE_HEADER(MsgId, MsgType, ProtocolId) ( \ > > + MsgType << MESSAGE_TYPE_SHIFT | \ > > + ProtocolId << PROTOCOL_ID_SHIFT | \ > > + MsgId \ > > + ) > > +// SCMI message header. > > +typedef struct { > > + UINT32 MessageHeader; > > +} SCMI_MESSAGE_HEADER; > > + > > +#pragma pack() > > + > > +/** Return a pointer to the message payload. > > + > > + @param[out] Payload Holds pointer to the message payload. > > + > > + @retval EFI_SUCCESS Payload holds a valid message payload po= inter. > > + @retval EFI_TIMEOUT Time out error if MTL channel is busy. > > + @retval EFI_UNSUPPORTED If MTL channel is unsupported. > > +**/ > > +EFI_STATUS > > +ScmiCommandGetPayload ( > > + OUT UINT32** Payload > > + ); > > + > > +/** Execute a SCMI command and receive a response. > > + > > + This function uses a MTL channel to transfer message to SCP > > + and waits for a response. > > + > > + @param[in] Command Pointer to the SCMI command (Protocol ID > > + and Message ID) > > + > > + @param[in,out] PayloadLength SCMI command message length. > > + > > + @param[out] OPTIONAL ReturnValues Pointer to SCMI response. > > + > > + @retval OUT EFI_SUCCESS Command sent and message received > successfully. > > + @retval OUT EFI_UNSUPPORTED Channel not supported. > > + @retval OUT EFI_TIMEOUT Timeout on the channel. > > + @retval OUT EFI_DEVICE_ERROR Channel not ready. > > + @retval OUT EFI_DEVICE_ERROR Message Header corrupted. > > + @retval OUT EFI_DEVICE_ERROR SCMI error. > > +**/ > > +EFI_STATUS > > +ScmiCommandExecute ( > > + IN SCMI_COMMAND *Command, > > + IN OUT UINT32 *PayloadLength, > > + OUT UINT32 **ReturnValues OPTIONAL > > + ); > > + > > +/** Return protocol version from SCP for a given protocol ID. > > + > > + @param[in] Protocol ID Protocol ID. > > + @param[out] Version Pointer to version of the protocol. > > + > > + @retval EFI_SUCCESS Version holds a valid version received > > + from the SCP. > > + @retval EFI_DEVICE_ERROR SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +EFI_STATUS > > +ScmiGetProtocolVersion ( > > + IN SCMI_PROTOCOL_ID ProtocolId, > > + OUT UINT32 *Version > > + ); > > + > > +/** Return protocol attributes from SCP for a given protocol ID. > > + > > + @param[in] Protocol ID Protocol ID. > > + @param[out] ReturnValues Pointer to attributes of the protocol. > > + > > + @retval EFI_SUCCESS ReturnValues points to protocol attributes= . > > + @retval EFI_DEVICE_ERROR SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +EFI_STATUS > > +ScmiGetProtocolAttributes ( > > + IN SCMI_PROTOCOL_ID ProtocolId, > > + OUT UINT32 **ReturnValues > > + ); > > + > > +/** Return protocol message attributes from SCP for a given protocol I= D. > > + > > + @param[in] Protocol ID Protocol ID. > > + > > + @param[out] Attributes Pointer to attributes of the protocol. > > + > > + @retval EFI_SUCCESS ReturnValues points to protocol message > attributes. > > + @retval EFI_DEVICE_ERROR SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +EFI_STATUS > > +ScmiGetProtocolMessageAttributes ( > > + IN SCMI_PROTOCOL_ID ProtocolId, > > + OUT UINT32 **ReturnValues > > + ); > > + > > +#endif /* SCMI_PRIVATE_H_ */ > > diff --git a/ArmPkg/Include/Protocol/ArmScmi.h > b/ArmPkg/Include/Protocol/ArmScmi.h > > new file mode 100644 > > index > 0000000000000000000000000000000000000000..239abb97064578c949614f79a6 > a33fe1881c3c68 > > --- /dev/null > > +++ b/ArmPkg/Include/Protocol/ArmScmi.h > > @@ -0,0 +1,27 @@ > > +/** @file > > + > > + Copyright (c) 2017-2018, Arm Limited. All rights reserved. > > + > > + This program and the accompanying materials > > + are licensed and made available under the terms and conditions of th= e > BSD License > > + which accompanies this distribution. The full text of the license m= ay be > found at > > + http://opensource.org/licenses/bsd-license.php > > + > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > > + > > + System Control and Management Interface V1.0 > > + http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ > > + DEN0056A_System_Control_and_Management_Interface.pdf > > +**/ > > + > > +#ifndef ARM_SCMI_H_ > > +#define ARM_SCMI_H_ > > + > > +/* As per SCMI specification, maximum allowed ASCII string length > > + for various return values/parameters of a SCMI message. > > +*/ > > +#define SCMI_MAX_STR_LEN 16 > > + > > +#endif /* ARM_SCMI_H_ */ > > + > > diff --git a/ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h > b/ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h > > new file mode 100644 > > index > 0000000000000000000000000000000000000000..ecc41f2181ecc9f835950ab46c > 7cfd2e476a7073 > > --- /dev/null > > +++ b/ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h > > @@ -0,0 +1,174 @@ > > +/** @file > > + > > + Copyright (c) 2017-2018, Arm Limited. All rights reserved. > > + > > + This program and the accompanying materials > > + are licensed and made available under the terms and conditions of th= e > BSD License > > + which accompanies this distribution. The full text of the license m= ay be > found at > > + http://opensource.org/licenses/bsd-license.php > > + > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > > + > > + System Control and Management Interface V1.0 > > + http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ > > + DEN0056A_System_Control_and_Management_Interface.pdf > > +**/ > > + > > +#ifndef ARM_SCMI_BASE_PROTOCOL_H_ > > +#define ARM_SCMI_BASE_PROTOCOL_H_ > > + > > +#include > > + > > +#define BASE_PROTOCOL_VERSION 0x10000 > > + > > +#define NUM_PROTOCOL_MASK 0xFFU > > +#define NUM_AGENT_MASK 0xFFU > > + > > +#define NUM_AGENT_SHIFT 0x8 > > + > > +/** Returns total number of protocols that are > > + implemented (excluding the Base protocol) > > +*/ > > +#define SCMI_TOTAL_PROTOCOLS(Attr) (Attr & NUM_PROTOCOL_MASK) > > + > > +// Returns total number of agents in the system. > > +#define SCMI_TOTAL_AGENTS(Attr) ((Attr >> NUM_AGENT_SHIFT) & > NUM_AGENT_MASK) > > + > > +#define ARM_SCMI_BASE_PROTOCOL_GUID { \ > > + 0xd7e5abe9, 0x33ab, 0x418e, {0x9f, 0x91, 0x72, 0xda, 0xe2, 0xba, 0x8= e, > 0x2f} \ > > + } > > + > > +extern EFI_GUID gArmScmiBaseProtocolGuid; > > + > > +typedef struct _SCMI_BASE_PROTOCOL SCMI_BASE_PROTOCOL; > > + > > +/** Return version of the Base protocol supported by SCP firmware. > > + > > + @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. > > + > > + @param[out] Version Version of the supported SCMI Base protocol. > > + > > + @retval EFI_SUCCESS The version of the protocol is returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_BASE_GET_VERSION) ( > > + IN SCMI_BASE_PROTOCOL *This, > > + OUT UINT32 *Version > > + ); > > + > > +/** Return total number of SCMI protocols supported by the SCP > firmware. > > + > > + @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. > > + > > + @param[out] TotalProtocols Total number of SCMI protocols supported. > > + > > + @retval EFI_SUCCESS Total number of protocols supported are > returned. > > + @retval EFI_DEVICE_ERROR SCP returns a SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_BASE_GET_TOTAL_PROTOCOLS) ( > > + IN SCMI_BASE_PROTOCOL *This, > > + OUT UINT32 *TotalProtocols > > + ); > > + > > +/** Return vendor name. > > + > > + @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. > > + > > + @param[out] VendorIdentifier Null terminated ASCII string of up to > > + 16 bytes with a vendor name. > > + > > + @retval EFI_SUCCESS VendorIdentifier is returned. > > + @retval EFI_DEVICE_ERROR SCP returns a SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_BASE_DISCOVER_VENDOR) ( > > + IN SCMI_BASE_PROTOCOL *This, > > + OUT UINT8 VendorIdentifier[SCMI_MAX_STR_LEN] > > + ); > > + > > +/** Return sub vendor name. > > + > > + @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. > > + > > + @param[out] VendorIdentifier Null terminated ASCII string of up to > > + 16 bytes with a vendor name. > > + > > + @retval EFI_SUCCESS VendorIdentifier is returned. > > + @retval EFI_DEVICE_ERROR SCP returns a SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_BASE_DISCOVER_SUB_VENDOR) ( > > + IN SCMI_BASE_PROTOCOL *This, > > + OUT UINT8 VendorIdentifier[SCMI_MAX_STR_LEN] > > + ); > > + > > +/** Return implementation version. > > + > > + @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. > > + > > + @param[out] ImplementationVersion Vendor specific implementation > version. > > + > > + @retval EFI_SUCCESS Implementation version is returned. > > + @retval EFI_DEVICE_ERROR SCP returns a SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION) ( > > + IN SCMI_BASE_PROTOCOL *This, > > + OUT UINT32 *ImplementationVersion > > + ); > > + > > +/** Return list of protocols. > > + > > + @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance. > > + > > + @param[out] ProtocolListSize Size of the ProtocolList. > > + > > + @param[out] ProtocolList Protocol list. > > + > > + @retval EFI_SUCCESS List of protocols is returned. > > + @retval EFI_BUFFER_TOO_SMALL ProtocolListSize is too small for the > result. > > + It has been updated to the size needed= . > > + @retval EFI_DEVICE_ERROR SCP returns a SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_BASE_DISCOVER_LIST_PROTOCOLS) ( > > + IN SCMI_BASE_PROTOCOL *This, > > + IN OUT UINT32 *ProtocolListSize, > > + OUT UINT8 *ProtocolList > > + ); > > + > > +// Base protocol. > > +typedef struct _SCMI_BASE_PROTOCOL { > > + SCMI_BASE_GET_VERSION GetVersion; > > + SCMI_BASE_GET_TOTAL_PROTOCOLS GetTotalProtocols; > > + SCMI_BASE_DISCOVER_VENDOR DiscoverVendor; > > + SCMI_BASE_DISCOVER_SUB_VENDOR DiscoverSubVendor; > > + SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION > DiscoverImplementationVersion; > > + SCMI_BASE_DISCOVER_LIST_PROTOCOLS DiscoverListProtocols; > > +} SCMI_BASE_PROTOCOL; > > + > > +// SCMI Message IDs for Base protocol. > > +typedef enum { > > + SCMI_MESSAGE_ID_BASE_DISCOVER_VENDOR =3D 0x3, > > + SCMI_MESSAGE_ID_BASE_DISCOVER_SUB_VENDOR =3D 0x4, > > + SCMI_MESSAGE_ID_BASE_DISCOVER_IMPLEMENTATION_VERSION =3D > 0x5, > > + SCMI_MESSAGE_ID_BASE_DISCOVER_LIST_PROTOCOLS =3D 0x6 > > +} SCMI_MESSAGE_ID_BASE; > > + > > +#endif /* ARM_SCMI_BASE_PROTOCOL_H_ */ > > + > > diff --git a/ArmPkg/Include/Protocol/ArmScmiClockProtocol.h > b/ArmPkg/Include/Protocol/ArmScmiClockProtocol.h > > new file mode 100644 > > index > 0000000000000000000000000000000000000000..3db26cb0641c7377c022a8e00 > be9a51ee5dc7361 > > --- /dev/null > > +++ b/ArmPkg/Include/Protocol/ArmScmiClockProtocol.h > > @@ -0,0 +1,218 @@ > > +/** @file > > + > > + Copyright (c) 2017-2018, Arm Limited. All rights reserved. > > + > > + This program and the accompanying materials > > + are licensed and made available under the terms and conditions of th= e > BSD License > > + which accompanies this distribution. The full text of the license m= ay be > found at > > + http://opensource.org/licenses/bsd-license.php > > + > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > > + > > + System Control and Management Interface V1.0 > > + http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ > > + DEN0056A_System_Control_and_Management_Interface.pdf > > +**/ > > + > > +#ifndef ARM_SCMI_CLOCK_PROTOCOL_H_ > > +#define ARM_SCMI_CLOCK_PROTOCOL_H_ > > + > > +#include > > + > > +#define ARM_SCMI_CLOCK_PROTOCOL_GUID { \ > > + 0x91ce67a8, 0xe0aa, 0x4012, {0xb9, 0x9f, 0xb6, 0xfc, 0xf3, 0x4, 0x8e= , 0xaa} > \ > > + } > > + > > +extern EFI_GUID gArmScmiClockProtocolGuid; > > + > > +// Message Type for clock management protocol. > > +typedef enum { > > + SCMI_MESSAGE_ID_CLOCK_ATTRIBUTES =3D 0x3, > > + SCMI_MESSAGE_ID_CLOCK_DESCRIBE_RATES =3D 0x4, > > + SCMI_MESSAGE_ID_CLOCK_RATE_SET =3D 0x5, > > + SCMI_MESSAGE_ID_CLOCK_RATE_GET =3D 0x6, > > + SCMI_MESSAGE_ID_CLOCK_CONFIG_SET =3D 0x7 > > +} SCMI_MESSAGE_ID_CLOCK; > > + > > +typedef enum { > > + SCMI_CLOCK_RATE_FORMAT_DISCRETE, // Non-linear range. > > + SCMI_CLOCK_RATE_FORMAT_LINEAR // Linear range. > > +} SCMI_CLOCK_RATE_FORMAT; > > + > > +// Clock management protocol version. > > +#define SCMI_CLOCK_PROTOCOL_VERSION 0x10000 > > + > > +#define SCMI_CLOCK_PROTOCOL_PENDING_ASYNC_RATES_MASK > 0xFFU > > +#define SCMI_CLOCK_PROTOCOL_PENDING_ASYNC_RATES_SHIFT 16 > > +#define SCMI_CLOCK_PROTOCOL_NUM_CLOCKS_MASK 0xFFFFU > > + > > +/** Total number of pending asynchronous clock rates changes > > + supported by the SCP, Attr Bits[23:16] > > +*/ > > +#define SCMI_CLOCK_PROTOCOL_MAX_ASYNC_CLK_RATES(Attr) > ( \ > > + (Attr >> > SCMI_CLOCK_PROTOCOL_PENDING_ASYNC_RATES_SHIFT) && \ > > + SCMI_CLOCK_PROTOCOL_PENDING_ASYNC_RATES_MASK) > > + > > +// Total of clock devices supported by the SCP, Attr Bits[15:0] > > +#define SCMI_CLOCK_PROTOCOL_TOTAL_CLKS(Attr) (Attr & > SCMI_CLOCK_PROTOCOL_NUM_CLOCKS_MASK) > > + > > +#pragma pack(1) > > + > > +/* Depending on the format (linear/non-linear) supported by a clock > device > > + either Rate or Min/Max/Step triplet is valid. > > +*/ > > +typedef struct { > > + union { > > + UINT64 Min; > > + UINT64 Rate; > > + }; > > + UINT64 Max; > > + UINT64 Step; > > +} SCMI_CLOCK_RATE; > > + > > +#pragma pack() > > + > > +typedef struct _SCMI_CLOCK_PROTOCOL SCMI_CLOCK_PROTOCOL; > > + > > +// Protocol Interface functions. > > + > > +/** Return version of the clock management protocol supported by SCP > firmware. > > + > > + @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance. > > + > > + @param[out] Version Version of the supported SCMI Clock > management protocol. > > + > > + @retval EFI_SUCCESS The version is returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_CLOCK_GET_VERSION) ( > > + IN SCMI_CLOCK_PROTOCOL *This, > > + OUT UINT32 *Version > > + ); > > + > > +/** Return total number of clock devices supported by the clock > management > > + protocol. > > + > > + @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance. > > + > > + @param[out] TotalClocks Total number of clocks supported. > > + > > + @retval EFI_SUCCESS Total number of clocks supported is return= ed. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_CLOCK_GET_TOTAL_CLOCKS) ( > > + IN SCMI_CLOCK_PROTOCOL *This, > > + OUT UINT32 *TotalClocks > > + ); > > + > > +/** Return attributes of a clock device. > > + > > + @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance. > > + @param[in] ClockId Identifier for the clock device. > > + > > + @param[out] Enabled If TRUE, the clock device is enabled. > > + @param[out] ClockAsciiName A NULL terminated ASCII string with the > clock > > + name, of up to 16 bytes. > > + > > + @retval EFI_SUCCESS Clock device attributes are returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_CLOCK_GET_CLOCK_ATTRIBUTES) ( > > + IN SCMI_CLOCK_PROTOCOL *This, > > + IN UINT32 ClockId, > > + OUT BOOLEAN *Enabled, > > + OUT CHAR8 *ClockAsciiName > > + ); > > + > > +/** Return list of rates supported by a given clock device. > > + > > + @param[in] This A pointer to SCMI_CLOCK_PROTOCOL Instance. > > + @param[in] ClockId Identifier for the clock device. > > + > > + @param[out] Format SCMI_CLOCK_RATE_FORMAT_DISCRETE: Clock > device > > + supports range of clock rates which are non-= linear. > > + > > + SCMI_CLOCK_RATE_FORMAT_LINEAR: Clock device = supports > > + range of linear clock rates from Min to Max = in steps. > > + > > + @param[out] TotalRates Total number of rates. > > + > > + @param[in,out] RateArraySize Size of the RateArray. > > + > > + @param[out] RateArray List of clock rates. > > + > > + @retval EFI_SUCCESS List of clock rates are returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval EFI_BUFFER_TOO_SMALL RateArraySize is too small for the > result. > > + It has been updated to the size needed. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_CLOCK_DESCRIBE_RATES) ( > > + IN SCMI_CLOCK_PROTOCOL *This, > > + IN UINT32 ClockId, > > + OUT SCMI_CLOCK_RATE_FORMAT *Format, > > + OUT UINT32 *TotalRates, > > + IN OUT UINT32 *RateArraySize, > > + OUT SCMI_CLOCK_RATE *RateArray > > + ); > > + > > +/** Get clock rate. > > + > > + @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance. > > + @param[in] ClockId Identifier for the clock device. > > + > > + @param[out] Rate Clock rate. > > + > > + @retval EFI_SUCCESS Clock rate is returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_CLOCK_RATE_GET) ( > > + IN SCMI_CLOCK_PROTOCOL *This, > > + IN UINT32 ClockId, > > + OUT UINT64 *Rate > > + ); > > + > > +/** Set clock rate. > > + > > + @param[in] This A Pointer to SCMI_CLOCK_PROTOCOL Instance. > > + @param[in] ClockId Identifier for the clock device. > > + @param[in] Rate Clock rate. > > + > > + @retval EFI_SUCCESS Clock rate set success. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_CLOCK_RATE_SET) ( > > + IN SCMI_CLOCK_PROTOCOL *This, > > + IN UINT32 ClockId, > > + IN UINT64 Rate > > + ); > > + > > +typedef struct _SCMI_CLOCK_PROTOCOL { > > + SCMI_CLOCK_GET_VERSION GetVersion; > > + SCMI_CLOCK_GET_TOTAL_CLOCKS GetTotalClocks; > > + SCMI_CLOCK_GET_CLOCK_ATTRIBUTES GetClockAttributes; > > + SCMI_CLOCK_DESCRIBE_RATES DescribeRates; > > + SCMI_CLOCK_RATE_GET RateGet; > > + SCMI_CLOCK_RATE_SET RateSet; > > +} SCMI_CLOCK_PROTOCOL; > > + > > +#endif /* ARM_SCMI_CLOCK_PROTOCOL_H_ */ > > + > > diff --git a/ArmPkg/Include/Protocol/ArmScmiPerformanceProtocol.h > b/ArmPkg/Include/Protocol/ArmScmiPerformanceProtocol.h > > new file mode 100644 > > index > 0000000000000000000000000000000000000000..1d1af6f8bee0c00bbe6b47740 > 36c87c988a4f4af > > --- /dev/null > > +++ b/ArmPkg/Include/Protocol/ArmScmiPerformanceProtocol.h > > @@ -0,0 +1,265 @@ > > +/** @file > > + > > + Copyright (c) 2017-2018, Arm Limited. All rights reserved. > > + > > + This program and the accompanying materials > > + are licensed and made available under the terms and conditions of th= e > BSD License > > + which accompanies this distribution. The full text of the license m= ay be > found at > > + http://opensource.org/licenses/bsd-license.php > > + > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > > + > > + System Control and Management Interface V1.0 > > + http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/ > > + DEN0056A_System_Control_and_Management_Interface.pdf > > +**/ > > + > > +#ifndef ARM_SCMI_PERFORMANCE_PROTOCOL_H_ > > +#define ARM_SCMI_PERFORMANCE_PROTOCOL_H_ > > + > > +#include > > + > > +#define PERFORMANCE_PROTOCOL_VERSION 0x10000 > > + > > +#define ARM_SCMI_PERFORMANCE_PROTOCOL_GUID { \ > > + 0x9b8ba84, 0x3dd3, 0x49a6, {0xa0, 0x5a, 0x31, 0x34, 0xa5, 0xf0, 0x7b= , > 0xad} \ > > + } > > + > > +extern EFI_GUID gArmScmiPerformanceProtocolGuid; > > + > > +typedef struct _SCMI_PERFORMANCE_PROTOCOL > SCMI_PERFORMANCE_PROTOCOL; > > + > > +#pragma pack(1) > > + > > +#define POWER_IN_MW_SHIFT 16 > > +#define POWER_IN_MW_MASK 0x1 > > +#define NUM_PERF_DOMAINS_MASK 0xFFFF > > + > > +// Total number of performance domains, Attr Bits [15:0] > > +#define SCMI_PERF_TOTAL_DOMAINS(Attr) (Attr & > NUM_PERF_DOMAINS_MASK) > > + > > +// A flag to express power values in mW or platform specific way, Attr= Bit > [16] > > +#define SCMI_PERF_POWER_IN_MW(Attr) ((Attr >> > POWER_IN_MW_SHIFT) & \ > > + POWER_IN_MW_MASK) > > + > > +// Performance protocol attributes return values. > > +typedef struct { > > + UINT32 Attributes; > > + UINT64 StatisticsAddress; > > + UINT32 StatisticsLen; > > +} SCMI_PERFORMANCE_PROTOCOL_ATTRIBUTES; > > + > > +#define SCMI_PERF_SUPPORT_LVL_CHANGE_NOTIFY(Attr) ((Attr >> 28) > & 0x1) > > +#define SCMI_PERF_SUPPORT_LIM_CHANGE_NOTIFY(Attr) ((Attr >> 29) > & 0x1) > > +#define SCMI_PERF_SUPPORT_SET_LVL(Attr) ((Attr >> 30) & 0x1) > > +#define SCMI_PERF_SUPPORT_SET_LIM(Attr) ((Attr >> 31) & 0x1) > > +#define SCMI_PERF_RATE_LIMIT(RateLimit) (RateLimit & 0xFFF) > > + > > +// Performance protocol domain attributes. > > +typedef struct { > > + UINT32 Attributes; > > + UINT32 RateLimit; > > + UINT32 SustainedFreq; > > + UINT32 SustainedPerfLevel; > > + UINT8 Name[SCMI_MAX_STR_LEN]; > > +} SCMI_PERFORMANCE_DOMAIN_ATTRIBUTES; > > + > > +// Worst case latency in microseconds, Bits[15:0] > > +#define PERF_LATENCY_MASK 0xFFFF > > +#define SCMI_PERFORMANCE_PROTOCOL_LATENCY(Latency) (Latency & > PERF_LATENCY_MASK) > > + > > +// Performance protocol performance level. > > +typedef struct { > > + UINT32 Level; > > + UINT32 PowerCost; > > + UINT32 Latency; > > +} SCMI_PERFORMANCE_LEVEL; > > + > > +// Performance protocol performance limit. > > +typedef struct { > > + UINT32 RangeMax; > > + UINT32 RangeMin; > > +} SCMI_PERFORMANCE_LIMITS; > > + > > +#pragma pack() > > + > > +/** Return version of the performance management protocol supported > by SCP. > > + firmware. > > + > > + @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL > Instance. > > + > > + @param[out] Version Version of the supported SCMI performance > management > > + protocol. > > + > > + @retval EFI_SUCCESS The version is returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_PERFORMANCE_GET_VERSION) ( > > + IN SCMI_PERFORMANCE_PROTOCOL *This, > > + OUT UINT32 *Version > > + ); > > + > > +/** Return protocol attributes of the performance management protocol. > > + > > + @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL > Instance. > > + > > + @param[out] Attributes Protocol attributes. > > + > > + @retval EFI_SUCCESS Protocol attributes are returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_PERFORMANCE_GET_ATTRIBUTES) ( > > + IN SCMI_PERFORMANCE_PROTOCOL *This, > > + OUT SCMI_PERFORMANCE_PROTOCOL_ATTRIBUTES *Attributes > > + > > + ); > > + > > +/** Return performance domain attributes. > > + > > + @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL > Instance. > > + @param[in] DomainId Identifier for the performance domain. > > + > > + @param[out] Attributes Performance domain attributes. > > + > > + @retval EFI_SUCCESS Domain attributes are returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_PERFORMANCE_GET_DOMAIN_ATTRIBUTES) ( > > + IN SCMI_PERFORMANCE_PROTOCOL *This, > > + IN UINT32 DomainId, > > + OUT SCMI_PERFORMANCE_DOMAIN_ATTRIBUTES *DomainAttributes > > + ); > > + > > +/** Return list of performance domain levels of a given domain. > > + > > + @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL > Instance. > > + @param[in] DomainId Identifier for the performance domain. > > + > > + @param[out] NumLevels Total number of levels a domain can support. > > + > > + @param[in,out] LevelArraySize Size of the performance level array. > > + > > + @param[out] LevelArray Array of the performance levels. > > + > > + @retval EFI_SUCCESS Domain levels are returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval EFI_BUFFER_TOO_SMALL LevelArraySize is too small for the > result. > > + It has been updated to the size needed. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_PERFORMANCE_DESCRIBE_LEVELS) ( > > + IN SCMI_PERFORMANCE_PROTOCOL *This, > > + IN UINT32 DomainId, > > + OUT UINT32 *NumLevels, > > + IN OUT UINT32 *LevelArraySize, > > + OUT SCMI_PERFORMANCE_LEVEL *LevelArray > > + ); > > + > > +/** Set performance limits of a domain. > > + > > + @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL > Instance. > > + @param[in] DomainId Identifier for the performance domain. > > + @param[in] Limit Performance limit to set. > > + > > + @retval EFI_SUCCESS Performance limits set successfully. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_PERFORMANCE_LIMITS_SET) ( > > + IN SCMI_PERFORMANCE_PROTOCOL *This, > > + IN UINT32 DomainId, > > + IN SCMI_PERFORMANCE_LIMITS *Limits > > + ); > > + > > +/** Get performance limits of a domain. > > + > > + @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL > Instance. > > + @param[in] DomainId Identifier for the performance domain. > > + > > + @param[out] Limit Performance Limits of the domain. > > + > > + @retval EFI_SUCCESS Performance limits are returned. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_PERFORMANCE_LIMITS_GET) ( > > + SCMI_PERFORMANCE_PROTOCOL *This, > > + UINT32 DomainId, > > + SCMI_PERFORMANCE_LIMITS *Limits > > + ); > > + > > +/** Set performance level of a domain. > > + > > + @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL > Instance. > > + @param[in] DomainId Identifier for the performance domain. > > + @param[in] Level Performance level of the domain. > > + > > + @retval EFI_SUCCESS Performance level set successfully. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_PERFORMANCE_LEVEL_SET) ( > > + IN SCMI_PERFORMANCE_PROTOCOL *This, > > + IN UINT32 DomainId, > > + IN UINT32 Level > > + ); > > + > > +/** Get performance level of a domain. > > + > > + @param[in] This A Pointer to SCMI_PERFORMANCE_PROTOCOL > Instance. > > + @param[in] DomainId Identifier for the performance domain. > > + > > + @param[out] Level Performance level of the domain. > > + > > + @retval EFI_SUCCESS Performance level got successfully. > > + @retval EFI_DEVICE_ERROR SCP returns an SCMI error. > > + @retval !(EFI_SUCCESS) Other errors. > > +**/ > > +typedef > > +EFI_STATUS > > +(EFIAPI *SCMI_PERFORMANCE_LEVEL_GET) ( > > + IN SCMI_PERFORMANCE_PROTOCOL *This, > > + IN UINT32 DomainId, > > + OUT UINT32 *Level > > + ); > > + > > +typedef struct _SCMI_PERFORMANCE_PROTOCOL { > > + SCMI_PERFORMANCE_GET_VERSION GetVersion; > > + SCMI_PERFORMANCE_GET_ATTRIBUTES GetProtocolAttributes; > > + SCMI_PERFORMANCE_GET_DOMAIN_ATTRIBUTES > GetDomainAttributes; > > + SCMI_PERFORMANCE_DESCRIBE_LEVELS DescribeLevels; > > + SCMI_PERFORMANCE_LIMITS_SET LimitsSet; > > + SCMI_PERFORMANCE_LIMITS_GET LimitsGet; > > + SCMI_PERFORMANCE_LEVEL_SET LevelSet; > > + SCMI_PERFORMANCE_LEVEL_GET LevelGet; > > +} SCMI_PERFORMANCE_PROTOCOL; > > + > > +typedef enum { > > + SCMI_MESSAGE_ID_PERFORMANCE_DOMAIN_ATTRIBUTES =3D 0x3, > > + SCMI_MESSAGE_ID_PERFORMANCE_DESCRIBE_LEVELS =3D 0x4, > > + SCMI_MESSAGE_ID_PERFORMANCE_LIMITS_SET =3D 0x5, > > + SCMI_MESSAGE_ID_PERFORMANCE_LIMITS_GET =3D 0x6, > > + SCMI_MESSAGE_ID_PERFORMANCE_LEVEL_SET =3D 0x7, > > + SCMI_MESSAGE_ID_PERFORMANCE_LEVEL_GET =3D 0x8, > > +} SCMI_MESSAGE_ID_PERFORMANCE; > > + > > +#endif /* ARM_SCMI_PERFORMANCE_PROTOCOL_H_ */ > > + > > -- > > 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)' > > > >