From: Girish Pathak <Girish.Pathak@arm.com>
To: Leif Lindholm <leif.lindholm@linaro.org>
Cc: "edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
"ard.biesheuvel@linaro.org" <ard.biesheuvel@linaro.org>,
Matteo Carlini <Matteo.Carlini@arm.com>,
Stephanie Hughes-Fitt <Stephanie.Hughes-Fitt@arm.com>,
nd <nd@arm.com>
Subject: Re: [PATCH v3 16/16] ArmPkg: Introduce SCMI protocol
Date: Mon, 23 Apr 2018 16:06:43 +0000 [thread overview]
Message-ID: <AM4PR08MB0995E5B9E1621EDE10F722DFEC890@AM4PR08MB0995.eurprd08.prod.outlook.com> (raw)
In-Reply-To: <20180423113150.6dgqzp23ersamcrh@bivouac.eciton.net>
Hi Leif,
> -----Original Message-----
> From: Leif Lindholm <leif.lindholm@linaro.org>
> Sent: 23 April 2018 12:32
> To: Girish Pathak <Girish.Pathak@arm.com>
> Cc: edk2-devel@lists.01.org; ard.biesheuvel@linaro.org; Matteo Carlini
> <Matteo.Carlini@arm.com>; Stephanie Hughes-Fitt <Stephanie.Hughes-
> Fitt@arm.com>; nd <nd@arm.com>
> Subject: Re: [PATCH v3 16/16] ArmPkg: Introduce SCMI protocol
>
> 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, shall I tidy this up and resubmit the patch series ?
Regards,
Girish
>
> 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 <girish.pathak@arm.com>
> > Signed-off-by: Evan Lloyd <evan.lloyd@arm.com>
> > ---
> >
> > 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 [Girish]
> >
> > - Move ArmScmiDxe to ArmPkg from ArmPlatformPkg [Ard]
> >
> > Done [Girish]
> >
> > - Declare gArmScmiBaseProtocolGuid and similar
> > protocols Guids in ArmPkg.dec [Ard]
> >
> > Done [Girish]
> >
> > - Replace flexible array member [] with [1] [Ard]
> >
> > Done [Girish]
> >
> > - Move protocol init function which are not part of
> > of protocol like ScmiBaseProtocolInit elsewhere [Ard]
> >
> > Done [Girish]
> >
> > - Please don't put stuff in Include/Drivers. [Ard]
> >
> > Moved headers to Include/Protocol. [Girish]
> >
> > 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 = { 0xde371f7c, 0xdec4, 0x4d21, { 0xad, 0xf1, 0x59,
> 0x3a, 0xbc, 0xc1, 0x58, 0x82 } }
> >
> > +[Protocols.common]
> > + ## Arm System Control and Management Interface(SCMI) Base protocol
> > + ## ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h
> > + gArmScmiBaseProtocolGuid = { 0xd7e5abe9, 0x33ab, 0x418e, { 0x9f, 0x91,
> 0x72, 0xda, 0xe2, 0xba, 0x8e, 0x2f } }
> > +
> > + ## Arm System Control and Management Interface(SCMI) Clock
> management protocol
> > + ## ArmPkg/Include/Protocol/ArmScmiClockProtocol.h
> > + gArmScmiClockProtocolGuid = { 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 = { 0x9b8ba84, 0x3dd3, 0x49a6,
> { 0xa0, 0x5a, 0x31, 0x34, 0xa5, 0xf0, 0x7b, 0xad } }
> > +
> > [Ppis]
> > ## Include/Ppi/ArmMpCoreInfo.h
> > gArmMpCoreInfoPpiGuid = { 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.<BR>
> > -# Copyright (c) 2011 - 2015, ARM Ltd. All rights reserved.<BR>
> > +# Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
> > # Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
> > #
> > # 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 the
> 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
> > +**/
> > +
> > +#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 = 1 + (NumProtocols-1)/4
> > +
> > + // NOTE: Since EDK2 does not allow flexible array member [] we declare
> > + // here array of 1 element length. However below is used as a variable
> > + // 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 the
> 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
> > +**/
> > +
> > +#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)
>
> I'll decrease indentation of above line by one unless someone objects?
>
> > +
> > +// Number of remaining rates after a call to the SCP, RatesFlag Bits[31: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 declare
> > + // here array of 1 element length. However below is used as a variable
> > + // 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)
> == 1)
> > +
> > +typedef struct {
> > + UINT32 Attributes;
> > + UINT8 ClockName[SCMI_MAX_STR_LEN];
> > +} CLOCK_ATTRIBUTES;
> > +
> > +#pragma pack()
> > +
> > +/** Initialize clock management protocol and install protocol on a given
> handle.
> > +
> > + @param[in] Handle Handle to install clock management protocol.
> > +
> > + @retval EFI_SUCCESS Clock protocol interface installed successfully.
> > +**/
> > +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 the
> 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 = 0x00010019
> > + BASE_NAME = ArmScmiDxe
> > + FILE_GUID = 9585984C-F027-45E9-AFDF-ADAA6DFAAAC7
> > + MODULE_TYPE = DXE_DRIVER
> > + VERSION_STRING = 1.0
> > + ENTRY_POINT = 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 the
> 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
> > +**/
> > +
> > +#ifndef ARM_SCMI_PERFORMANCE_PROTOCOL_PRIVATE_H_
> > +#define ARM_SCMI_PERFORMANCE_PROTOCOL_PRIVATE_H_
> > +
> > +#include <Protocol/ArmScmiPerformanceProtocol.h>
> > +
> > +// 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, Lvls
> 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 declare
> > + // here array of 1 element length. However below is used as a variable
> > + // 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 management
> > + protocol.
> > +
> > + @retval EFI_SUCCESS Performance protocol installed successfully.
> > +**/
> > +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 the
> 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
> > +**/
> > +
> > +#include <Library/ArmMtlLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +
> > +#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 pointer.
> > + @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 = MtlGetChannel (MTL_CHANNEL_TYPE_LOW, &Channel);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + // Payload will not be populated until channel is free.
> > + Status = MtlWaitUntilChannelFree (Channel, RESPONSE_TIMEOUT);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + // Get the address of the payload.
> > + *Payload = 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 != NULL);
> > +
> > + Status = MtlGetChannel (MTL_CHANNEL_TYPE_LOW, &Channel);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + // Fill in message header.
> > + MessageHeader = SCMI_MESSAGE_HEADER (
> > + Command->MessageId,
> > + SCMI_MESSAGE_TYPE_COMMAND,
> > + Command->ProtocolId
> > + );
> > +
> > + // Send payload using MTL channel.
> > + Status = MtlSendMessage (
> > + Channel,
> > + MessageHeader,
> > + *PayloadLength
> > + );
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + // Wait for the response on the channel.
> > + Status = MtlReceiveMessage (Channel, &ResponseHeader,
> PayloadLength);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + // SCMI must return MessageHeader unmodified.
> > + if (MessageHeader != ResponseHeader) {
> > + ASSERT (FALSE);
> > + return EFI_DEVICE_ERROR;
> > + }
> > +
> > + Response = (SCMI_MESSAGE_RESPONSE*)MtlGetChannelPayload
> (Channel);
> > +
> > + if (Response->Status != SCMI_SUCCESS) {
> > + DEBUG ((DEBUG_ERROR, "SCMI error: ProtocolId = 0x%x, MessageId =
> 0x%x, error = %d\n",
> > + Command->ProtocolId,
> > + Command->MessageId,
> > + Response->Status
> > + ));
> > +
> > + ASSERT (FALSE);
> > + return EFI_DEVICE_ERROR;
> > + }
> > +
> > + if (ReturnValues != NULL) {
> > + *ReturnValues = 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 = 0;
> > +
> > + Command.ProtocolId = ProtocolId;
> > + Command.MessageId = 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 = ScmiProtocolDiscoveryCommon (
> > + ProtocolId,
> > + SCMI_MESSAGE_ID_PROTOCOL_VERSION,
> > + (UINT32**)&ProtocolVersion
> > + );
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + *Version = *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 ID.
> > +
> > + @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 the
> 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
> > +**/
> > +
> > +#include <Library/BaseLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Protocol/ArmScmiBaseProtocol.h>
> > +
> > +#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 = ScmiGetProtocolAttributes (SCMI_PROTOCOL_ID_BASE,
> &ReturnValues);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + *TotalProtocols = 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 = SCMI_PROTOCOL_ID_BASE;
> > + Cmd.MessageId = MessageId;
> > +
> > + PayloadLength = 0;
> > +
> > + Status = 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 = SCMI_PROTOCOL_ID_BASE;
> > + Cmd.MessageId =
> SCMI_MESSAGE_ID_BASE_DISCOVER_IMPLEMENTATION_VERSION;
> > +
> > + PayloadLength = 0;
> > +
> > + Status = ScmiCommandExecute (
> > + &Cmd,
> > + &PayloadLength,
> > + &ReturnValues
> > + );
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + *ImplementationVersion = 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 = BaseGetTotalProtocols (This, &TotalProtocols);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + Status = ScmiCommandGetPayload (&MessageParams);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + RequiredSize = sizeof (UINT8) * TotalProtocols;
> > + if (*ProtocolListSize < RequiredSize) {
> > + *ProtocolListSize = RequiredSize;
> > + return EFI_BUFFER_TOO_SMALL;
> > + }
> > +
> > + Cmd.ProtocolId = SCMI_PROTOCOL_ID_BASE;
> > + Cmd.MessageId =
> SCMI_MESSAGE_ID_BASE_DISCOVER_LIST_PROTOCOLS;
> > +
> > + Skip = 0;
> > +
> > + while (Skip < TotalProtocols) {
> > +
> > + *MessageParams = Skip;
> > +
> > + // Note PayloadLength is a IN/OUT parameter.
> > + PayloadLength = sizeof (Skip);
> > +
> > + Status = ScmiCommandExecute (
> > + &Cmd,
> > + &PayloadLength,
> > + (UINT32**)&DiscoverList
> > + );
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + for (Index = 0; Index < DiscoverList->NumProtocols; Index++) {
> > + ProtocolList[Skip++] = DiscoverList->Protocols[Index];
> > + }
> > + }
> > +
> > + *ProtocolListSize = RequiredSize;
> > +
> > + return EFI_SUCCESS;
> > +}
> > +
> > +// Instance of the SCMI Base protocol.
> > +STATIC CONST SCMI_BASE_PROTOCOL BaseProtocol = {
> > + 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 the
> 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
> > +**/
> > +
> > +#include <Library/BaseLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Protocol/ArmScmiClockProtocol.h>
> > +
> > +#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));
> > +}
>
> Suggestion for future improvement: make this a macro in Base.h
> The SIGNATURE_64 macro in there would already benefit from it.
>
> > +
> > +/** 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 returned.
> > + @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 = ScmiGetProtocolAttributes (SCMI_PROTOCOL_ID_CLOCK,
> &ReturnValues);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
>
> Missing space (will add before committing).
>
> > + }
> > +
> > + *TotalClocks = 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 = ScmiCommandGetPayload (&MessageParams);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + *MessageParams = ClockId;
> > +
> > + Cmd.ProtocolId = SCMI_PROTOCOL_ID_CLOCK;
> > + Cmd.MessageId = SCMI_MESSAGE_ID_CLOCK_ATTRIBUTES;
> > +
> > + PayloadLength = sizeof (ClockId);
> > +
> > + Status = ScmiCommandExecute (
> > + &Cmd,
> > + &PayloadLength,
> > + (UINT32**)&ClockAttributes
> > + );
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > + // TRUE if bit 0 of ClockAttributes->Attributes is set.
> > + *Enabled = 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 = 0;
> > + UINT32 RateIndex = 0;
> > + UINT32 RateNo;
> > + UINT32 RateOffset;
> > +
> > + *TotalRates = 0;
> > +
> > + Status = ScmiCommandGetPayload (&MessageParams);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + Cmd.ProtocolId = SCMI_PROTOCOL_ID_CLOCK;
> > + Cmd.MessageId = SCMI_MESSAGE_ID_CLOCK_DESCRIBE_RATES;
> > +
> > + *MessageParams++ = ClockId;
> > +
> > + do {
> > +
> > + *MessageParams = RateIndex;
> > +
> > + // Set Payload length, note PayloadLength is a IN/OUT parameter.
> > + PayloadLength = sizeof (ClockId) + sizeof (RateIndex);
> > +
> > + // Execute and wait for response on a SCMI channel.
> > + Status = ScmiCommandExecute (
> > + &Cmd,
> > + &PayloadLength,
> > + (UINT32**)&DescribeRates
> > + );
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + if (*TotalRates == 0) {
> > + // In the first iteration we will get number of returned rates and
> number
> > + // of remaining rates. With this information calculate required size
> > + // for rate array. If provided RateArraySize is less, return an
> > + // error.
> > +
> > + *Format = RATE_FORMAT (DescribeRates->NumRatesFlags);
> > +
> > + *TotalRates = NUM_RATES (DescribeRates->NumRatesFlags)
> > + + NUM_REMAIN_RATES (DescribeRates->NumRatesFlags);
> > +
> > + if (*Format == SCMI_CLOCK_RATE_FORMAT_DISCRETE) {
> > + RequiredArraySize = (*TotalRates) * sizeof (UINT64);
> > + } else {
> > + // We need to return triplet of 64 bit value for each rate
> > + RequiredArraySize = (*TotalRates) * 3 * sizeof (UINT64);
> > + }
> > +
> > + if (RequiredArraySize > (*RateArraySize)) {
> > + *RateArraySize = RequiredArraySize;
> > + return EFI_BUFFER_TOO_SMALL;
> > + }
> > + }
> > +
> > + RateOffset = 0;
> > +
> > + if (*Format == SCMI_CLOCK_RATE_FORMAT_DISCRETE) {
> > + for (RateNo = 0; RateNo < NUM_RATES (DescribeRates-
> >NumRatesFlags); RateNo++) {
> > + Rate = &DescribeRates->Rates[RateOffset++];
> > + // Non-linear discrete rates.
> > + RateArray[RateIndex++].Rate = ConvertTo64Bit (Rate->Low, Rate-
> >High);
> > + }
> > + } else {
> > + for (RateNo = 0; RateNo < NUM_RATES (DescribeRates-
> >NumRatesFlags); RateNo++) {
> > + // Linear clock rates from minimum to maximum in steps
> > + // Minimum clock rate.
> > + Rate = &DescribeRates->Rates[RateOffset++];
> > + RateArray[RateIndex].Min = ConvertTo64Bit (Rate->Low, Rate->High);
> > +
> > + Rate = &DescribeRates->Rates[RateOffset++];
> > + // Maximum clock rate.
> > + RateArray[RateIndex].Max = ConvertTo64Bit (Rate->Low, Rate->High);
> > +
> > + Rate = &DescribeRates->Rates[RateOffset++];
> > + // Step.
> > + RateArray[RateIndex++].Step = ConvertTo64Bit (Rate->Low, Rate-
> >High);
> > + }
> > + }
> > + } while (NUM_REMAIN_RATES (DescribeRates->NumRatesFlags) != 0);
> > +
> > + // Update RateArraySize with RequiredArraySize.
> > + *RateArraySize = 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 = ScmiCommandGetPayload (&MessageParams);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + // Fill arguments for clock protocol command.
> > + *MessageParams = ClockId;
> > +
> > + Cmd.ProtocolId = SCMI_PROTOCOL_ID_CLOCK;
> > + Cmd.MessageId = SCMI_MESSAGE_ID_CLOCK_RATE_GET;
> > +
> > + PayloadLength = sizeof (ClockId);
> > +
> > + // Execute and wait for response on a SCMI channel.
> > + Status = ScmiCommandExecute (
> > + &Cmd,
> > + &PayloadLength,
> > + (UINT32**)&ClockRate
> > + );
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + *Rate = ((UINT64)ClockRate->High << 32) | ClockRate->Low;
>
> Should this not use the helper function?
> I could fix that up before committing, but would like confirmation on that.
>
> > +
> > + 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 = ScmiCommandGetPayload
> ((UINT32**)&ClockRateSetAttributes);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + // Fill arguments for clock protocol command.
> > + ClockRateSetAttributes->ClockId = ClockId;
> > + ClockRateSetAttributes->Flags = CLOCK_SET_DEFAULT_FLAGS;
> > + ClockRateSetAttributes->Rate.Low = (UINT32)Rate;
> > + ClockRateSetAttributes->Rate.High = (UINT32)(Rate >> 32);
> > +
> > + Cmd.ProtocolId = SCMI_PROTOCOL_ID_CLOCK;
> > + Cmd.MessageId = SCMI_MESSAGE_ID_CLOCK_RATE_SET;
> > +
> > + PayloadLength = sizeof (CLOCK_RATE_SET_ATTRIBUTES);
> > +
> > + // Execute and wait for response on a SCMI channel.
> > + Status = ScmiCommandExecute (
> > + &Cmd,
> > + &PayloadLength,
> > + NULL
> > + );
> > +
> > + return Status;
> > +}
> > +
> > +// Instance of the SCMI clock management protocol.
> > +STATIC CONST SCMI_CLOCK_PROTOCOL ScmiClockProtocol = {
> > + ClockGetVersion,
> > + ClockGetTotalClocks,
> > + ClockGetClockAttributes,
> > + ClockDescribeRates,
> > + ClockRateGet,
> > + ClockRateSet
> > + };
> > +
> > +/** Initialize clock management protocol and install protocol on a given
> handle.
> > +
> > + @param[in] Handle Handle to install clock management protocol.
> > +
> > + @retval EFI_SUCCESS Clock protocol interface installed successfully.
> > +**/
> > +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 the
> 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
> > +**/
> > +
> > +#include <Base.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Protocol/ArmScmiBaseProtocol.h>
> > +#include <Protocol/ArmScmiClockProtocol.h>
> > +#include <Protocol/ArmScmiPerformanceProtocol.h>
> > +
> > +#include "ArmScmiBaseProtocolPrivate.h"
> > +#include "ArmScmiClockProtocolPrivate.h"
> > +#include "ArmScmiPerformanceProtocolPrivate.h"
> > +#include "ScmiDxe.h"
> > +#include "ScmiPrivate.h"
> > +
> > +STATIC CONST SCMI_PROTOCOL_INIT_TABLE
> ProtocolInitFxns[MAX_PROTOCOLS] = {
> > + { 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 supported,
> > + 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 used
> to
> > + install Base, Clock and Performance protocols.
> > + @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 = sizeof (SupportedList);
> > +
> > + ProtocolNo = SCMI_PROTOCOL_ID_BASE & PROTOCOL_ID_MASK;
> > +
> > + // Every SCMI implementation must implement the base protocol.
> > + Status = ProtocolInitFxns[ProtocolNo].Init (&ImageHandle);
> > + if (EFI_ERROR (Status)) {
> > + ASSERT (FALSE);
> > + return Status;
> > + }
> > +
> > + Status = gBS->LocateProtocol (
> > + &gArmScmiBaseProtocolGuid,
> > + NULL,
> > + (VOID**)&BaseProtocol
> > + );
> > + if (EFI_ERROR (Status)) {
> > + ASSERT (FALSE);
> > + return Status;
> > + }
> > +
> > + // Get SCMI Base protocol version.
> > + Status = BaseProtocol->GetVersion (BaseProtocol, &Version);
> > + if (EFI_ERROR (Status)) {
> > + ASSERT (FALSE);
> > + return Status;
> > + }
> > +
> > + if (Version != 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 = 0;
> > + Status = BaseProtocol->GetTotalProtocols (BaseProtocol,
> &NumProtocols);
> > + if (EFI_ERROR (Status)) {
> > + ASSERT (FALSE);
> > + return Status;
> > + }
> > +
> > + ASSERT (NumProtocols != 0);
> > +
> > + // Get the list of protocols supported by SCP firmware on the platform.
> > + Status = BaseProtocol->DiscoverListProtocols (
> > + BaseProtocol,
> > + &SupportedListSize,
> > + SupportedList
> > + );
> > + if (EFI_ERROR (Status)) {
> > + ASSERT (FALSE);
> > + return Status;
> > + }
> > +
> > + // Install supported protocol on ImageHandle.
> > + for (Index = 0; Index < NumProtocols; Index++) {
> > + ProtocolNo = SupportedList[Index] & PROTOCOL_ID_MASK;
> > + if (ProtocolInitFxns[ProtocolNo].Init != NULL) {
> > + Status = 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 the
> 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
> > +**/
> > +#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 protocol
> > + 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 the
> 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
> > +**/
> > +
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Protocol/ArmScmiPerformanceProtocol.h>
> > +#include <string.h>
> > +
> > +#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 = ScmiGetProtocolAttributes (
> > + SCMI_PROTOCOL_ID_PERFORMANCE,
> > + &ReturnValues
> > + );
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + memcpy (
>
> Urgh, missed this one on previous passes.
> Surely this should be CopyMem?
>
> > + 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 = ScmiCommandGetPayload (&MessageParams);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + *MessageParams = DomainId;
> > +
> > + Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;
> > + Cmd.MessageId =
> SCMI_MESSAGE_ID_PERFORMANCE_DOMAIN_ATTRIBUTES;
> > +
> > + PayloadLength = sizeof (DomainId);
> > +
> > + Status = ScmiCommandExecute (
> > + &Cmd,
> > + &PayloadLength,
> > + &ReturnValues
> > + );
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + memcpy (
>
> CopyMem?
>
> > + 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 = ScmiCommandGetPayload (&MessageParams);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + LevelIndex = 0;
> > + RequiredSize = 0;
> > +
> > + *MessageParams++ = DomainId;
> > +
> > + Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;
> > + Cmd.MessageId =
> SCMI_MESSAGE_ID_PERFORMANCE_DESCRIBE_LEVELS;
> > +
> > + do {
> > +
> > + *MessageParams = LevelIndex;
> > +
> > + // Note, PayloadLength is an IN/OUT parameter.
> > + PayloadLength = sizeof (DomainId) + sizeof (LevelIndex);
> > +
> > + Status = ScmiCommandExecute (
> > + &Cmd,
> > + &PayloadLength,
> > + (UINT32**)&Levels
> > + );
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + ReturnNumLevels = NUM_PERF_LEVELS (Levels->NumLevels);
> > + ReturnRemainNumLevels = NUM_REMAIN_PERF_LEVELS (Levels-
> >NumLevels);
> > +
> > + if (RequiredSize == 0) {
> > + *NumLevels = ReturnNumLevels + ReturnRemainNumLevels;
> > +
> > + RequiredSize = (*NumLevels) * sizeof (SCMI_PERFORMANCE_LEVEL);
> > + if (RequiredSize > (*LevelArraySize)) {
> > + // Update LevelArraySize with required size.
> > + *LevelArraySize = RequiredSize;
> > + return EFI_BUFFER_TOO_SMALL;
> > + }
> > + }
> > +
> > + for (LevelNo = 0; LevelNo < ReturnNumLevels; LevelNo++) {
> > + memcpy (
>
> CopyMem?
>
> /
> Leif
>
> > + &LevelArray[LevelIndex++],
> > + &Levels->PerfLevel[LevelNo],
> > + sizeof (SCMI_PERFORMANCE_LEVEL)
> > + );
> > + }
> > +
> > + } while (ReturnRemainNumLevels != 0);
> > +
> > + *LevelArraySize = 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 = ScmiCommandGetPayload (&MessageParams);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + *MessageParams++ = DomainId;
> > + *MessageParams++ = Limits->RangeMax;
> > + *MessageParams = Limits->RangeMin;
> > +
> > + Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;
> > + Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_LIMITS_SET;
> > +
> > + PayloadLength = sizeof (DomainId) + sizeof
> (SCMI_PERFORMANCE_LIMITS);
> > +
> > + Status = 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 = ScmiCommandGetPayload (&MessageParams);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + *MessageParams = DomainId;
> > +
> > + Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;
> > + Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_LIMITS_GET;
> > +
> > + PayloadLength = sizeof (DomainId);
> > +
> > + Status = ScmiCommandExecute (
> > + &Cmd,
> > + &PayloadLength,
> > + (UINT32**)&ReturnValues
> > + );
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + Limits->RangeMax = ReturnValues->RangeMax;
> > + Limits->RangeMin = 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 = ScmiCommandGetPayload (&MessageParams);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + *MessageParams++ = DomainId;
> > + *MessageParams = Level;
> > +
> > + Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;
> > + Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_LEVEL_SET;
> > +
> > + PayloadLength = sizeof (DomainId) + sizeof (Level);
> > +
> > + Status = 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 = ScmiCommandGetPayload (&MessageParams);
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + *MessageParams = DomainId;
> > +
> > + Cmd.ProtocolId = SCMI_PROTOCOL_ID_PERFORMANCE;
> > + Cmd.MessageId = SCMI_MESSAGE_ID_PERFORMANCE_LEVEL_GET;
> > +
> > + PayloadLength = sizeof (DomainId);
> > +
> > + Status = ScmiCommandExecute (
> > + &Cmd,
> > + &PayloadLength,
> > + &ReturnValues
> > + );
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + *Level = *ReturnValues;
> > +
> > + return EFI_SUCCESS;
> > +}
> > +
> > +// Instance of the SCMI performance management protocol.
> > +STATIC CONST SCMI_PERFORMANCE_PROTOCOL PerformanceProtocol =
> {
> > + 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 management
> > + protocol.
> > +
> > + @retval EFI_SUCCESS Performance protocol installed successfully.
> > +**/
> > +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 the
> 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
> > +**/
> > +#ifndef SCMI_PRIVATE_H_
> > +#define SCMI_PRIVATE_H_
> > +
> > +// SCMI protocol IDs.
> > +typedef enum {
> > + SCMI_PROTOCOL_ID_BASE = 0x10,
> > + SCMI_PROTOCOL_ID_POWER_DOMAIN = 0x11,
> > + SCMI_PROTOCOL_ID_SYSTEM_POWER = 0x12,
> > + SCMI_PROTOCOL_ID_PERFORMANCE = 0x13,
> > + SCMI_PROTOCOL_ID_CLOCK = 0x14,
> > + SCMI_PROTOCOL_ID_SENSOR = 0x15
> > +} SCMI_PROTOCOL_ID;
> > +
> > +// SCMI message types.
> > +typedef enum {
> > + SCMI_MESSAGE_TYPE_COMMAND = 0,
> > + SCMI_MESSAGE_TYPE_DELAYED_RESPONSE = 2, // Skipping 1 is
> deliberate.
> > + SCMI_MESSAGE_TYPE_NOTIFICATION = 3
> > +} SCMI_MESSAGE_TYPE;
> > +
> > +// SCMI response error codes.
> > +typedef enum {
> > + SCMI_SUCCESS = 0,
> > + SCMI_NOT_SUPPORTED = -1,
> > + SCMI_INVALID_PARAMETERS = -2,
> > + SCMI_DENIED = -3,
> > + SCMI_NOT_FOUND = -4,
> > + SCMI_OUT_OF_RANGE = -5,
> > + SCMI_BUSY = -6,
> > + SCMI_COMMS_ERROR = -7,
> > + SCMI_GENERIC_ERROR = -8,
> > + SCMI_HARDWARE_ERROR = -9,
> > + SCMI_PROTOCOL_ERROR = -10
> > +} SCMI_STATUS;
> > +
> > +// SCMI message IDs common to all protocols.
> > +typedef enum {
> > + SCMI_MESSAGE_ID_PROTOCOL_VERSION = 0x0,
> > + SCMI_MESSAGE_ID_PROTOCOL_ATTRIBUTES = 0x1,
> > + SCMI_MESSAGE_ID_PROTOCOL_MESSAGE_ATTRIBUTES = 0x2
> > +} SCMI_MESSAGE_ID;
> > +
> > +// Not defined in SCMI specification but will help to identify a message.
> > +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 pointer.
> > + @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 ID.
> > +
> > + @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 the
> 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
> > +**/
> > +
> > +#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 the
> 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
> > +**/
> > +
> > +#ifndef ARM_SCMI_BASE_PROTOCOL_H_
> > +#define ARM_SCMI_BASE_PROTOCOL_H_
> > +
> > +#include <Protocol/ArmScmi.h>
> > +
> > +#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, 0x8e,
> 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 = 0x3,
> > + SCMI_MESSAGE_ID_BASE_DISCOVER_SUB_VENDOR = 0x4,
> > + SCMI_MESSAGE_ID_BASE_DISCOVER_IMPLEMENTATION_VERSION =
> 0x5,
> > + SCMI_MESSAGE_ID_BASE_DISCOVER_LIST_PROTOCOLS = 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 the
> 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
> > +**/
> > +
> > +#ifndef ARM_SCMI_CLOCK_PROTOCOL_H_
> > +#define ARM_SCMI_CLOCK_PROTOCOL_H_
> > +
> > +#include <Protocol/ArmScmi.h>
> > +
> > +#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 = 0x3,
> > + SCMI_MESSAGE_ID_CLOCK_DESCRIBE_RATES = 0x4,
> > + SCMI_MESSAGE_ID_CLOCK_RATE_SET = 0x5,
> > + SCMI_MESSAGE_ID_CLOCK_RATE_GET = 0x6,
> > + SCMI_MESSAGE_ID_CLOCK_CONFIG_SET = 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 returned.
> > + @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 the
> 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
> > +**/
> > +
> > +#ifndef ARM_SCMI_PERFORMANCE_PROTOCOL_H_
> > +#define ARM_SCMI_PERFORMANCE_PROTOCOL_H_
> > +
> > +#include <Protocol/ArmScmi.h>
> > +
> > +#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 = 0x3,
> > + SCMI_MESSAGE_ID_PERFORMANCE_DESCRIBE_LEVELS = 0x4,
> > + SCMI_MESSAGE_ID_PERFORMANCE_LIMITS_SET = 0x5,
> > + SCMI_MESSAGE_ID_PERFORMANCE_LIMITS_GET = 0x6,
> > + SCMI_MESSAGE_ID_PERFORMANCE_LEVEL_SET = 0x7,
> > + SCMI_MESSAGE_ID_PERFORMANCE_LEVEL_GET = 0x8,
> > +} SCMI_MESSAGE_ID_PERFORMANCE;
> > +
> > +#endif /* ARM_SCMI_PERFORMANCE_PROTOCOL_H_ */
> > +
> > --
> > 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
> >
> >
next prev parent reply other threads:[~2018-04-23 16:06 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-20 16:11 [PATCH v3 00/16] Update GOP Girish Pathak
2018-03-20 16:11 ` [PATCH v3 01/16] ArmPlatformPkg: Rectify line endings of LcdHwNullLib Girish Pathak
2018-03-21 12:53 ` Evan Lloyd
2018-03-20 16:11 ` [PATCH v3 02/16] ArmPlatformPkg: Rectify line endings of LcdPlatformNullLib Girish Pathak
2018-03-21 12:53 ` Evan Lloyd
2018-03-20 16:11 ` [PATCH v3 03/16] ArmPlatformPkg: Tidy Lcd code: Coding standard Girish Pathak
2018-03-21 12:53 ` Evan Lloyd
2018-03-20 16:12 ` [PATCH v3 04/16] ArmPlatformPkg: Tidy Lcd code: Updated comments Girish Pathak
2018-03-21 12:53 ` Evan Lloyd
2018-03-20 16:12 ` [PATCH v3 05/16] ArmPlatformPkg: HDLCD and PL111: Update debug ASSERTS Girish Pathak
2018-03-21 12:53 ` Evan Lloyd
2018-03-20 16:12 ` [PATCH v3 06/16] ArmPlatformPkg: PL111Lcd: Replace magic number with macro Girish Pathak
2018-03-21 12:26 ` Evan Lloyd
2018-03-20 16:12 ` [PATCH v3 07/16] ArmPlatformPkg: PL111Lcd: Combine two writes to LCDControl Girish Pathak
2018-03-21 12:26 ` Evan Lloyd
2018-03-20 16:12 ` [PATCH v3 08/16] ArmPlatformPkg: Implement LcdIdentify function for HDLCD GOP Girish Pathak
2018-03-21 12:26 ` Evan Lloyd
2018-03-20 16:12 ` [PATCH v3 09/16] ArmPlatformPkg: Redefine LcdPlatformGetTimings function Girish Pathak
2018-03-21 12:53 ` Evan Lloyd
2018-03-20 16:12 ` [PATCH v3 10/16] ArmPlatformPkg: Add PCD to select pixel format Girish Pathak
2018-03-21 12:53 ` Evan Lloyd
2018-03-20 16:12 ` [PATCH v3 11/16] ArmPlatformPkg: PCD to swap red/blue format for HDLCD Girish Pathak
2018-03-21 12:53 ` Evan Lloyd
2018-03-20 16:12 ` [PATCH v3 12/16] ArmPlatformPkg: Additional display modes Girish Pathak
2018-03-21 12:54 ` Evan Lloyd
2018-03-20 16:12 ` [PATCH v3 13/16] ArmPlatformPkg: Reserving framebuffer at build Girish Pathak
2018-03-21 12:54 ` Evan Lloyd
2018-03-20 16:12 ` [PATCH v3 14/16] ArmPlatformPkg: New DP500/DP550/DP650 GOP driver Girish Pathak
2018-03-21 12:54 ` Evan Lloyd
2018-04-23 11:07 ` Leif Lindholm
2018-03-20 16:12 ` [PATCH v3 15/16] ArmPkg: MTL Library interface and Null library implementation Girish Pathak
2018-03-21 12:54 ` Evan Lloyd
2018-04-23 11:11 ` Leif Lindholm
2018-03-20 16:12 ` [PATCH v3 16/16] ArmPkg: Introduce SCMI protocol Girish Pathak
2018-03-21 12:54 ` Evan Lloyd
2018-04-23 11:31 ` Leif Lindholm
2018-04-23 16:06 ` Girish Pathak [this message]
2018-04-23 16:22 ` Leif Lindholm
2018-04-23 16:49 ` Girish Pathak
2018-04-23 17:11 ` [PATCH v3 00/16] Update GOP Leif Lindholm
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=AM4PR08MB0995E5B9E1621EDE10F722DFEC890@AM4PR08MB0995.eurprd08.prod.outlook.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox