From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
To: Evan Lloyd <evan.lloyd@arm.com>
Cc: "edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
<"ard.biesheuvel@linaro.org"@arm.com>,
<"leif.lindholm@linaro.org"@arm.com>,
<"Matteo.Carlini@arm.com"@arm.com>, <"nd@arm.com"@arm.com>
Subject: Re: [PATCH v2 13/13] ArmPlatformPkg: Introduce SCMI protocol
Date: Sat, 23 Dec 2017 14:05:39 +0000 [thread overview]
Message-ID: <CAKv+Gu8pW6nRc6XMQjQtug2+grVS=Qdgt17i3DvLsWHaPZNUEQ@mail.gmail.com> (raw)
In-Reply-To: <20171222183418.8616-14-evan.lloyd@arm.com>
, couOn 22 December 2017 at 18:34, <evan.lloyd@arm.com> wrote:
> From: Girish Pathak <girish.pathak@arm.com>
>
> This change introduces a new SCMI protocol driver for
> Arm Platforms. 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 the HDLCD clock
> on Juno platforms.
>
> Whereas performance management protocol allows adjustment
> of various performance domains to evaluate performance of the
> Juno platform.
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Girish Pathak <girish.pathak@arm.com>
> ---
> ArmPlatformPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf | 48 ++
> ArmPlatformPkg/Drivers/ArmScmiDxe/ArmScmiBaseProtocolPrivate.h | 29 ++
> ArmPlatformPkg/Drivers/ArmScmiDxe/ArmScmiClockProtocolPrivate.h | 69 +++
> ArmPlatformPkg/Drivers/ArmScmiDxe/ArmScmiPerformanceProtocolPrivate.h | 39 ++
> ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiDxe.h | 41 ++
> ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiPrivate.h | 174 ++++++++
> ArmPlatformPkg/Include/Drivers/ArmScmi.h | 27 ++
> ArmPlatformPkg/Include/Drivers/ArmScmiBaseProtocol.h | 182 ++++++++
> ArmPlatformPkg/Include/Drivers/ArmScmiClockProtocol.h | 225 ++++++++++
> ArmPlatformPkg/Include/Drivers/ArmScmiPerformanceProtocol.h | 274 ++++++++++++
> ArmPlatformPkg/Include/Library/ArmMtl.h | 132 ++++++
> ArmPlatformPkg/Drivers/ArmScmiDxe/Scmi.c | 261 +++++++++++
> ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiBaseProtocol.c | 320 ++++++++++++++
> ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiClockProtocol.c | 419 ++++++++++++++++++
> ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiDxe.c | 135 ++++++
> ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiPerformanceProtocol.c | 457 ++++++++++++++++++++
> 16 files changed, 2832 insertions(+)
>
> diff --git a/ArmPlatformPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf b/ArmPlatformPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf
> new file mode 100644
> index 0000000000000000000000000000000000000000..ad7c363c9d6621df36fb7beddff9e2ae28127c52
> --- /dev/null
> +++ b/ArmPlatformPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf
> @@ -0,0 +1,48 @@
> +#/** @file
> +#
> +# Copyright (c) 2017, 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
> + ArmMtl
> + DebugLib
> + IoLib
> + UefiBootServicesTableLib
> + UefiDriverEntryPoint
> +
> +[Depex]
> + TRUE
> +
> diff --git a/ArmPlatformPkg/Drivers/ArmScmiDxe/ArmScmiBaseProtocolPrivate.h b/ArmPlatformPkg/Drivers/ArmScmiDxe/ArmScmiBaseProtocolPrivate.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..88d47b9efb49f02dbadd0b6d76dac7a991df2124
> --- /dev/null
> +++ b/ArmPlatformPkg/Drivers/ArmScmiDxe/ArmScmiBaseProtocolPrivate.h
> @@ -0,0 +1,29 @@
> +/** @file
> +
> + Copyright (c) 2017, 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
> + UINT8 Protocols[];
For paleontological reasons, EDK2 code does not allow arrays of
unspecified length at the end of a struct. I don't know which version
of which toolchain used to be the issue here, and I would be surprised
if anyone went through the trouble of writing that down, but it is the
reason that EDK2 only allows a [1] array, and hence care needs to be
taken to add/substract 1 as appropriate when sizing the variable.
So now, it's my turn to cut /you/ a deal here. If you stop whingeing
about frivolous patches that only move whitespace around or change //
for /*, or move ASSERT()s into if () conditions on cold-as-ice code
paths, I am not going to complain about the arrays of unspecified
length in this patch, simply because I don't take the coding standard
as gospel, and feel that the Tianocore could do with a bit more
pragmatism when it comes to matters like these.
> +} BASE_DISCOVER_LIST;
> +
> +#endif /* ARM_SCMI_BASE_PROTOCOL_PRIVATE_H_ */
> diff --git a/ArmPlatformPkg/Drivers/ArmScmiDxe/ArmScmiClockProtocolPrivate.h b/ArmPlatformPkg/Drivers/ArmScmiDxe/ArmScmiClockProtocolPrivate.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..2807b6b476ac1b8cf821a29ca7a59a78e9188c52
> --- /dev/null
> +++ b/ArmPlatformPkg/Drivers/ArmScmiDxe/ArmScmiClockProtocolPrivate.h
> @@ -0,0 +1,69 @@
> +/** @file
> +
> + Copyright (c) 2017, 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)
> +
> +// 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;
> + CLOCK_RATE_DWORD Rates[];
> +} 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()
> +
> +#endif /* ARM_SCMI_CLOCK_PROTOCOL_PRIVATE_H_ */
> diff --git a/ArmPlatformPkg/Drivers/ArmScmiDxe/ArmScmiPerformanceProtocolPrivate.h b/ArmPlatformPkg/Drivers/ArmScmiDxe/ArmScmiPerformanceProtocolPrivate.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..99fe80ae30bc818edef9125e5e8a2d11322feb41
> --- /dev/null
> +++ b/ArmPlatformPkg/Drivers/ArmScmiDxe/ArmScmiPerformanceProtocolPrivate.h
> @@ -0,0 +1,39 @@
> +/** @file
> +
> + Copyright (c) 2017, 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 <Drivers/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;
> + SCMI_PERFORMANCE_LEVEL PerfLevel[]; // Offset to array of performance levels
> +} PERF_DESCRIBE_LEVELS;
> +
> +#endif /* ARM_SCMI_PERFORMANCE_PROTOCOL_PRIVATE_H_ */
> diff --git a/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiDxe.h b/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiDxe.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..a2ce4bf9022cee79e0486db3cf9b4fdddf481081
> --- /dev/null
> +++ b/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiDxe.h
> @@ -0,0 +1,41 @@
> +/** @file
> +
> + Copyright (c) 2017, 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/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiPrivate.h b/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiPrivate.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..ca3a712c1afd3e3bd25f831f57aab7e6bff1cddb
> --- /dev/null
> +++ b/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiPrivate.h
> @@ -0,0 +1,174 @@
> +/** @file
> +
> + Copyright (c) 2017, 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/ArmPlatformPkg/Include/Drivers/ArmScmi.h b/ArmPlatformPkg/Include/Drivers/ArmScmi.h
Please don't put stuff in Include/Drivers.
Things derived from industry specs belong in Include/IndustryStandard,
but given that this header only defines SCMI_MAX_STR_LEN, could you
move it into the protocol header instead?
> new file mode 100644
> index 0000000000000000000000000000000000000000..04ea3de5b34157ed459ee47440abbcaa7114e93a
> --- /dev/null
> +++ b/ArmPlatformPkg/Include/Drivers/ArmScmi.h
> @@ -0,0 +1,27 @@
> +/** @file
> +
> + Copyright (c) 2017, 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/ArmPlatformPkg/Include/Drivers/ArmScmiBaseProtocol.h b/ArmPlatformPkg/Include/Drivers/ArmScmiBaseProtocol.h
This belongs in Include/Protocol, and needs to be declared in the
package .dec file as well, along with its GUID.
> new file mode 100644
> index 0000000000000000000000000000000000000000..d8fab57fc354f14e79287520f6c8f05eb1eff141
> --- /dev/null
> +++ b/ArmPlatformPkg/Include/Drivers/ArmScmiBaseProtocol.h
> @@ -0,0 +1,182 @@
> +/** @file
> +
> + Copyright (c) 2017, 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 <Drivers/ArmScmi.h>
> +
> +#define BASE_PROTOCOL_VERSION 0x10000
> +
> +#define NUM_PROTOCOL_MASK 0xFFU
> +#define NUM_AGENT_MASK 0xFFU
> +
> +#define NUM_AGENT_SHIFT 0x8
> +
> +// Returns total protocols that are implemented (excluding the Base protocol)
> +#define SCMI_TOTAL_PROTOCOLS(Attr) (Attr & NUM_PROTOCOL_MASK)
> +
> +// Returns 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 } }
> +
Please wrap this line
> +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;
> +
> +/** 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
> + );
> +
This is not part of the protocol so it needs to be moved elsewhere.
> +#endif /* ARM_SCMI_BASE_PROTOCOL_H_ */
> +
> diff --git a/ArmPlatformPkg/Include/Drivers/ArmScmiClockProtocol.h b/ArmPlatformPkg/Include/Drivers/ArmScmiClockProtocol.h
Please move to Include/Protocol as well, and add declaration to the
package file.
> new file mode 100644
> index 0000000000000000000000000000000000000000..a97728e4dfe8efc3cd8dc29dc94987c1cc6c6a80
> --- /dev/null
> +++ b/ArmPlatformPkg/Include/Drivers/ArmScmiClockProtocol.h
> @@ -0,0 +1,225 @@
> +/** @file
> +
> + Copyright (c) 2017, 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 <Drivers/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 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;
> +
> +/** 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
> + );
> +
Please move this into a separate header, it is not part of the protocol.
> +#endif /* ARM_SCMI_CLOCK_PROTOCOL_H_ */
> +
> diff --git a/ArmPlatformPkg/Include/Drivers/ArmScmiPerformanceProtocol.h b/ArmPlatformPkg/Include/Drivers/ArmScmiPerformanceProtocol.h
Same as above
> new file mode 100644
> index 0000000000000000000000000000000000000000..cb4aa6bf71df86cfd7a0dabb354112c5a38c978f
> --- /dev/null
> +++ b/ArmPlatformPkg/Include/Drivers/ArmScmiPerformanceProtocol.h
> @@ -0,0 +1,274 @@
> +/** @file
> +
> + Copyright (c) 2017, 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 <Drivers/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)
> +// Power values expressed in mW, 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;
> +
> +/** 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
> + );
> +
Same as above
> +#endif /* ARM_SCMI_PERFORMANCE_PROTOCOL_H_ */
> +
> diff --git a/ArmPlatformPkg/Include/Library/ArmMtl.h b/ArmPlatformPkg/Include/Library/ArmMtl.h
Please rename to ArmMtlLib, and declare it as a library class in the
package file.
> new file mode 100644
> index 0000000000000000000000000000000000000000..9be65cfa0a1dcf0d984f29e5d95aedf5e0afac2b
> --- /dev/null
> +++ b/ArmPlatformPkg/Include/Library/ArmMtl.h
> @@ -0,0 +1,132 @@
> +/** @file
> +
> + Copyright (c) 2017, 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_MTL_H_
> +#define ARM_MTL_H_
> +
> +// Ideally we don't need packed struct. However we can't rely on compilers
> +#pragma pack(1)
> +
> +typedef struct {
> + UINT32 Reserved1;
> + UINT32 ChannelStatus;
> + UINT64 Reserved2;
> + UINT32 Flags;
> + UINT32 Length;
> + UINT32 MessageHeader;
> + UINT32 Payload[]; // size less object gives offset to payload.
> +} MTL_MAILBOX;
> +
> +#pragma pack()
> +
> +// Channel Type, Low-priority, and High-priority
> +typedef enum {
> + MTL_CHANNEL_TYPE_LOW = 0,
> + MTL_CHANNEL_TYPE_HIGH = 1
> +} MTL_CHANNEL_TYPE;
> +
> +typedef struct {
> + UINT64 PhysicalAddress;
> + UINT32 ModifyMask;
> + UINT32 PreserveMask;
> +} MTL_DOORBELL;
> +
> +typedef struct {
> + MTL_CHANNEL_TYPE ChannelType;
> + MTL_MAILBOX * CONST MailBox;
> + MTL_DOORBELL DoorBell;
> +} MTL_CHANNEL;
> +
> +/** Wait until channel is free.
> +
> + @param[in] Channel Pointer to a channel.
> + @param[in] TimeOutInMicroSeconds Time out in micro seconds.
> +
> + @retval EFI_SUCCESS Channel is free.
> + @retval EFI_TIMOUT Timeout error.
> +**/
> +EFI_STATUS
> +MtlWaitUntilChannelFree (
> + IN MTL_CHANNEL *Channel,
> + IN UINT64 TimeOutInMicroSeconds
> + );
> +
> +/** Return the address of the message payload.
> +
> + @param[in] Channel Pointer to a channel.
> +
> + @retval UINT32* Pointer to the payload.
> +**/
> +UINT32*
> +MtlGetChannelPayload (
> + IN MTL_CHANNEL *Channel
> + );
> +
> +/** Return pointer to a channel for the requested channel type.
> +
> + @param[in] ChannelType ChannelType, Low or High priority channel.
> + MTL_CHANNEL_TYPE_LOW or
> + MTL_CHANNEL_TYPE_HIGH
> +
> + @param[out] Channel Holds pointer to the channel.
> +
> + @retval EFI_SUCCESS Pointer to channel is returned.
> + @retval EFI_UNSUPPORTED Requested channel type not supported.
> +**/
> +EFI_STATUS
> +MtlGetChannel (
> + IN MTL_CHANNEL_TYPE ChannelType,
> + OUT MTL_CHANNEL **Channel
> + );
> +
> +
> +/** Mark the channel busy and ring the doorbell.
> +
> + @param[in] Channel Pointer to a channel.
> + @param[in] MessageHeader Message header.
> +
> + @param[out] PayloadLength Message length.
> +
> + @retval EFI_SUCCESS Message sent successfully.
> + @retval EFI_DEVICE_ERROR Channel is busy.
> +**/
> +EFI_STATUS
> +MtlSendMessage (
> + IN MTL_CHANNEL *Channel,
> + IN UINT32 MessageHeader,
> + OUT UINT32 PayloadLength
> + );
> +
> +/** Wait for a response on a channel.
> +
> + If channel is free after sending message, it implies SCP responded
> + with a response on the channel.
> +
> + @param[in] Channel Pointer to a channel.
> +
> + @retval EFI_SUCCESS Message received successfully.
> + @retval EFI_TIMOUT Timeout error.
> +**/
> +EFI_STATUS
> +MtlReceiveMessage (
> + IN MTL_CHANNEL *Channel,
> + OUT UINT32 *MessageHeader,
> + OUT UINT32 *PayloadLength
> + );
> +
> +#endif /* ARM_MTL_H_ */
> +
> diff --git a/ArmPlatformPkg/Drivers/ArmScmiDxe/Scmi.c b/ArmPlatformPkg/Drivers/ArmScmiDxe/Scmi.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..8abbd90ce7bd5420cf81f89a4680e5563d7af085
> --- /dev/null
> +++ b/ArmPlatformPkg/Drivers/ArmScmiDxe/Scmi.c
> @@ -0,0 +1,261 @@
> +/** @file
> +
> + Copyright (c) 2017, 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/ArmMtl.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/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiBaseProtocol.c b/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiBaseProtocol.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..144df459e9238b5e08c87ad12999a5491679d1fb
> --- /dev/null
> +++ b/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiBaseProtocol.c
> @@ -0,0 +1,320 @@
> +/** @file
> +
> + Copyright (c) 2017, 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 <Drivers/ArmScmiBaseProtocol.h>
> +
> +#include "ArmScmiBaseProtocolPrivate.h"
> +#include "ScmiPrivate.h"
> +
> +EFI_GUID gArmScmiBaseProtocolGuid = ARM_SCMI_BASE_PROTOCOL_GUID;
> +
> +/** 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/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiClockProtocol.c b/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiClockProtocol.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..895f3f6c5dccbd24e98ed73fa08c41a369d83f43
> --- /dev/null
> +++ b/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiClockProtocol.c
> @@ -0,0 +1,419 @@
> +/** @file
> +
> + Copyright (c) 2017, 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 <Drivers/ArmScmiClockProtocol.h>
> +
> +#include "ArmScmiClockProtocolPrivate.h"
> +#include "ScmiPrivate.h"
> +
> +EFI_GUID gArmScmiClockProtocolGuid = ARM_SCMI_CLOCK_PROTOCOL_GUID;
> +
Please remove this, and declare the guid in the .inf file instead
(same applies to other protocols)
> +/** 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));
> +}
> +
> +/** 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;
> + }
> +
> + *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;
> +
> + 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/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiDxe.c b/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiDxe.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..b11d232d7e910f7ed0a165fb4e22e207c2c3e607
> --- /dev/null
> +++ b/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiDxe.c
> @@ -0,0 +1,135 @@
> +/** @file
> +
> + Copyright (c) 2017, 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 <Drivers/ArmScmiBaseProtocol.h>
> +#include <Drivers/ArmScmiClockProtocol.h>
> +#include <Drivers/ArmScmiPerformanceProtocol.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#include "ScmiPrivate.h"
> +#include "ScmiDxe.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/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiPerformanceProtocol.c b/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiPerformanceProtocol.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..3946dc21005430c430605bf60fb40fb99e2a0178
> --- /dev/null
> +++ b/ArmPlatformPkg/Drivers/ArmScmiDxe/ScmiPerformanceProtocol.c
> @@ -0,0 +1,457 @@
> +/** @file
> +
> + Copyright (c) 2017, 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 <Drivers/ArmScmiPerformanceProtocol.h>
> +#include <string.h>
> +
> +#include "ArmScmiPerformanceProtocolPrivate.h"
> +#include "ScmiPrivate.h"
> +
> +EFI_GUID gArmScmiPerformanceProtocolGuid = ARM_SCMI_PERFORMANCE_PROTOCOL_GUID;
> +
> +/** 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 (
> + 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 (
> + 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;
> +
> + 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;
> + }
> +
> + if (RequiredSize == 0) {
> + *NumLevels = NUM_PERF_LEVELS (Levels->NumLevels)
> + + NUM_REMAIN_PERF_LEVELS (Levels->NumLevels);
> + 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 < NUM_PERF_LEVELS (Levels->NumLevels);
> + LevelNo++) {
> + memcpy (
> + &LevelArray[LevelIndex++],
> + &Levels->PerfLevel[LevelNo],
> + sizeof (SCMI_PERFORMANCE_LEVEL)
> + );
> + }
> +
> + } while (NUM_REMAIN_PERF_LEVELS (Levels->NumLevels) != 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
> + );
> +}
> --
> Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")
>
next prev parent reply other threads:[~2017-12-23 14:00 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-22 18:34 [PATCH v2 00/13] ArmPlatformPkg: Update GOP evan.lloyd
2017-12-22 18:34 ` [PATCH v2 01/13] ArmPlatformPkg: Tidy Lcd code: Coding standard evan.lloyd
2017-12-23 13:19 ` Ard Biesheuvel
2018-01-02 15:11 ` Evan Lloyd
2018-01-02 15:21 ` Ard Biesheuvel
2018-01-02 15:21 ` Ard Biesheuvel
2018-01-03 16:06 ` Evan Lloyd
2017-12-22 18:34 ` [PATCH v2 02/13] ArmPlatformPkg: Tidy Lcd code: Updated comments evan.lloyd
2017-12-22 18:34 ` [PATCH v2 03/13] ArmPlatformPkg: PL111 and HDLCD: add const qualifier evan.lloyd
2017-12-23 13:21 ` Ard Biesheuvel
2017-12-22 18:34 ` [PATCH v2 04/13] ArmPlatformPkg: HDLCD and PL111: Update debug ASSERTS evan.lloyd
2017-12-23 13:22 ` Ard Biesheuvel
2017-12-22 18:34 ` [PATCH v2 05/13] ArmPlatformPkg: PL111Lcd: Replace magic number with macro evan.lloyd
2017-12-23 13:24 ` Ard Biesheuvel
2017-12-22 18:34 ` [PATCH v2 06/13] ArmPlatformPkg: Implement LcdIdentify function for HDLCD GOP evan.lloyd
2017-12-23 13:24 ` Ard Biesheuvel
2017-12-22 18:34 ` [PATCH v2 07/13] ArmPlatformPkg: Redefine LcdPlatformGetTimings function evan.lloyd
2017-12-23 13:27 ` Ard Biesheuvel
2017-12-22 18:34 ` [PATCH v2 08/13] ArmPlatformPkg: Add PCD to select pixel format evan.lloyd
2017-12-23 13:29 ` Ard Biesheuvel
2017-12-22 18:34 ` [PATCH v2 09/13] ArmPlatformPkg: PCD to swap red/blue format for HDLCD evan.lloyd
2017-12-23 13:34 ` Ard Biesheuvel
2017-12-22 18:34 ` [PATCH v2 10/13] ArmPlatformPkg: Additional display modes evan.lloyd
2017-12-23 13:35 ` Ard Biesheuvel
2017-12-22 18:34 ` [PATCH v2 11/13] ArmPlatformPkg: Reserving framebuffer at build evan.lloyd
2017-12-23 13:36 ` Ard Biesheuvel
2017-12-22 18:34 ` [PATCH v2 12/13] ArmPlatformPkg: New DP500/DP550/DP650 GOP driver evan.lloyd
2017-12-23 13:44 ` Ard Biesheuvel
2017-12-22 18:34 ` [PATCH v2 13/13] ArmPlatformPkg: Introduce SCMI protocol evan.lloyd
2017-12-23 14:05 ` Ard Biesheuvel [this message]
-- strict thread matches above, loose matches on Subject: below --
2018-01-11 16:33 Evan Lloyd
2018-01-12 13:35 ` Ard Biesheuvel
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='CAKv+Gu8pW6nRc6XMQjQtug2+grVS=Qdgt17i3DvLsWHaPZNUEQ@mail.gmail.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