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
) {
129 "SCMI error: ProtocolId = 0x%x, MessageId = 0x%x, error = %d\n",
136 return EFI_DEVICE_ERROR
;
139 if (ReturnValues
!= NULL
) {
140 *ReturnValues
= Response
->ReturnValues
;
146 /** Internal common function useful for common protocol discovery messages.
148 @param[in] ProtocolId Protocol Id of the the protocol.
149 @param[in] MesaageId Message Id of the message.
151 @param[out] ReturnValues SCMI response return values.
153 @retval EFI_SUCCESS Success with valid return values.
154 @retval EFI_DEVICE_ERROR SCMI error.
155 @retval !(EFI_SUCCESS) Other errors.
159 ScmiProtocolDiscoveryCommon (
160 IN SCMI_PROTOCOL_ID ProtocolId
,
161 IN SCMI_MESSAGE_ID MessageId
,
162 OUT UINT32
**ReturnValues
165 SCMI_COMMAND Command
;
166 UINT32 PayloadLength
;
169 Command
.ProtocolId
= ProtocolId
;
170 Command
.MessageId
= MessageId
;
172 return ScmiCommandExecute (
179 /** Return protocol version from SCP for a given protocol ID.
181 @param[in] Protocol ID Protocol ID.
182 @param[out] Version Pointer to version of the protocol.
184 @retval EFI_SUCCESS Version holds a valid version received
186 @retval EFI_DEVICE_ERROR SCMI error.
187 @retval !(EFI_SUCCESS) Other errors.
190 ScmiGetProtocolVersion (
191 IN SCMI_PROTOCOL_ID ProtocolId
,
196 UINT32
*ProtocolVersion
;
198 Status
= ScmiProtocolDiscoveryCommon (
200 ScmiMessageIdProtocolVersion
,
201 (UINT32
**)&ProtocolVersion
203 if (EFI_ERROR (Status
)) {
207 *Version
= *ProtocolVersion
;
212 /** Return protocol attributes from SCP for a given protocol ID.
214 @param[in] Protocol ID Protocol ID.
215 @param[out] ReturnValues Pointer to attributes of the protocol.
217 @retval EFI_SUCCESS ReturnValues points to protocol attributes.
218 @retval EFI_DEVICE_ERROR SCMI error.
219 @retval !(EFI_SUCCESS) Other errors.
222 ScmiGetProtocolAttributes (
223 IN SCMI_PROTOCOL_ID ProtocolId
,
224 OUT UINT32
**ReturnValues
227 return ScmiProtocolDiscoveryCommon (
229 ScmiMessageIdProtocolAttributes
,
234 /** Return protocol message attributes from SCP for a given protocol ID.
236 @param[in] Protocol ID Protocol ID.
237 @param[out] Attributes Pointer to attributes of the protocol.
239 @retval EFI_SUCCESS ReturnValues points to protocol message attributes.
240 @retval EFI_DEVICE_ERROR SCMI error.
241 @retval !(EFI_SUCCESS) Other errors.
244 ScmiGetProtocolMessageAttributes (
245 IN SCMI_PROTOCOL_ID ProtocolId
,
246 OUT UINT32
**ReturnValues
249 return ScmiProtocolDiscoveryCommon (
251 ScmiMessageIdProtocolMessageAttributes
,