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