3 Copyright (c) 2017-2021, Arm Limited. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
7 System Control and Management Interface V1.0
8 http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/
9 DEN0056A_System_Control_and_Management_Interface.pdf
12 #include <Library/ArmMtlLib.h>
13 #include <Library/DebugLib.h>
14 #include <Library/MemoryAllocationLib.h>
15 #include <Library/UefiBootServicesTableLib.h>
17 #include "ScmiPrivate.h"
19 // Arbitrary timeout value 20ms.
20 #define RESPONSE_TIMEOUT 20000
22 /** Return a pointer to the message payload.
24 @param[out] Payload Holds pointer to the message payload.
26 @retval EFI_SUCCESS Payload holds a valid message payload pointer.
27 @retval EFI_TIMEOUT Time out error if MTL channel is busy.
28 @retval EFI_UNSUPPORTED If MTL channel is unsupported.
31 ScmiCommandGetPayload (
38 // Get handle to the Channel.
39 Status
= MtlGetChannel (MTL_CHANNEL_TYPE_LOW
, &Channel
);
40 if (EFI_ERROR (Status
)) {
44 // Payload will not be populated until channel is free.
45 Status
= MtlWaitUntilChannelFree (Channel
, RESPONSE_TIMEOUT
);
46 if (EFI_ERROR (Status
)) {
50 // Get the address of the payload.
51 *Payload
= MtlGetChannelPayload (Channel
);
56 /** Execute a SCMI command and receive a response.
58 This function uses a MTL channel to transfer message to SCP
59 and waits for a response.
61 @param[in] Command Pointer to the SCMI command (Protocol ID
64 @param[in,out] PayloadLength SCMI command message length.
66 @param[out] OPTIONAL ReturnValues Pointer to SCMI response.
68 @retval OUT EFI_SUCCESS Command sent and message received successfully.
69 @retval OUT EFI_UNSUPPORTED Channel not supported.
70 @retval OUT EFI_TIMEOUT Timeout on the channel.
71 @retval OUT EFI_DEVICE_ERROR Channel not ready.
72 @retval OUT EFI_DEVICE_ERROR Message Header corrupted.
73 @retval OUT EFI_DEVICE_ERROR SCMI error.
77 IN SCMI_COMMAND
*Command
,
78 IN OUT UINT32
*PayloadLength
,
79 OUT UINT32
**ReturnValues OPTIONAL
83 SCMI_MESSAGE_RESPONSE
*Response
;
85 UINT32 ResponseHeader
;
88 ASSERT (PayloadLength
!= NULL
);
90 Status
= MtlGetChannel (MTL_CHANNEL_TYPE_LOW
, &Channel
);
91 if (EFI_ERROR (Status
)) {
95 // Fill in message header.
96 MessageHeader
= SCMI_MESSAGE_HEADER (
98 ScmiMessageTypeCommand
,
102 // Send payload using MTL channel.
103 Status
= MtlSendMessage (
108 if (EFI_ERROR (Status
)) {
112 // Wait for the response on the channel.
113 Status
= MtlReceiveMessage (Channel
, &ResponseHeader
, PayloadLength
);
114 if (EFI_ERROR (Status
)) {
118 // SCMI must return MessageHeader unmodified.
119 if (MessageHeader
!= ResponseHeader
) {
121 return EFI_DEVICE_ERROR
;
124 Response
= (SCMI_MESSAGE_RESPONSE
*)MtlGetChannelPayload (Channel
);
126 if (Response
->Status
!= ScmiSuccess
) {
127 DEBUG ((DEBUG_ERROR
, "SCMI error: ProtocolId = 0x%x, MessageId = 0x%x, error = %d\n",
134 return EFI_DEVICE_ERROR
;
137 if (ReturnValues
!= NULL
) {
138 *ReturnValues
= Response
->ReturnValues
;
144 /** Internal common function useful for common protocol discovery messages.
146 @param[in] ProtocolId Protocol Id of the the protocol.
147 @param[in] MesaageId Message Id of the message.
149 @param[out] ReturnValues SCMI response return values.
151 @retval EFI_SUCCESS Success with valid return values.
152 @retval EFI_DEVICE_ERROR SCMI error.
153 @retval !(EFI_SUCCESS) Other errors.
157 ScmiProtocolDiscoveryCommon (
158 IN SCMI_PROTOCOL_ID ProtocolId
,
159 IN SCMI_MESSAGE_ID MessageId
,
160 OUT UINT32
**ReturnValues
163 SCMI_COMMAND Command
;
164 UINT32 PayloadLength
;
167 Command
.ProtocolId
= ProtocolId
;
168 Command
.MessageId
= MessageId
;
170 return ScmiCommandExecute (
177 /** Return protocol version from SCP for a given protocol ID.
179 @param[in] Protocol ID Protocol ID.
180 @param[out] Version Pointer to version of the protocol.
182 @retval EFI_SUCCESS Version holds a valid version received
184 @retval EFI_DEVICE_ERROR SCMI error.
185 @retval !(EFI_SUCCESS) Other errors.
188 ScmiGetProtocolVersion (
189 IN SCMI_PROTOCOL_ID ProtocolId
,
194 UINT32
*ProtocolVersion
;
196 Status
= ScmiProtocolDiscoveryCommon (
198 ScmiMessageIdProtocolVersion
,
199 (UINT32
**)&ProtocolVersion
201 if (EFI_ERROR (Status
)) {
205 *Version
= *ProtocolVersion
;
210 /** Return protocol attributes from SCP for a given protocol ID.
212 @param[in] Protocol ID Protocol ID.
213 @param[out] ReturnValues Pointer to attributes of the protocol.
215 @retval EFI_SUCCESS ReturnValues points to protocol attributes.
216 @retval EFI_DEVICE_ERROR SCMI error.
217 @retval !(EFI_SUCCESS) Other errors.
220 ScmiGetProtocolAttributes (
221 IN SCMI_PROTOCOL_ID ProtocolId
,
222 OUT UINT32
**ReturnValues
225 return ScmiProtocolDiscoveryCommon (
227 ScmiMessageIdProtocolAttributes
,
232 /** Return protocol message attributes from SCP for a given protocol ID.
234 @param[in] Protocol ID Protocol ID.
235 @param[out] Attributes Pointer to attributes of the protocol.
237 @retval EFI_SUCCESS ReturnValues points to protocol message attributes.
238 @retval EFI_DEVICE_ERROR SCMI error.
239 @retval !(EFI_SUCCESS) Other errors.
242 ScmiGetProtocolMessageAttributes (
243 IN SCMI_PROTOCOL_ID ProtocolId
,
244 OUT UINT32
**ReturnValues
247 return ScmiProtocolDiscoveryCommon (
249 ScmiMessageIdProtocolMessageAttributes
,