]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Drivers/ArmScmiDxe/Scmi.c
ArmPkg: Fix Ecc error 8005 for SCMI_STATUS
[mirror_edk2.git] / ArmPkg / Drivers / ArmScmiDxe / Scmi.c
1 /** @file
2
3 Copyright (c) 2017-2021, Arm Limited. All rights reserved.
4
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
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
10 **/
11
12 #include <Library/ArmMtlLib.h>
13 #include <Library/DebugLib.h>
14 #include <Library/MemoryAllocationLib.h>
15 #include <Library/UefiBootServicesTableLib.h>
16
17 #include "ScmiPrivate.h"
18
19 // Arbitrary timeout value 20ms.
20 #define RESPONSE_TIMEOUT 20000
21
22 /** Return a pointer to the message payload.
23
24 @param[out] Payload Holds pointer to the message payload.
25
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.
29 **/
30 EFI_STATUS
31 ScmiCommandGetPayload (
32 OUT UINT32** Payload
33 )
34 {
35 EFI_STATUS Status;
36 MTL_CHANNEL *Channel;
37
38 // Get handle to the Channel.
39 Status = MtlGetChannel (MTL_CHANNEL_TYPE_LOW, &Channel);
40 if (EFI_ERROR (Status)) {
41 return Status;
42 }
43
44 // Payload will not be populated until channel is free.
45 Status = MtlWaitUntilChannelFree (Channel, RESPONSE_TIMEOUT);
46 if (EFI_ERROR (Status)) {
47 return Status;
48 }
49
50 // Get the address of the payload.
51 *Payload = MtlGetChannelPayload (Channel);
52
53 return EFI_SUCCESS;
54 }
55
56 /** Execute a SCMI command and receive a response.
57
58 This function uses a MTL channel to transfer message to SCP
59 and waits for a response.
60
61 @param[in] Command Pointer to the SCMI command (Protocol ID
62 and Message ID)
63
64 @param[in,out] PayloadLength SCMI command message length.
65
66 @param[out] OPTIONAL ReturnValues Pointer to SCMI response.
67
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.
74 **/
75 EFI_STATUS
76 ScmiCommandExecute (
77 IN SCMI_COMMAND *Command,
78 IN OUT UINT32 *PayloadLength,
79 OUT UINT32 **ReturnValues OPTIONAL
80 )
81 {
82 EFI_STATUS Status;
83 SCMI_MESSAGE_RESPONSE *Response;
84 UINT32 MessageHeader;
85 UINT32 ResponseHeader;
86 MTL_CHANNEL *Channel;
87
88 ASSERT (PayloadLength != NULL);
89
90 Status = MtlGetChannel (MTL_CHANNEL_TYPE_LOW, &Channel);
91 if (EFI_ERROR (Status)) {
92 return Status;
93 }
94
95 // Fill in message header.
96 MessageHeader = SCMI_MESSAGE_HEADER (
97 Command->MessageId,
98 ScmiMessageTypeCommand,
99 Command->ProtocolId
100 );
101
102 // Send payload using MTL channel.
103 Status = MtlSendMessage (
104 Channel,
105 MessageHeader,
106 *PayloadLength
107 );
108 if (EFI_ERROR (Status)) {
109 return Status;
110 }
111
112 // Wait for the response on the channel.
113 Status = MtlReceiveMessage (Channel, &ResponseHeader, PayloadLength);
114 if (EFI_ERROR (Status)) {
115 return Status;
116 }
117
118 // SCMI must return MessageHeader unmodified.
119 if (MessageHeader != ResponseHeader) {
120 ASSERT (FALSE);
121 return EFI_DEVICE_ERROR;
122 }
123
124 Response = (SCMI_MESSAGE_RESPONSE*)MtlGetChannelPayload (Channel);
125
126 if (Response->Status != ScmiSuccess) {
127 DEBUG ((DEBUG_ERROR, "SCMI error: ProtocolId = 0x%x, MessageId = 0x%x, error = %d\n",
128 Command->ProtocolId,
129 Command->MessageId,
130 Response->Status
131 ));
132
133 ASSERT (FALSE);
134 return EFI_DEVICE_ERROR;
135 }
136
137 if (ReturnValues != NULL) {
138 *ReturnValues = Response->ReturnValues;
139 }
140
141 return EFI_SUCCESS;
142 }
143
144 /** Internal common function useful for common protocol discovery messages.
145
146 @param[in] ProtocolId Protocol Id of the the protocol.
147 @param[in] MesaageId Message Id of the message.
148
149 @param[out] ReturnValues SCMI response return values.
150
151 @retval EFI_SUCCESS Success with valid return values.
152 @retval EFI_DEVICE_ERROR SCMI error.
153 @retval !(EFI_SUCCESS) Other errors.
154 **/
155 STATIC
156 EFI_STATUS
157 ScmiProtocolDiscoveryCommon (
158 IN SCMI_PROTOCOL_ID ProtocolId,
159 IN SCMI_MESSAGE_ID MessageId,
160 OUT UINT32 **ReturnValues
161 )
162 {
163 SCMI_COMMAND Command;
164 UINT32 PayloadLength;
165
166 PayloadLength = 0;
167 Command.ProtocolId = ProtocolId;
168 Command.MessageId = MessageId;
169
170 return ScmiCommandExecute (
171 &Command,
172 &PayloadLength,
173 ReturnValues
174 );
175 }
176
177 /** Return protocol version from SCP for a given protocol ID.
178
179 @param[in] Protocol ID Protocol ID.
180 @param[out] Version Pointer to version of the protocol.
181
182 @retval EFI_SUCCESS Version holds a valid version received
183 from the SCP.
184 @retval EFI_DEVICE_ERROR SCMI error.
185 @retval !(EFI_SUCCESS) Other errors.
186 **/
187 EFI_STATUS
188 ScmiGetProtocolVersion (
189 IN SCMI_PROTOCOL_ID ProtocolId,
190 OUT UINT32 *Version
191 )
192 {
193 EFI_STATUS Status;
194 UINT32 *ProtocolVersion;
195
196 Status = ScmiProtocolDiscoveryCommon (
197 ProtocolId,
198 SCMI_MESSAGE_ID_PROTOCOL_VERSION,
199 (UINT32**)&ProtocolVersion
200 );
201 if (EFI_ERROR (Status)) {
202 return Status;
203 }
204
205 *Version = *ProtocolVersion;
206
207 return EFI_SUCCESS;
208 }
209
210 /** Return protocol attributes from SCP for a given protocol ID.
211
212 @param[in] Protocol ID Protocol ID.
213 @param[out] ReturnValues Pointer to attributes of the protocol.
214
215 @retval EFI_SUCCESS ReturnValues points to protocol attributes.
216 @retval EFI_DEVICE_ERROR SCMI error.
217 @retval !(EFI_SUCCESS) Other errors.
218 **/
219 EFI_STATUS
220 ScmiGetProtocolAttributes (
221 IN SCMI_PROTOCOL_ID ProtocolId,
222 OUT UINT32 **ReturnValues
223 )
224 {
225 return ScmiProtocolDiscoveryCommon (
226 ProtocolId,
227 SCMI_MESSAGE_ID_PROTOCOL_ATTRIBUTES,
228 ReturnValues
229 );
230 }
231
232 /** Return protocol message attributes from SCP for a given protocol ID.
233
234 @param[in] Protocol ID Protocol ID.
235 @param[out] Attributes Pointer to attributes of the protocol.
236
237 @retval EFI_SUCCESS ReturnValues points to protocol message attributes.
238 @retval EFI_DEVICE_ERROR SCMI error.
239 @retval !(EFI_SUCCESS) Other errors.
240 **/
241 EFI_STATUS
242 ScmiGetProtocolMessageAttributes (
243 IN SCMI_PROTOCOL_ID ProtocolId,
244 OUT UINT32 **ReturnValues
245 )
246 {
247 return ScmiProtocolDiscoveryCommon (
248 ProtocolId,
249 SCMI_MESSAGE_ID_PROTOCOL_MESSAGE_ATTRIBUTES,
250 ReturnValues
251 );
252 }