VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/ArmPkg/Drivers/ArmScmiDxe/Scmi.c@ 100307

Last change on this file since 100307 was 99464, checked in by vboxsync, 21 months ago

Devices/EFI/Firmware: Restore ArmPkg, ArmVirtPkg, ArmPlatformPkg in order to be able to build Aarch64 and Aarch32 firmware images for the virt platform, bugref:10400

  • Property svn:eol-style set to native
File size: 6.5 KB
Line 
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**/
30EFI_STATUS
31ScmiCommandGetPayload (
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**/
75EFI_STATUS
76ScmiCommandExecute (
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 ((
128 DEBUG_ERROR,
129 "SCMI error: ProtocolId = 0x%x, MessageId = 0x%x, error = %d\n",
130 Command->ProtocolId,
131 Command->MessageId,
132 Response->Status
133 ));
134
135 ASSERT (FALSE);
136 return EFI_DEVICE_ERROR;
137 }
138
139 if (ReturnValues != NULL) {
140 *ReturnValues = Response->ReturnValues;
141 }
142
143 return EFI_SUCCESS;
144}
145
146/** Internal common function useful for common protocol discovery messages.
147
148 @param[in] ProtocolId Protocol Id of the protocol.
149 @param[in] MessageId Message Id of the message.
150
151 @param[out] ReturnValues SCMI response return values.
152
153 @retval EFI_SUCCESS Success with valid return values.
154 @retval EFI_DEVICE_ERROR SCMI error.
155 @retval !(EFI_SUCCESS) Other errors.
156**/
157STATIC
158EFI_STATUS
159ScmiProtocolDiscoveryCommon (
160 IN SCMI_PROTOCOL_ID ProtocolId,
161 IN SCMI_MESSAGE_ID MessageId,
162 OUT UINT32 **ReturnValues
163 )
164{
165 SCMI_COMMAND Command;
166 UINT32 PayloadLength;
167
168 PayloadLength = 0;
169 Command.ProtocolId = ProtocolId;
170 Command.MessageId = MessageId;
171
172 return ScmiCommandExecute (
173 &Command,
174 &PayloadLength,
175 ReturnValues
176 );
177}
178
179/** Return protocol version from SCP for a given protocol ID.
180
181 @param[in] Protocol ID Protocol ID.
182 @param[out] Version Pointer to version of the protocol.
183
184 @retval EFI_SUCCESS Version holds a valid version received
185 from the SCP.
186 @retval EFI_DEVICE_ERROR SCMI error.
187 @retval !(EFI_SUCCESS) Other errors.
188**/
189EFI_STATUS
190ScmiGetProtocolVersion (
191 IN SCMI_PROTOCOL_ID ProtocolId,
192 OUT UINT32 *Version
193 )
194{
195 EFI_STATUS Status;
196 UINT32 *ProtocolVersion;
197
198 Status = ScmiProtocolDiscoveryCommon (
199 ProtocolId,
200 ScmiMessageIdProtocolVersion,
201 (UINT32 **)&ProtocolVersion
202 );
203 if (EFI_ERROR (Status)) {
204 return Status;
205 }
206
207 *Version = *ProtocolVersion;
208
209 return EFI_SUCCESS;
210}
211
212/** Return protocol attributes from SCP for a given protocol ID.
213
214 @param[in] Protocol ID Protocol ID.
215 @param[out] ReturnValues Pointer to attributes of the protocol.
216
217 @retval EFI_SUCCESS ReturnValues points to protocol attributes.
218 @retval EFI_DEVICE_ERROR SCMI error.
219 @retval !(EFI_SUCCESS) Other errors.
220**/
221EFI_STATUS
222ScmiGetProtocolAttributes (
223 IN SCMI_PROTOCOL_ID ProtocolId,
224 OUT UINT32 **ReturnValues
225 )
226{
227 return ScmiProtocolDiscoveryCommon (
228 ProtocolId,
229 ScmiMessageIdProtocolAttributes,
230 ReturnValues
231 );
232}
233
234/** Return protocol message attributes from SCP for a given protocol ID.
235
236 @param[in] Protocol ID Protocol ID.
237 @param[out] Attributes Pointer to attributes of the protocol.
238
239 @retval EFI_SUCCESS ReturnValues points to protocol message attributes.
240 @retval EFI_DEVICE_ERROR SCMI error.
241 @retval !(EFI_SUCCESS) Other errors.
242**/
243EFI_STATUS
244ScmiGetProtocolMessageAttributes (
245 IN SCMI_PROTOCOL_ID ProtocolId,
246 OUT UINT32 **ReturnValues
247 )
248{
249 return ScmiProtocolDiscoveryCommon (
250 ProtocolId,
251 ScmiMessageIdProtocolMessageAttributes,
252 ReturnValues
253 );
254}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette