]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Drivers/ArmScmiDxe/ScmiBaseProtocol.c
ArmPkg: Introduce SCMI protocol
[mirror_edk2.git] / ArmPkg / Drivers / ArmScmiDxe / ScmiBaseProtocol.c
CommitLineData
4f2494cf
GP
1/** @file\r
2\r
3 Copyright (c) 2017-2018, Arm Limited. All rights reserved.\r
4\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13 System Control and Management Interface V1.0\r
14 http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/\r
15 DEN0056A_System_Control_and_Management_Interface.pdf\r
16**/\r
17\r
18#include <Library/BaseLib.h>\r
19#include <Library/DebugLib.h>\r
20#include <Library/UefiBootServicesTableLib.h>\r
21#include <Protocol/ArmScmiBaseProtocol.h>\r
22\r
23#include "ArmScmiBaseProtocolPrivate.h"\r
24#include "ScmiPrivate.h"\r
25\r
26/** Return version of the Base protocol supported by SCP firmware.\r
27\r
28 @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
29\r
30 @param[out] Version Version of the supported SCMI Base protocol.\r
31\r
32 @retval EFI_SUCCESS The version of the protocol is returned.\r
33 @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
34 @retval !(EFI_SUCCESS) Other errors.\r
35**/\r
36STATIC\r
37EFI_STATUS\r
38BaseGetVersion (\r
39 IN SCMI_BASE_PROTOCOL *This,\r
40 OUT UINT32 *Version\r
41 )\r
42{\r
43 return ScmiGetProtocolVersion (SCMI_PROTOCOL_ID_BASE, Version);\r
44}\r
45\r
46/** Return total number of SCMI protocols supported by the SCP firmware.\r
47\r
48 @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
49\r
50 @param[out] TotalProtocols Total number of SCMI protocols supported.\r
51\r
52 @retval EFI_SUCCESS Total number of protocols supported are returned.\r
53 @retval EFI_DEVICE_ERROR SCP returns a SCMI error.\r
54 @retval !(EFI_SUCCESS) Other errors.\r
55**/\r
56STATIC\r
57EFI_STATUS\r
58BaseGetTotalProtocols (\r
59 IN SCMI_BASE_PROTOCOL *This,\r
60 OUT UINT32 *TotalProtocols\r
61 )\r
62{\r
63 EFI_STATUS Status;\r
64 UINT32 *ReturnValues;\r
65\r
66 Status = ScmiGetProtocolAttributes (SCMI_PROTOCOL_ID_BASE, &ReturnValues);\r
67 if (EFI_ERROR (Status)) {\r
68 return Status;\r
69 }\r
70\r
71 *TotalProtocols = SCMI_TOTAL_PROTOCOLS (ReturnValues[0]);\r
72\r
73 return EFI_SUCCESS;\r
74}\r
75\r
76/** Common function which returns vendor details.\r
77\r
78 @param[in] MessageId SCMI_MESSAGE_ID_BASE_DISCOVER_VENDOR\r
79 OR\r
80 SCMI_MESSAGE_ID_BASE_DISCOVER_SUB_VENDOR\r
81\r
82 @param[out] VendorIdentifier ASCII name of the vendor/subvendor.\r
83\r
84 @retval EFI_SUCCESS VendorIdentifier is returned.\r
85 @retval EFI_DEVICE_ERROR SCP returns an SCMI error.\r
86 @retval !(EFI_SUCCESS) Other errors.\r
87**/\r
88STATIC\r
89EFI_STATUS\r
90BaseDiscoverVendorDetails (\r
91 IN SCMI_MESSAGE_ID_BASE MessageId,\r
92 OUT UINT8 VendorIdentifier[SCMI_MAX_STR_LEN]\r
93 )\r
94{\r
95 EFI_STATUS Status;\r
96 UINT32 *ReturnValues;\r
97 SCMI_COMMAND Cmd;\r
98 UINT32 PayloadLength;\r
99\r
100 Cmd.ProtocolId = SCMI_PROTOCOL_ID_BASE;\r
101 Cmd.MessageId = MessageId;\r
102\r
103 PayloadLength = 0;\r
104\r
105 Status = ScmiCommandExecute (\r
106 &Cmd,\r
107 &PayloadLength,\r
108 &ReturnValues\r
109 );\r
110 if (EFI_ERROR (Status)) {\r
111 return Status;\r
112 }\r
113\r
114 AsciiStrCpyS (\r
115 (CHAR8*)VendorIdentifier,\r
116 SCMI_MAX_STR_LEN,\r
117 (CONST CHAR8*)ReturnValues\r
118 );\r
119\r
120 return EFI_SUCCESS;\r
121}\r
122\r
123/** Return vendor name.\r
124\r
125 @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
126\r
127 @param[out] VendorIdentifier Null terminated ASCII string of up to\r
128 16 bytes with a vendor name.\r
129\r
130 @retval EFI_SUCCESS VendorIdentifier is returned.\r
131 @retval EFI_DEVICE_ERROR SCP returns a SCMI error.\r
132 @retval !(EFI_SUCCESS) Other errors.\r
133**/\r
134STATIC\r
135EFI_STATUS\r
136BaseDiscoverVendor (\r
137 IN SCMI_BASE_PROTOCOL *This,\r
138 OUT UINT8 VendorIdentifier[SCMI_MAX_STR_LEN]\r
139 )\r
140{\r
141 return BaseDiscoverVendorDetails (\r
142 SCMI_MESSAGE_ID_BASE_DISCOVER_VENDOR,\r
143 VendorIdentifier\r
144 );\r
145}\r
146\r
147/** Return sub vendor name.\r
148\r
149 @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
150\r
151 @param[out] VendorIdentifier Null terminated ASCII string of up to\r
152 16 bytes with a sub vendor name.\r
153\r
154 @retval EFI_SUCCESS VendorIdentifier is returned.\r
155 @retval EFI_DEVICE_ERROR SCP returns a SCMI error.\r
156 @retval !(EFI_SUCCESS) Other errors.\r
157**/\r
158EFI_STATUS\r
159BaseDiscoverSubVendor (\r
160 IN SCMI_BASE_PROTOCOL *This,\r
161 OUT UINT8 VendorIdentifier[SCMI_MAX_STR_LEN]\r
162 )\r
163{\r
164 return BaseDiscoverVendorDetails (\r
165 SCMI_MESSAGE_ID_BASE_DISCOVER_SUB_VENDOR,\r
166 VendorIdentifier\r
167 );\r
168}\r
169\r
170/** Return implementation version.\r
171\r
172 @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
173\r
174 @param[out] ImplementationVersion Vendor specific implementation version.\r
175\r
176 @retval EFI_SUCCESS Implementation version is returned.\r
177 @retval EFI_DEVICE_ERROR SCP returns a SCMI error.\r
178 @retval !(EFI_SUCCESS) Other errors.\r
179**/\r
180STATIC\r
181EFI_STATUS\r
182BaseDiscoverImplVersion (\r
183 IN SCMI_BASE_PROTOCOL *This,\r
184 OUT UINT32 *ImplementationVersion\r
185 )\r
186{\r
187 EFI_STATUS Status;\r
188 UINT32 *ReturnValues;\r
189 SCMI_COMMAND Cmd;\r
190 UINT32 PayloadLength;\r
191\r
192 Cmd.ProtocolId = SCMI_PROTOCOL_ID_BASE;\r
193 Cmd.MessageId = SCMI_MESSAGE_ID_BASE_DISCOVER_IMPLEMENTATION_VERSION;\r
194\r
195 PayloadLength = 0;\r
196\r
197 Status = ScmiCommandExecute (\r
198 &Cmd,\r
199 &PayloadLength,\r
200 &ReturnValues\r
201 );\r
202 if (EFI_ERROR (Status)) {\r
203 return Status;\r
204 }\r
205\r
206 *ImplementationVersion = ReturnValues[0];\r
207\r
208 return EFI_SUCCESS;\r
209}\r
210\r
211/** Return list of protocols.\r
212\r
213 @param[in] This A Pointer to SCMI_BASE_PROTOCOL Instance.\r
214\r
215 @param[out] ProtocolListSize Size of the ProtocolList.\r
216\r
217 @param[out] ProtocolList Protocol list.\r
218\r
219 @retval EFI_SUCCESS List of protocols is returned.\r
220 @retval EFI_BUFFER_TOO_SMALL ProtocolListSize is too small for the result.\r
221 It has been updated to the size needed.\r
222 @retval EFI_DEVICE_ERROR SCP returns a SCMI error.\r
223 @retval !(EFI_SUCCESS) Other errors.\r
224**/\r
225STATIC\r
226EFI_STATUS\r
227BaseDiscoverListProtocols (\r
228 IN SCMI_BASE_PROTOCOL *This,\r
229 IN OUT UINT32 *ProtocolListSize,\r
230 OUT UINT8 *ProtocolList\r
231 )\r
232{\r
233 EFI_STATUS Status;\r
234 UINT32 TotalProtocols;\r
235 UINT32 *MessageParams;\r
236 BASE_DISCOVER_LIST *DiscoverList;\r
237 UINT32 Skip;\r
238 UINT32 Index;\r
239 SCMI_COMMAND Cmd;\r
240 UINT32 PayloadLength;\r
241 UINT32 RequiredSize;\r
242\r
243 Status = BaseGetTotalProtocols (This, &TotalProtocols);\r
244 if (EFI_ERROR (Status)) {\r
245 return Status;\r
246 }\r
247\r
248 Status = ScmiCommandGetPayload (&MessageParams);\r
249 if (EFI_ERROR (Status)) {\r
250 return Status;\r
251 }\r
252\r
253 RequiredSize = sizeof (UINT8) * TotalProtocols;\r
254 if (*ProtocolListSize < RequiredSize) {\r
255 *ProtocolListSize = RequiredSize;\r
256 return EFI_BUFFER_TOO_SMALL;\r
257 }\r
258\r
259 Cmd.ProtocolId = SCMI_PROTOCOL_ID_BASE;\r
260 Cmd.MessageId = SCMI_MESSAGE_ID_BASE_DISCOVER_LIST_PROTOCOLS;\r
261\r
262 Skip = 0;\r
263\r
264 while (Skip < TotalProtocols) {\r
265\r
266 *MessageParams = Skip;\r
267\r
268 // Note PayloadLength is a IN/OUT parameter.\r
269 PayloadLength = sizeof (Skip);\r
270\r
271 Status = ScmiCommandExecute (\r
272 &Cmd,\r
273 &PayloadLength,\r
274 (UINT32**)&DiscoverList\r
275 );\r
276 if (EFI_ERROR (Status)) {\r
277 return Status;\r
278 }\r
279\r
280 for (Index = 0; Index < DiscoverList->NumProtocols; Index++) {\r
281 ProtocolList[Skip++] = DiscoverList->Protocols[Index];\r
282 }\r
283 }\r
284\r
285 *ProtocolListSize = RequiredSize;\r
286\r
287 return EFI_SUCCESS;\r
288}\r
289\r
290// Instance of the SCMI Base protocol.\r
291STATIC CONST SCMI_BASE_PROTOCOL BaseProtocol = {\r
292 BaseGetVersion,\r
293 BaseGetTotalProtocols,\r
294 BaseDiscoverVendor,\r
295 BaseDiscoverSubVendor,\r
296 BaseDiscoverImplVersion,\r
297 BaseDiscoverListProtocols\r
298};\r
299\r
300/** Initialize Base protocol and install protocol on a given handle.\r
301\r
302 @param[in] Handle Handle to install Base protocol.\r
303\r
304 @retval EFI_SUCCESS Base protocol interface installed\r
305 successfully.\r
306**/\r
307EFI_STATUS\r
308ScmiBaseProtocolInit (\r
309 IN OUT EFI_HANDLE* Handle\r
310 )\r
311{\r
312 return gBS->InstallMultipleProtocolInterfaces (\r
313 Handle,\r
314 &gArmScmiBaseProtocolGuid,\r
315 &BaseProtocol,\r
316 NULL\r
317 );\r
318}\r