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