]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Acpi/AcpiTableDxe/AmlString.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Universal / Acpi / AcpiTableDxe / AmlString.c
CommitLineData
3dc8585e
JY
1/** @file\r
2 ACPI Sdt Protocol Driver\r
3\r
d1102dba 4 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. <BR>\r
9d510e61 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
3dc8585e
JY
6\r
7**/\r
8\r
9#include "AcpiTable.h"\r
10\r
11/**\r
12 Check if it is AML Root name\r
13\r
14 @param[in] Buffer AML path.\r
d1102dba 15\r
3dc8585e
JY
16 @retval TRUE AML path is root.\r
17 @retval FALSE AML path is not root.\r
18**/\r
19BOOLEAN\r
20AmlIsRootPath (\r
1436aea4 21 IN UINT8 *Buffer\r
3dc8585e
JY
22 )\r
23{\r
24 if ((Buffer[0] == AML_ROOT_CHAR) && (Buffer[1] == 0)) {\r
25 return TRUE;\r
26 } else {\r
27 return FALSE;\r
28 }\r
29}\r
30\r
31/**\r
32 Check if it is AML LeadName.\r
33\r
34 @param[in] Ch Char.\r
d1102dba 35\r
3dc8585e
JY
36 @retval TRUE Char is AML LeadName.\r
37 @retval FALSE Char is not AML LeadName.\r
38**/\r
39BOOLEAN\r
40AmlIsLeadName (\r
1436aea4 41 IN CHAR8 Ch\r
3dc8585e
JY
42 )\r
43{\r
1436aea4 44 if ((Ch == '_') || ((Ch >= 'A') && (Ch <= 'Z'))) {\r
3dc8585e
JY
45 return TRUE;\r
46 } else {\r
47 return FALSE;\r
48 }\r
49}\r
50\r
51/**\r
52 Check if it is AML Name.\r
53\r
54 @param[in] Ch Char.\r
d1102dba 55\r
3dc8585e
JY
56 @retval TRUE Char is AML Name.\r
57 @retval FALSE Char is not AML Name.\r
58**/\r
59BOOLEAN\r
60AmlIsName (\r
1436aea4 61 IN CHAR8 Ch\r
3dc8585e
JY
62 )\r
63{\r
1436aea4 64 if (AmlIsLeadName (Ch) || ((Ch >= '0') && (Ch <= '9'))) {\r
3dc8585e
JY
65 return TRUE;\r
66 } else {\r
67 return FALSE;\r
68 }\r
69}\r
70\r
71/**\r
72 Return is buffer is AML NameSeg.\r
73\r
74 @param[in] Buffer AML NameSement.\r
d1102dba 75\r
3dc8585e
JY
76 @retval TRUE It is AML NameSegment.\r
77 @retval FALSE It is not AML NameSegment.\r
78**/\r
79BOOLEAN\r
80AmlIsNameSeg (\r
1436aea4 81 IN UINT8 *Buffer\r
3dc8585e
JY
82 )\r
83{\r
84 UINTN Index;\r
1436aea4 85\r
3dc8585e
JY
86 if (!AmlIsLeadName (Buffer[0])) {\r
87 return FALSE;\r
88 }\r
1436aea4 89\r
3dc8585e
JY
90 for (Index = 1; Index < AML_NAME_SEG_SIZE; Index++) {\r
91 if (!AmlIsName (Buffer[Index])) {\r
92 return FALSE;\r
93 }\r
94 }\r
1436aea4 95\r
3dc8585e
JY
96 return TRUE;\r
97}\r
98\r
99/**\r
100 Get AML NameString size.\r
101\r
102 @param[in] Buffer AML NameString.\r
d1102dba
LG
103 @param[out] BufferSize AML NameString size\r
104\r
3dc8585e
JY
105 @retval EFI_SUCCESS Success.\r
106 @retval EFI_INVALID_PARAMETER Buffer does not refer to a valid AML NameString.\r
107**/\r
108EFI_STATUS\r
109AmlGetNameStringSize (\r
1436aea4
MK
110 IN UINT8 *Buffer,\r
111 OUT UINTN *BufferSize\r
3dc8585e
JY
112 )\r
113{\r
1436aea4
MK
114 UINTN SegCount;\r
115 UINTN Length;\r
116 UINTN Index;\r
3dc8585e 117\r
3dc8585e
JY
118 Length = 0;\r
119\r
120 //\r
121 // Parse root or parent prefix\r
122 //\r
123 if (*Buffer == AML_ROOT_CHAR) {\r
1436aea4
MK
124 Buffer++;\r
125 Length++;\r
3dc8585e
JY
126 } else if (*Buffer == AML_PARENT_PREFIX_CHAR) {\r
127 do {\r
1436aea4
MK
128 Buffer++;\r
129 Length++;\r
3dc8585e
JY
130 } while (*Buffer == AML_PARENT_PREFIX_CHAR);\r
131 }\r
132\r
133 //\r
134 // Parse name segment\r
135 //\r
136 if (*Buffer == AML_DUAL_NAME_PREFIX) {\r
1436aea4
MK
137 Buffer++;\r
138 Length++;\r
3dc8585e
JY
139 SegCount = 2;\r
140 } else if (*Buffer == AML_MULTI_NAME_PREFIX) {\r
1436aea4
MK
141 Buffer++;\r
142 Length++;\r
3dc8585e 143 SegCount = *Buffer;\r
1436aea4
MK
144 Buffer++;\r
145 Length++;\r
3dc8585e
JY
146 } else if (*Buffer == 0) {\r
147 //\r
148 // NULL Name, only for Root\r
149 //\r
150 SegCount = 0;\r
1436aea4 151 Buffer--;\r
3dc8585e
JY
152 if ((Length == 1) && (*Buffer == AML_ROOT_CHAR)) {\r
153 *BufferSize = 2;\r
154 return EFI_SUCCESS;\r
155 } else {\r
156 return EFI_INVALID_PARAMETER;\r
157 }\r
158 } else {\r
159 //\r
160 // NameSeg\r
161 //\r
162 SegCount = 1;\r
163 }\r
164\r
165 Index = 0;\r
166 do {\r
167 if (!AmlIsNameSeg (Buffer)) {\r
168 return EFI_INVALID_PARAMETER;\r
169 }\r
1436aea4 170\r
3dc8585e
JY
171 Buffer += AML_NAME_SEG_SIZE;\r
172 Length += AML_NAME_SEG_SIZE;\r
1436aea4 173 Index++;\r
3dc8585e
JY
174 } while (Index < SegCount);\r
175\r
176 *BufferSize = Length;\r
177 return EFI_SUCCESS;\r
178}\r
179\r
180/**\r
181 Check if it is ASL LeadName.\r
182\r
183 @param[in] Ch Char.\r
d1102dba 184\r
3dc8585e
JY
185 @retval TRUE Char is ASL LeadName.\r
186 @retval FALSE Char is not ASL LeadName.\r
187**/\r
188BOOLEAN\r
189AmlIsAslLeadName (\r
1436aea4 190 IN CHAR8 Ch\r
3dc8585e
JY
191 )\r
192{\r
1436aea4 193 if (AmlIsLeadName (Ch) || ((Ch >= 'a') && (Ch <= 'z'))) {\r
3dc8585e
JY
194 return TRUE;\r
195 } else {\r
196 return FALSE;\r
197 }\r
198}\r
199\r
200/**\r
201 Check if it is ASL Name.\r
202\r
203 @param[in] Ch Char.\r
d1102dba 204\r
3dc8585e
JY
205 @retval TRUE Char is ASL Name.\r
206 @retval FALSE Char is not ASL Name.\r
207**/\r
208BOOLEAN\r
209AmlIsAslName (\r
1436aea4 210 IN CHAR8 Ch\r
3dc8585e
JY
211 )\r
212{\r
1436aea4 213 if (AmlIsAslLeadName (Ch) || ((Ch >= '0') && (Ch <= '9'))) {\r
3dc8585e
JY
214 return TRUE;\r
215 } else {\r
216 return FALSE;\r
217 }\r
218}\r
219\r
220/**\r
221 Get ASL NameString size.\r
222\r
223 @param[in] Buffer ASL NameString.\r
d1102dba 224\r
3dc8585e
JY
225 @return ASL NameString size.\r
226**/\r
227UINTN\r
228AmlGetAslNameSegLength (\r
1436aea4 229 IN UINT8 *Buffer\r
3dc8585e
JY
230 )\r
231{\r
1436aea4
MK
232 UINTN Length;\r
233 UINTN Index;\r
3dc8585e
JY
234\r
235 if (*Buffer == 0) {\r
236 return 0;\r
237 }\r
d1102dba 238\r
3dc8585e
JY
239 Length = 0;\r
240 //\r
241 // 1st\r
242 //\r
243 if (AmlIsAslLeadName (*Buffer)) {\r
1436aea4
MK
244 Length++;\r
245 Buffer++;\r
3dc8585e 246 }\r
1436aea4 247\r
3dc8585e
JY
248 if ((*Buffer == 0) || (*Buffer == '.')) {\r
249 return Length;\r
250 }\r
1436aea4 251\r
3dc8585e
JY
252 //\r
253 // 2, 3, 4 name char\r
254 //\r
255 for (Index = 0; Index < 3; Index++) {\r
256 if (AmlIsAslName (*Buffer)) {\r
1436aea4
MK
257 Length++;\r
258 Buffer++;\r
3dc8585e 259 }\r
1436aea4 260\r
3dc8585e
JY
261 if ((*Buffer == 0) || (*Buffer == '.')) {\r
262 return Length;\r
263 }\r
264 }\r
265\r
266 //\r
267 // Invalid ASL name\r
268 //\r
269 return 0;\r
270}\r
271\r
272/**\r
273 Get ASL NameString size.\r
274\r
275 @param[in] Buffer ASL NameString.\r
276 @param[out] Root On return, points to Root char number.\r
277 @param[out] Parent On return, points to Parent char number.\r
278 @param[out] SegCount On return, points to Segment count.\r
d1102dba 279\r
3dc8585e
JY
280 @return ASL NameString size.\r
281**/\r
282UINTN\r
283AmlGetAslNameStringSize (\r
1436aea4
MK
284 IN UINT8 *Buffer,\r
285 OUT UINTN *Root,\r
286 OUT UINTN *Parent,\r
287 OUT UINTN *SegCount\r
3dc8585e
JY
288 )\r
289{\r
1436aea4
MK
290 UINTN NameLength;\r
291 UINTN TotalLength;\r
3dc8585e 292\r
1436aea4
MK
293 *Root = 0;\r
294 *Parent = 0;\r
295 *SegCount = 0;\r
3dc8585e 296 TotalLength = 0;\r
1436aea4 297 NameLength = 0;\r
3dc8585e
JY
298 if (*Buffer == AML_ROOT_CHAR) {\r
299 *Root = 1;\r
1436aea4 300 Buffer++;\r
3dc8585e
JY
301 } else if (*Buffer == AML_PARENT_PREFIX_CHAR) {\r
302 do {\r
1436aea4
MK
303 Buffer++;\r
304 (*Parent)++;\r
3dc8585e
JY
305 } while (*Buffer == AML_PARENT_PREFIX_CHAR);\r
306 }\r
307\r
308 //\r
309 // Now parse name\r
310 //\r
311 while (*Buffer != 0) {\r
312 NameLength = AmlGetAslNameSegLength (Buffer);\r
313 if ((NameLength == 0) || (NameLength > AML_NAME_SEG_SIZE)) {\r
314 return 0;\r
315 }\r
1436aea4
MK
316\r
317 (*SegCount)++;\r
3dc8585e
JY
318 Buffer += NameLength;\r
319 if (*Buffer == 0) {\r
320 break;\r
321 }\r
1436aea4
MK
322\r
323 Buffer++;\r
3dc8585e
JY
324 }\r
325\r
326 //\r
327 // Check SegCoount\r
328 //\r
329 if (*SegCount > 0xFF) {\r
330 return 0;\r
331 }\r
332\r
333 //\r
334 // Calculate total length\r
335 //\r
336 TotalLength = *Root + *Parent + (*SegCount) * AML_NAME_SEG_SIZE;\r
337 if (*SegCount > 2) {\r
338 TotalLength += 2;\r
339 } else if (*SegCount == 2) {\r
340 TotalLength += 1;\r
341 }\r
342\r
343 //\r
344 // Add NULL char\r
345 //\r
1436aea4 346 TotalLength++;\r
3dc8585e
JY
347\r
348 return TotalLength;\r
349}\r
350\r
351/**\r
352 Copy mem, and cast all the char in dest to be upper case.\r
353\r
354 @param[in] DstBuffer Destination buffer.\r
355 @param[in] SrcBuffer Source buffer.\r
356 @param[in] Length Buffer length.\r
357**/\r
358VOID\r
359AmlUpperCaseCopyMem (\r
1436aea4
MK
360 IN UINT8 *DstBuffer,\r
361 IN UINT8 *SrcBuffer,\r
362 IN UINTN Length\r
3dc8585e
JY
363 )\r
364{\r
1436aea4 365 UINTN Index;\r
3dc8585e
JY
366\r
367 for (Index = 0; Index < Length; Index++) {\r
1436aea4 368 if ((SrcBuffer[Index] >= 'a') && (SrcBuffer[Index] <= 'z')) {\r
3dc8585e
JY
369 DstBuffer[Index] = (UINT8)(SrcBuffer[Index] - 'a' + 'A');\r
370 } else {\r
371 DstBuffer[Index] = SrcBuffer[Index];\r
372 }\r
373 }\r
374}\r
375\r
376/**\r
377 Return AML name according to ASL name.\r
378 The caller need free the AmlName returned.\r
379\r
380 @param[in] AslPath ASL name.\r
381\r
382 @return AmlName\r
383**/\r
384UINT8 *\r
385AmlNameFromAslName (\r
1436aea4 386 IN UINT8 *AslPath\r
3dc8585e
JY
387 )\r
388{\r
1436aea4
MK
389 UINTN Root;\r
390 UINTN Parent;\r
391 UINTN SegCount;\r
392 UINTN TotalLength;\r
393 UINTN NameLength;\r
394 UINT8 *Buffer;\r
395 UINT8 *AmlPath;\r
396 UINT8 *AmlBuffer;\r
3dc8585e
JY
397\r
398 TotalLength = AmlGetAslNameStringSize (AslPath, &Root, &Parent, &SegCount);\r
399 if (TotalLength == 0) {\r
400 return NULL;\r
401 }\r
402\r
403 AmlPath = AllocatePool (TotalLength);\r
404 ASSERT (AmlPath != NULL);\r
405\r
406 AmlBuffer = AmlPath;\r
1436aea4 407 Buffer = AslPath;\r
3dc8585e
JY
408\r
409 //\r
410 // Handle Root and Parent\r
411 //\r
412 if (Root == 1) {\r
413 *AmlBuffer = AML_ROOT_CHAR;\r
1436aea4
MK
414 AmlBuffer++;\r
415 Buffer++;\r
3dc8585e
JY
416 } else if (Parent > 0) {\r
417 SetMem (AmlBuffer, Parent, AML_PARENT_PREFIX_CHAR);\r
418 AmlBuffer += Parent;\r
1436aea4 419 Buffer += Parent;\r
3dc8585e
JY
420 }\r
421\r
422 //\r
423 // Handle SegCount\r
424 //\r
425 if (SegCount > 2) {\r
426 *AmlBuffer = AML_MULTI_NAME_PREFIX;\r
1436aea4 427 AmlBuffer++;\r
3dc8585e 428 *AmlBuffer = (UINT8)SegCount;\r
1436aea4 429 AmlBuffer++;\r
3dc8585e
JY
430 } else if (SegCount == 2) {\r
431 *AmlBuffer = AML_DUAL_NAME_PREFIX;\r
1436aea4 432 AmlBuffer++;\r
3dc8585e
JY
433 }\r
434\r
435 //\r
436 // Now to name\r
437 //\r
438 while (*Buffer != 0) {\r
439 NameLength = AmlGetAslNameSegLength (Buffer);\r
440 ASSERT ((NameLength != 0) && (NameLength <= AML_NAME_SEG_SIZE));\r
441 AmlUpperCaseCopyMem (AmlBuffer, Buffer, NameLength);\r
442 SetMem (AmlBuffer + NameLength, AML_NAME_SEG_SIZE - NameLength, AML_NAME_CHAR__);\r
1436aea4 443 Buffer += NameLength;\r
3dc8585e
JY
444 AmlBuffer += AML_NAME_SEG_SIZE;\r
445 if (*Buffer == 0) {\r
446 break;\r
447 }\r
1436aea4
MK
448\r
449 Buffer++;\r
3dc8585e
JY
450 }\r
451\r
452 //\r
453 // Add NULL\r
454 //\r
455 AmlPath[TotalLength - 1] = 0;\r
456\r
457 return AmlPath;\r
458}\r
459\r
460/**\r
461 Print AML NameSeg.\r
462\r
463 @param[in] Buffer AML NameSeg.\r
464**/\r
465VOID\r
466AmlPrintNameSeg (\r
1436aea4 467 IN UINT8 *Buffer\r
3dc8585e
JY
468 )\r
469{\r
87000d77 470 DEBUG ((DEBUG_ERROR, "%c", Buffer[0]));\r
3dc8585e 471 if ((Buffer[1] == '_') && (Buffer[2] == '_') && (Buffer[3] == '_')) {\r
1436aea4 472 return;\r
3dc8585e 473 }\r
1436aea4 474\r
87000d77 475 DEBUG ((DEBUG_ERROR, "%c", Buffer[1]));\r
3dc8585e 476 if ((Buffer[2] == '_') && (Buffer[3] == '_')) {\r
1436aea4 477 return;\r
3dc8585e 478 }\r
1436aea4 479\r
87000d77 480 DEBUG ((DEBUG_ERROR, "%c", Buffer[2]));\r
3dc8585e 481 if (Buffer[3] == '_') {\r
1436aea4 482 return;\r
3dc8585e 483 }\r
1436aea4 484\r
87000d77 485 DEBUG ((DEBUG_ERROR, "%c", Buffer[3]));\r
1436aea4 486 return;\r
3dc8585e
JY
487}\r
488\r
489/**\r
490 Print AML NameString.\r
491\r
492 @param[in] Buffer AML NameString.\r
493**/\r
494VOID\r
495AmlPrintNameString (\r
1436aea4 496 IN UINT8 *Buffer\r
3dc8585e
JY
497 )\r
498{\r
1436aea4
MK
499 UINT8 SegCount;\r
500 UINT8 Index;\r
7538d536 501\r
3dc8585e
JY
502 if (*Buffer == AML_ROOT_CHAR) {\r
503 //\r
504 // RootChar\r
505 //\r
1436aea4 506 Buffer++;\r
87000d77 507 DEBUG ((DEBUG_ERROR, "\\"));\r
3dc8585e
JY
508 } else if (*Buffer == AML_PARENT_PREFIX_CHAR) {\r
509 //\r
510 // ParentPrefixChar\r
511 //\r
512 do {\r
1436aea4 513 Buffer++;\r
87000d77 514 DEBUG ((DEBUG_ERROR, "^"));\r
3dc8585e
JY
515 } while (*Buffer == AML_PARENT_PREFIX_CHAR);\r
516 }\r
517\r
518 if (*Buffer == AML_DUAL_NAME_PREFIX) {\r
519 //\r
520 // DualName\r
521 //\r
1436aea4 522 Buffer++;\r
3dc8585e
JY
523 SegCount = 2;\r
524 } else if (*Buffer == AML_MULTI_NAME_PREFIX) {\r
525 //\r
526 // MultiName\r
527 //\r
1436aea4 528 Buffer++;\r
3dc8585e 529 SegCount = *Buffer;\r
1436aea4 530 Buffer++;\r
3dc8585e
JY
531 } else if (*Buffer == 0) {\r
532 //\r
533 // NULL Name\r
534 //\r
1436aea4 535 return;\r
3dc8585e
JY
536 } else {\r
537 //\r
538 // NameSeg\r
539 //\r
540 SegCount = 1;\r
541 }\r
d1102dba 542\r
3dc8585e
JY
543 AmlPrintNameSeg (Buffer);\r
544 Buffer += AML_NAME_SEG_SIZE;\r
545 for (Index = 0; Index < SegCount - 1; Index++) {\r
87000d77 546 DEBUG ((DEBUG_ERROR, "."));\r
3dc8585e
JY
547 AmlPrintNameSeg (Buffer);\r
548 Buffer += AML_NAME_SEG_SIZE;\r
549 }\r
550\r
1436aea4 551 return;\r
3dc8585e 552}\r