3 Copyright (c) 2017-2018, Arm Limited. All rights reserved.
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 System Control and Management Interface V1.0
14 http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/
15 DEN0056A_System_Control_and_Management_Interface.pdf
18 #include <Library/ArmMtlLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/MemoryAllocationLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
23 #include "ScmiPrivate.h"
25 // Arbitrary timeout value 20ms.
26 #define RESPONSE_TIMEOUT 20000
28 /** Return a pointer to the message payload.
30 @param[out] Payload Holds pointer to the message payload.
32 @retval EFI_SUCCESS Payload holds a valid message payload pointer.
33 @retval EFI_TIMEOUT Time out error if MTL channel is busy.
34 @retval EFI_UNSUPPORTED If MTL channel is unsupported.
37 ScmiCommandGetPayload (
44 // Get handle to the Channel.
45 Status
= MtlGetChannel (MTL_CHANNEL_TYPE_LOW
, &Channel
);
46 if (EFI_ERROR (Status
)) {
50 // Payload will not be populated until channel is free.
51 Status
= MtlWaitUntilChannelFree (Channel
, RESPONSE_TIMEOUT
);
52 if (EFI_ERROR (Status
)) {
56 // Get the address of the payload.
57 *Payload
= MtlGetChannelPayload (Channel
);
62 /** Execute a SCMI command and receive a response.
64 This function uses a MTL channel to transfer message to SCP
65 and waits for a response.
67 @param[in] Command Pointer to the SCMI command (Protocol ID
70 @param[in,out] PayloadLength SCMI command message length.
72 @param[out] OPTIONAL ReturnValues Pointer to SCMI response.
74 @retval OUT EFI_SUCCESS Command sent and message received successfully.
75 @retval OUT EFI_UNSUPPORTED Channel not supported.
76 @retval OUT EFI_TIMEOUT Timeout on the channel.
77 @retval OUT EFI_DEVICE_ERROR Channel not ready.
78 @retval OUT EFI_DEVICE_ERROR Message Header corrupted.
79 @retval OUT EFI_DEVICE_ERROR SCMI error.
83 IN SCMI_COMMAND
*Command
,
84 IN OUT UINT32
*PayloadLength
,
85 OUT UINT32
**ReturnValues OPTIONAL
89 SCMI_MESSAGE_RESPONSE
*Response
;
91 UINT32 ResponseHeader
;
94 ASSERT (PayloadLength
!= NULL
);
96 Status
= MtlGetChannel (MTL_CHANNEL_TYPE_LOW
, &Channel
);
97 if (EFI_ERROR (Status
)) {
101 // Fill in message header.
102 MessageHeader
= SCMI_MESSAGE_HEADER (
104 SCMI_MESSAGE_TYPE_COMMAND
,
108 // Send payload using MTL channel.
109 Status
= MtlSendMessage (
114 if (EFI_ERROR (Status
)) {
118 // Wait for the response on the channel.
119 Status
= MtlReceiveMessage (Channel
, &ResponseHeader
, PayloadLength
);
120 if (EFI_ERROR (Status
)) {
124 // SCMI must return MessageHeader unmodified.
125 if (MessageHeader
!= ResponseHeader
) {
127 return EFI_DEVICE_ERROR
;
130 Response
= (SCMI_MESSAGE_RESPONSE
*)MtlGetChannelPayload (Channel
);
132 if (Response
->Status
!= SCMI_SUCCESS
) {
133 DEBUG ((DEBUG_ERROR
, "SCMI error: ProtocolId = 0x%x, MessageId = 0x%x, error = %d\n",
140 return EFI_DEVICE_ERROR
;
143 if (ReturnValues
!= NULL
) {
144 *ReturnValues
= Response
->ReturnValues
;
150 /** Internal common function useful for common protocol discovery messages.
152 @param[in] ProtocolId Protocol Id of the the protocol.
153 @param[in] MesaageId Message Id of the message.
155 @param[out] ReturnValues SCMI response return values.
157 @retval EFI_SUCCESS Success with valid return values.
158 @retval EFI_DEVICE_ERROR SCMI error.
159 @retval !(EFI_SUCCESS) Other errors.
163 ScmiProtocolDiscoveryCommon (
164 IN SCMI_PROTOCOL_ID ProtocolId
,
165 IN SCMI_MESSAGE_ID MessageId
,
166 OUT UINT32
**ReturnValues
169 SCMI_COMMAND Command
;
170 UINT32 PayloadLength
= 0;
172 Command
.ProtocolId
= ProtocolId
;
173 Command
.MessageId
= MessageId
;
175 return ScmiCommandExecute (
182 /** Return protocol version from SCP for a given protocol ID.
184 @param[in] Protocol ID Protocol ID.
185 @param[out] Version Pointer to version of the protocol.
187 @retval EFI_SUCCESS Version holds a valid version received
189 @retval EFI_DEVICE_ERROR SCMI error.
190 @retval !(EFI_SUCCESS) Other errors.
193 ScmiGetProtocolVersion (
194 IN SCMI_PROTOCOL_ID ProtocolId
,
199 UINT32
*ProtocolVersion
;
201 Status
= ScmiProtocolDiscoveryCommon (
203 SCMI_MESSAGE_ID_PROTOCOL_VERSION
,
204 (UINT32
**)&ProtocolVersion
206 if (EFI_ERROR (Status
)) {
210 *Version
= *ProtocolVersion
;
215 /** Return protocol attributes from SCP for a given protocol ID.
217 @param[in] Protocol ID Protocol ID.
218 @param[out] ReturnValues Pointer to attributes of the protocol.
220 @retval EFI_SUCCESS ReturnValues points to protocol attributes.
221 @retval EFI_DEVICE_ERROR SCMI error.
222 @retval !(EFI_SUCCESS) Other errors.
225 ScmiGetProtocolAttributes (
226 IN SCMI_PROTOCOL_ID ProtocolId
,
227 OUT UINT32
**ReturnValues
230 return ScmiProtocolDiscoveryCommon (
232 SCMI_MESSAGE_ID_PROTOCOL_ATTRIBUTES
,
237 /** Return protocol message attributes from SCP for a given protocol ID.
239 @param[in] Protocol ID Protocol ID.
240 @param[out] Attributes Pointer to attributes of the protocol.
242 @retval EFI_SUCCESS ReturnValues points to protocol message attributes.
243 @retval EFI_DEVICE_ERROR SCMI error.
244 @retval !(EFI_SUCCESS) Other errors.
247 ScmiGetProtocolMessageAttributes (
248 IN SCMI_PROTOCOL_ID ProtocolId
,
249 OUT UINT32
**ReturnValues
252 return ScmiProtocolDiscoveryCommon (
254 SCMI_MESSAGE_ID_PROTOCOL_MESSAGE_ATTRIBUTES
,