OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
AcpiParser.c
Go to the documentation of this file.
1
7#include <Uefi.h>
8#include <IndustryStandard/Acpi62.h>
9#include <Library/OcAcpiLib.h>
10#include <Library/BaseMemoryLib.h>
11#include <Library/DebugLib.h>
12#include <Library/MemoryAllocationLib.h>
13#include <Library/UefiLib.h>
14#include <Library/UefiApplicationEntryPoint.h>
15#include <Library/UefiBootServicesTableLib.h>
16#include <IndustryStandard/AcpiAml.h>
17
18#include "AcpiParser.h"
19
33STATIC
34EFI_STATUS
36 IN OUT ACPI_PARSER_CONTEXT *Context,
37 IN OUT UINT8 **NamePathStart OPTIONAL,
38 IN OUT UINT8 *PathLength OPTIONAL,
39 IN OUT UINT8 *IsRootPath OPTIONAL
40 )
41{
42 CONTEXT_ENTER (Context, "NameString");
43 CONTEXT_HAS_WORK (Context);
45
46 if (IsRootPath != NULL) {
47 *IsRootPath = 0;
48 }
49
50 while (Context->CurrentOpcode[0] == AML_ROOT_CHAR || Context->CurrentOpcode[0] == AML_PARENT_PREFIX_CHAR) {
51 if ((Context->CurrentOpcode[0] == AML_ROOT_CHAR) && (IsRootPath != NULL)) {
52 *IsRootPath = 1;
53 }
54
55 CONTEXT_ADVANCE_OPCODE (Context);
56 }
57
58 switch (Context->CurrentOpcode[0]) {
59 case AML_ZERO_OP:
60 if (NamePathStart != NULL) {
61 *PathLength = 0;
62 *NamePathStart = NULL;
63 }
64
65 Context->CurrentOpcode += 1;
66 break;
67
68 case AML_DUAL_NAME_PREFIX:
69 CONTEXT_ADVANCE_OPCODE (Context);
70 CONTEXT_PEEK_BYTES (Context, 2 * IDENT_LEN);
71
72 if (NamePathStart != NULL) {
73 *PathLength = 2;
74 *NamePathStart = Context->CurrentOpcode;
75 }
76
77 Context->CurrentOpcode += 2 * IDENT_LEN;
78 break;
79
80 case AML_MULTI_NAME_PREFIX:
81 CONTEXT_ADVANCE_OPCODE (Context);
82 CONTEXT_PEEK_BYTES (Context, 1 + Context->CurrentOpcode[0] * IDENT_LEN);
83
84 if (NamePathStart != NULL) {
85 *PathLength = Context->CurrentOpcode[0];
86 *NamePathStart = Context->CurrentOpcode + 1;
87 }
88
89 Context->CurrentOpcode += 1 + Context->CurrentOpcode[0] * IDENT_LEN;
90 break;
91
92 default:
94
95 if (NamePathStart != NULL) {
96 *PathLength = 1;
97 *NamePathStart = Context->CurrentOpcode;
98 }
99
100 Context->CurrentOpcode += IDENT_LEN;
101 }
102
103 if (NamePathStart != NULL) {
104 PRINT_ACPI_NAME ("Read name", *NamePathStart, *PathLength);
105 }
106
107 CONTEXT_DECREASE_NESTING (Context);
108 return EFI_SUCCESS;
109}
110
121STATIC
122EFI_STATUS
124 IN OUT ACPI_PARSER_CONTEXT *Context,
125 OUT UINT32 *PkgLength
126 )
127{
128 UINT8 LeadByte;
129 UINT8 ByteCount;
130 UINT32 TotalSize;
131 UINT32 Index;
132
133 CONTEXT_ENTER (Context, "PkgLength");
134 CONTEXT_HAS_WORK (Context);
135 CONTEXT_INCREASE_NESTING (Context);
136
137 LeadByte = Context->CurrentOpcode[0];
138 TotalSize = 0;
139 ByteCount = (LeadByte & 0xC0) >> 6;
140
141 CONTEXT_CONSUME_BYTES (Context, 1);
142
143 if (ByteCount > 0) {
144 CONTEXT_PEEK_BYTES (Context, ByteCount);
145
146 for (Index = 0; Index < ByteCount; Index++) {
147 TotalSize |= (UINT32)Context->CurrentOpcode[Index] << (Index * 8U + 4);
148 }
149
150 TotalSize |= LeadByte & 0x0F;
151 *PkgLength = TotalSize;
152 CONTEXT_CONSUME_BYTES (Context, ByteCount);
153 } else {
154 *PkgLength = (UINT32)LeadByte;
155 }
156
157 CONTEXT_DECREASE_NESTING (Context);
158 return EFI_SUCCESS;
159}
160
170STATIC
171EFI_STATUS
173 IN OUT ACPI_PARSER_CONTEXT *Context
174 )
175{
176 CONTEXT_ENTER (Context, "Alias");
177 CONTEXT_HAS_WORK (Context);
178 CONTEXT_INCREASE_NESTING (Context);
179
180 if (ParseNameString (
181 Context,
182 NULL,
183 NULL,
184 NULL
185 ) != EFI_SUCCESS)
186 {
187 return EFI_DEVICE_ERROR;
188 }
189
190 CONTEXT_PEEK_BYTES (Context, 1);
191
192 if (ParseNameString (
193 Context,
194 NULL,
195 NULL,
196 NULL
197 ) != EFI_SUCCESS)
198 {
199 return EFI_DEVICE_ERROR;
200 }
201
202 CONTEXT_DECREASE_NESTING (Context);
203 return EFI_NOT_FOUND;
204}
205
219STATIC
220EFI_STATUS
222 IN OUT ACPI_PARSER_CONTEXT *Context,
223 OUT UINT8 **Result
224 )
225{
226 UINT32 PkgLength;
227 UINT8 *ScopeStart;
228 UINT32 *CurrentPath;
229 UINT8 *ScopeEnd;
230 UINT8 *ScopeName;
231 UINT8 *ScopeNameStart;
232 UINT8 ScopeNameLength;
233 UINT8 IsRootPath;
234 EFI_STATUS Status;
235 UINT8 Index;
236 UINT8 Index2;
237 BOOLEAN Breakout;
238
239 CONTEXT_ENTER (Context, "Scope / Device");
240 CONTEXT_HAS_WORK (Context);
241 CONTEXT_INCREASE_NESTING (Context);
242
243 ScopeStart = Context->CurrentOpcode;
244 CurrentPath = Context->CurrentIdentifier;
245
246 if (ParsePkgLength (
247 Context,
248 &PkgLength
249 ) != EFI_SUCCESS)
250 {
251 return EFI_DEVICE_ERROR;
252 }
253
254 if ((UINT32)(Context->TableEnd - ScopeStart) < PkgLength) {
255 return EFI_DEVICE_ERROR;
256 }
257
258 ScopeEnd = ScopeStart + PkgLength;
259
260 CONTEXT_PEEK_BYTES (Context, 1);
261
262 if (ParseNameString (
263 Context,
264 &ScopeName,
265 &ScopeNameLength,
266 &IsRootPath
267 ) != EFI_SUCCESS)
268 {
269 return EFI_DEVICE_ERROR;
270 }
271
272 ScopeNameStart = ScopeName;
273
274 if (Context->CurrentOpcode > ScopeEnd) {
275 return EFI_DEVICE_ERROR;
276 }
277
278 if (IsRootPath) {
279 Context->CurrentIdentifier = Context->PathStart;
280 }
281
282 //
283 // Both exit conditions in these loops are for cases when there can be
284 // root-relative scopes within the current scope that does not match ours at all.
285 //
286 Breakout = FALSE;
287
288 for (Index = 0; Index < ScopeNameLength; ++Index) {
289 if (Context->CurrentIdentifier == Context->PathEnd) {
290 Context->CurrentIdentifier = Context->PathStart;
291 break;
292 }
293
294 for (Index2 = 0; Index2 < IDENT_LEN; ++Index2) {
295 if (*(ScopeName + Index2) != *((UINT8 *)Context->CurrentIdentifier + (IDENT_LEN - Index2 - 1))) {
296 Context->CurrentIdentifier = Context->PathStart;
297 Breakout = TRUE;
298 break;
299 }
300 }
301
302 if (Breakout) {
303 break;
304 }
305
306 Context->CurrentIdentifier += 1;
307 ScopeName += 4;
308 }
309
310 if (Context->CurrentIdentifier == Context->PathEnd) {
311 Context->EntriesFound += 1;
312 if (Context->EntriesFound == Context->RequiredEntry) {
313 *Result = ScopeStart - 1;
314 return EFI_SUCCESS;
315 }
316
317 //
318 // Same issue with root-relative scopes. Retry search.
319 //
320 Context->CurrentIdentifier = Context->PathStart;
321 }
322
323 PRINT_ACPI_NAME ("Entered scope", ScopeNameStart, ScopeNameLength);
324
325 while (Context->CurrentOpcode < ScopeEnd) {
326 Status = InternalAcpiParseTerm (
327 Context,
328 Result
329 );
330
331 if (Status != EFI_NOT_FOUND) {
332 return Status;
333 }
334 }
335
336 PRINT_ACPI_NAME ("Left scope", ScopeNameStart, ScopeNameLength);
337
338 Context->CurrentIdentifier = CurrentPath;
339 CONTEXT_DECREASE_NESTING (Context);
340 return EFI_NOT_FOUND;
341}
342
352STATIC
353EFI_STATUS
355 IN OUT ACPI_PARSER_CONTEXT *Context
356 )
357{
358 UINT32 PkgLength;
359 UINT8 *CurrentOpcode;
360
361 CONTEXT_ENTER (Context, "Name");
362 CONTEXT_HAS_WORK (Context);
363 CONTEXT_INCREASE_NESTING (Context);
364
365 if (ParseNameString (
366 Context,
367 NULL,
368 NULL,
369 NULL
370 ) != EFI_SUCCESS)
371 {
372 return EFI_DEVICE_ERROR;
373 }
374
375 CONTEXT_PEEK_BYTES (Context, 1);
376
377 switch (Context->CurrentOpcode[0]) {
378 case AML_BYTE_PREFIX:
379 CONTEXT_CONSUME_BYTES (Context, 2);
380 break;
381
382 case AML_WORD_PREFIX:
383 CONTEXT_CONSUME_BYTES (Context, 3);
384 break;
385
386 case AML_DWORD_PREFIX:
387 CONTEXT_CONSUME_BYTES (Context, 5);
388 break;
389
390 case AML_QWORD_PREFIX:
391 CONTEXT_CONSUME_BYTES (Context, 9);
392 break;
393
394 case AML_STRING_PREFIX:
395 do {
396 CONTEXT_ADVANCE_OPCODE (Context);
397 } while (Context->CurrentOpcode[0] >= 0x01 && Context->CurrentOpcode[0] <= 0x7f);
398
399 if (Context->CurrentOpcode[0] != AML_ZERO_OP) {
400 return EFI_DEVICE_ERROR;
401 }
402
403 CONTEXT_CONSUME_BYTES (Context, 1);
404 break;
405
406 case AML_ZERO_OP:
407 case AML_ONE_OP:
408 case AML_ONES_OP:
409 CONTEXT_CONSUME_BYTES (Context, 1);
410 break;
411
412 case AML_EXT_OP:
413 CONTEXT_CONSUME_BYTES (Context, 2);
414 break;
415
416 case AML_BUFFER_OP:
417 case AML_PACKAGE_OP:
418 case AML_VAR_PACKAGE_OP:
419 CONTEXT_ADVANCE_OPCODE (Context);
420 CurrentOpcode = Context->CurrentOpcode;
421
422 if (ParsePkgLength (
423 Context,
424 &PkgLength
425 ) != EFI_SUCCESS)
426 {
427 return EFI_DEVICE_ERROR;
428 }
429
430 Context->CurrentOpcode = CurrentOpcode;
431 CONTEXT_CONSUME_BYTES (Context, PkgLength);
432 break;
433
434 default:
435 return EFI_DEVICE_ERROR;
436 }
437
438 CONTEXT_DECREASE_NESTING (Context);
439 return EFI_NOT_FOUND;
440}
441
454STATIC
455EFI_STATUS
457 IN OUT ACPI_PARSER_CONTEXT *Context,
458 OUT UINT8 **Result
459 )
460{
461 UINT32 PkgLength;
462 UINT8 *BankStart;
463 UINT8 *BankEnd;
464 UINT8 *Name;
465 UINT8 NameLength;
466 UINT8 Index;
467
468 CONTEXT_ENTER (Context, "BankField");
469 CONTEXT_HAS_WORK (Context);
470 CONTEXT_INCREASE_NESTING (Context);
471
472 BankStart = Context->CurrentOpcode;
473
474 if (ParsePkgLength (
475 Context,
476 &PkgLength
477 ) != EFI_SUCCESS)
478 {
479 return EFI_DEVICE_ERROR;
480 }
481
482 if ((UINT32)(Context->TableEnd - BankStart) < PkgLength) {
483 return EFI_DEVICE_ERROR;
484 }
485
486 BankEnd = BankStart + PkgLength;
487
488 CONTEXT_PEEK_BYTES (Context, 1);
489
490 if (ParseNameString (
491 Context,
492 &Name,
493 &NameLength,
494 NULL
495 ) != EFI_SUCCESS)
496 {
497 return EFI_DEVICE_ERROR;
498 }
499
500 if (Context->CurrentOpcode >= BankEnd) {
501 return EFI_DEVICE_ERROR;
502 }
503
504 if (NameLength != 1) {
505 return EFI_DEVICE_ERROR;
506 }
507
508 for (Index = 0; Index < IDENT_LEN; ++Index) {
509 if (*(Name + Index) != *((UINT8 *)Context->CurrentIdentifier + (IDENT_LEN - Index - 1))) {
510 Context->CurrentOpcode = BankEnd;
511 CONTEXT_DECREASE_NESTING (Context);
512 return EFI_NOT_FOUND;
513 }
514 }
515
516 Context->CurrentIdentifier += 1;
517
518 CONTEXT_PEEK_BYTES (Context, 1);
519
520 if (Context->CurrentIdentifier == Context->PathEnd) {
521 //
522 // FIXME: This looks weird. If it is a match, should not it return success?
523 //
524 Context->CurrentIdentifier -= 1;
525 if (ParseNameString (
526 Context,
527 &Name,
528 &NameLength,
529 NULL
530 ) != EFI_SUCCESS)
531 {
532 return EFI_DEVICE_ERROR;
533 }
534
535 Context->CurrentOpcode = BankEnd;
536 CONTEXT_DECREASE_NESTING (Context);
537 return EFI_NOT_FOUND;
538 }
539
540 if (ParseNameString (
541 Context,
542 &Name,
543 &NameLength,
544 NULL
545 ) != EFI_SUCCESS)
546 {
547 return EFI_DEVICE_ERROR;
548 }
549
550 if (Context->CurrentOpcode > BankEnd) {
551 return EFI_DEVICE_ERROR;
552 }
553
554 if (NameLength != 1) {
555 return EFI_DEVICE_ERROR;
556 }
557
558 for (Index = 0; Index < IDENT_LEN; ++Index) {
559 if (*(Name + Index) != *((UINT8 *)Context->CurrentIdentifier + (IDENT_LEN - Index - 1))) {
560 Context->CurrentOpcode = BankEnd;
561 Context->CurrentIdentifier -= 1;
562 CONTEXT_DECREASE_NESTING (Context);
563 return EFI_NOT_FOUND;
564 }
565 }
566
567 if (Context->CurrentIdentifier + 1 != Context->PathEnd) {
568 Context->CurrentOpcode = BankEnd;
569 Context->CurrentIdentifier -= 1;
570 CONTEXT_DECREASE_NESTING (Context);
571 return EFI_NOT_FOUND;
572 }
573
574 Context->EntriesFound += 1;
575
576 if (Context->EntriesFound != Context->RequiredEntry) {
577 Context->CurrentOpcode = BankEnd;
578 Context->CurrentIdentifier -= 1;
579 CONTEXT_DECREASE_NESTING (Context);
580 return EFI_NOT_FOUND;
581 }
582
583 *Result = BankStart - 1;
584 return EFI_SUCCESS;
585}
586
601STATIC
602EFI_STATUS
604 IN OUT ACPI_PARSER_CONTEXT *Context,
605 OUT UINT8 **Result
606 )
607{
608 UINT8 *FieldStart;
609 UINT8 *FieldOpcode;
610 UINT8 *Name;
611 UINT8 NameLength;
612 UINT8 Index;
613 BOOLEAN Matched;
614
615 CONTEXT_ENTER (Context, "CreateField");
616 CONTEXT_HAS_WORK (Context);
617 CONTEXT_INCREASE_NESTING (Context);
618
619 FieldStart = Context->CurrentOpcode;
620 FieldOpcode = Context->CurrentOpcode - 1;
621
622 switch (Context->CurrentOpcode[0]) {
623 case AML_ARG0:
624 case AML_ARG1:
625 case AML_ARG2:
626 case AML_ARG3:
627 case AML_ARG4:
628 case AML_ARG5:
629 case AML_ARG6:
630 CONTEXT_CONSUME_BYTES (Context, 5);
631
632 if (*FieldOpcode == AML_EXT_CREATE_FIELD_OP) {
633 CONTEXT_CONSUME_BYTES (Context, 4);
634 }
635
636 CONTEXT_PEEK_BYTES (Context, 1);
637
638 if (ParseNameString (
639 Context,
640 NULL,
641 NULL,
642 NULL
643 ) != EFI_SUCCESS)
644 {
645 return EFI_DEVICE_ERROR;
646 }
647
648 CONTEXT_DECREASE_NESTING (Context);
649 return EFI_NOT_FOUND;
650
651 default:
652
653 if (ParseNameString (
654 Context,
655 &Name,
656 &NameLength,
657 NULL
658 ) != EFI_SUCCESS)
659 {
660 return EFI_DEVICE_ERROR;
661 }
662
663 if (NameLength != 1) {
664 return EFI_DEVICE_ERROR;
665 }
666
667 Matched = TRUE;
668 for (Index = 0; Index < IDENT_LEN; Index++) {
669 if (*(Name + Index) != *((UINT8 *)Context->CurrentIdentifier + (IDENT_LEN - Index - 1))) {
670 Matched = FALSE;
671 break;
672 }
673 }
674
675 CONTEXT_PEEK_BYTES (Context, 1);
676
677 switch (Context->CurrentOpcode[0]) {
678 case AML_ZERO_OP:
679 case AML_ONE_OP:
680 CONTEXT_CONSUME_BYTES (Context, 1);
681 break;
682
683 case AML_BYTE_PREFIX:
684 CONTEXT_CONSUME_BYTES (Context, 2);
685 break;
686
687 case AML_WORD_PREFIX:
688 CONTEXT_CONSUME_BYTES (Context, 3);
689 break;
690
691 case AML_DWORD_PREFIX:
692 CONTEXT_CONSUME_BYTES (Context, 5);
693 break;
694
695 case AML_QWORD_PREFIX:
696 CONTEXT_CONSUME_BYTES (Context, 9);
697 break;
698 }
699
700 if (*FieldOpcode == AML_EXT_CREATE_FIELD_OP) {
701 CONTEXT_CONSUME_BYTES (Context, 1);
702 }
703
704 CONTEXT_PEEK_BYTES (Context, 1);
705
706 if (ParseNameString (
707 Context,
708 &Name,
709 &NameLength,
710 NULL
711 ) != EFI_SUCCESS)
712 {
713 return EFI_DEVICE_ERROR;
714 }
715
716 if (NameLength != 1) {
717 return EFI_DEVICE_ERROR;
718 }
719
720 if (!Matched) {
721 CONTEXT_DECREASE_NESTING (Context);
722 return EFI_NOT_FOUND;
723 }
724
725 Context->CurrentIdentifier += 1;
726
727 for (Index = 0; Index < IDENT_LEN; Index++) {
728 if (*(Name + Index) != *((UINT8 *)Context->CurrentIdentifier + (IDENT_LEN - Index - 1))) {
729 CONTEXT_DECREASE_NESTING (Context);
730 Context->CurrentIdentifier--;
731 return EFI_NOT_FOUND;
732 }
733 }
734
735 Context->CurrentIdentifier += 1;
736
737 if (Context->CurrentIdentifier != Context->PathEnd) {
738 CONTEXT_DECREASE_NESTING (Context);
739 Context->CurrentIdentifier -= 2;
740 return EFI_NOT_FOUND;
741 }
742
743 Context->EntriesFound += 1;
744
745 if (Context->EntriesFound != Context->RequiredEntry) {
746 CONTEXT_DECREASE_NESTING (Context);
747 Context->CurrentIdentifier -= 2;
748 return EFI_NOT_FOUND;
749 }
750
751 *Result = FieldStart - 1;
752 return EFI_SUCCESS;
753 }
754}
755
765STATIC
766EFI_STATUS
768 IN OUT ACPI_PARSER_CONTEXT *Context
769 )
770{
771 CONTEXT_ENTER (Context, "External");
772 CONTEXT_HAS_WORK (Context);
773 CONTEXT_INCREASE_NESTING (Context);
774
775 if (ParseNameString (
776 Context,
777 NULL,
778 NULL,
779 NULL
780 ) != EFI_SUCCESS)
781 {
782 return EFI_DEVICE_ERROR;
783 }
784
785 CONTEXT_CONSUME_BYTES (Context, 2);
786 CONTEXT_DECREASE_NESTING (Context);
787 return EFI_NOT_FOUND;
788}
789
799STATIC
800EFI_STATUS
802 IN OUT ACPI_PARSER_CONTEXT *Context
803 )
804{
805 CONTEXT_ENTER (Context, "OpRegion");
806 CONTEXT_HAS_WORK (Context);
807 CONTEXT_INCREASE_NESTING (Context);
808
809 if (ParseNameString (
810 Context,
811 NULL,
812 NULL,
813 NULL
814 ) != EFI_SUCCESS)
815 {
816 return EFI_DEVICE_ERROR;
817 }
818
819 CONTEXT_ADVANCE_OPCODE (Context);
820
821 switch (Context->CurrentOpcode[0]) {
822 case AML_ZERO_OP:
823 case AML_ONE_OP:
824 CONTEXT_CONSUME_BYTES (Context, 1);
825 break;
826
827 case AML_BYTE_PREFIX:
828 CONTEXT_CONSUME_BYTES (Context, 2);
829 break;
830
831 case AML_WORD_PREFIX:
832 CONTEXT_CONSUME_BYTES (Context, 3);
833 break;
834
835 case AML_DWORD_PREFIX:
836 CONTEXT_CONSUME_BYTES (Context, 5);
837 break;
838
839 case AML_QWORD_PREFIX:
840 CONTEXT_CONSUME_BYTES (Context, 9);
841 break;
842
843 case AML_ADD_OP:
844 case AML_SUBTRACT_OP:
845 CONTEXT_ADVANCE_OPCODE (Context);
846
847 switch (Context->CurrentOpcode[0]) {
848 case AML_ZERO_OP:
849 case AML_ONE_OP:
850 CONTEXT_CONSUME_BYTES (Context, 1);
851 break;
852
853 case AML_BYTE_PREFIX:
854 CONTEXT_CONSUME_BYTES (Context, 2);
855 break;
856
857 case AML_WORD_PREFIX:
858 CONTEXT_CONSUME_BYTES (Context, 3);
859 break;
860
861 case AML_DWORD_PREFIX:
862 CONTEXT_CONSUME_BYTES (Context, 5);
863 break;
864
865 case AML_QWORD_PREFIX:
866 CONTEXT_CONSUME_BYTES (Context, 9);
867 break;
868
869 default:
870 if (ParseNameString (
871 Context,
872 NULL,
873 NULL,
874 NULL
875 ) != EFI_SUCCESS)
876 {
877 return EFI_DEVICE_ERROR;
878 }
879
880 break;
881 }
882
883 CONTEXT_PEEK_BYTES (Context, 1);
884
885 switch (Context->CurrentOpcode[0]) {
886 case AML_ZERO_OP:
887 case AML_ONE_OP:
888 CONTEXT_CONSUME_BYTES (Context, 1);
889 break;
890
891 case AML_BYTE_PREFIX:
892 CONTEXT_CONSUME_BYTES (Context, 2);
893 break;
894
895 case AML_WORD_PREFIX:
896 CONTEXT_CONSUME_BYTES (Context, 3);
897 break;
898
899 case AML_DWORD_PREFIX:
900 CONTEXT_CONSUME_BYTES (Context, 5);
901 break;
902
903 case AML_QWORD_PREFIX:
904 CONTEXT_CONSUME_BYTES (Context, 9);
905 break;
906
907 default:
908 if (ParseNameString (
909 Context,
910 NULL,
911 NULL,
912 NULL
913 ) != EFI_SUCCESS)
914 {
915 return EFI_DEVICE_ERROR;
916 }
917
918 break;
919 }
920
921 CONTEXT_PEEK_BYTES (Context, 1);
922
923 /* Fallthrough */
924 default:
925 if (ParseNameString (
926 Context,
927 NULL,
928 NULL,
929 NULL
930 ) != EFI_SUCCESS)
931 {
932 return EFI_DEVICE_ERROR;
933 }
934
935 break;
936 }
937
938 CONTEXT_PEEK_BYTES (Context, 1);
939
940 switch (Context->CurrentOpcode[0]) {
941 case AML_ZERO_OP:
942 case AML_ONE_OP:
943 CONTEXT_CONSUME_BYTES (Context, 1);
944 break;
945
946 case AML_BYTE_PREFIX:
947 CONTEXT_CONSUME_BYTES (Context, 2);
948 break;
949
950 case AML_WORD_PREFIX:
951 CONTEXT_CONSUME_BYTES (Context, 3);
952 break;
953
954 case AML_DWORD_PREFIX:
955 CONTEXT_CONSUME_BYTES (Context, 5);
956 break;
957
958 case AML_QWORD_PREFIX:
959 CONTEXT_CONSUME_BYTES (Context, 9);
960 break;
961
962 case AML_ADD_OP:
963 case AML_SUBTRACT_OP:
964 CONTEXT_ADVANCE_OPCODE (Context);
965
966 switch (Context->CurrentOpcode[0]) {
967 case AML_ZERO_OP:
968 case AML_ONE_OP:
969 CONTEXT_CONSUME_BYTES (Context, 1);
970 break;
971
972 case AML_BYTE_PREFIX:
973 CONTEXT_CONSUME_BYTES (Context, 2);
974 break;
975
976 case AML_WORD_PREFIX:
977 CONTEXT_CONSUME_BYTES (Context, 3);
978 break;
979
980 case AML_DWORD_PREFIX:
981 CONTEXT_CONSUME_BYTES (Context, 5);
982 break;
983
984 case AML_QWORD_PREFIX:
985 CONTEXT_CONSUME_BYTES (Context, 9);
986 break;
987
988 default:
989 if (ParseNameString (
990 Context,
991 NULL,
992 NULL,
993 NULL
994 ) != EFI_SUCCESS)
995 {
996 return EFI_DEVICE_ERROR;
997 }
998
999 break;
1000 }
1001
1002 CONTEXT_PEEK_BYTES (Context, 1);
1003
1004 switch (Context->CurrentOpcode[0]) {
1005 case AML_ZERO_OP:
1006 case AML_ONE_OP:
1007 CONTEXT_CONSUME_BYTES (Context, 1);
1008 break;
1009
1010 case AML_BYTE_PREFIX:
1011 CONTEXT_CONSUME_BYTES (Context, 2);
1012 break;
1013
1014 case AML_WORD_PREFIX:
1015 CONTEXT_CONSUME_BYTES (Context, 3);
1016 break;
1017
1018 case AML_DWORD_PREFIX:
1019 CONTEXT_CONSUME_BYTES (Context, 5);
1020 break;
1021
1022 case AML_QWORD_PREFIX:
1023 CONTEXT_CONSUME_BYTES (Context, 9);
1024 break;
1025
1026 default:
1027 if (ParseNameString (
1028 Context,
1029 NULL,
1030 NULL,
1031 NULL
1032 ) != EFI_SUCCESS)
1033 {
1034 return EFI_DEVICE_ERROR;
1035 }
1036
1037 break;
1038 }
1039
1040 CONTEXT_PEEK_BYTES (Context, 1);
1041 /* Fallthrough */
1042
1043 default:
1044 if (ParseNameString (
1045 Context,
1046 NULL,
1047 NULL,
1048 NULL
1049 ) != EFI_SUCCESS)
1050 {
1051 return EFI_DEVICE_ERROR;
1052 }
1053
1054 break;
1055 }
1056
1057 CONTEXT_DECREASE_NESTING (Context);
1058 return EFI_NOT_FOUND;
1059}
1060
1070STATIC
1071EFI_STATUS
1073 IN OUT ACPI_PARSER_CONTEXT *Context
1074 )
1075{
1076 UINT32 PkgLength;
1077 UINT8 *CurrentOpcode;
1078
1079 CONTEXT_ENTER (Context, "PowerRes");
1080 CONTEXT_HAS_WORK (Context);
1081 CONTEXT_INCREASE_NESTING (Context);
1082
1083 CurrentOpcode = Context->CurrentOpcode;
1084
1085 if (ParsePkgLength (
1086 Context,
1087 &PkgLength
1088 ) != EFI_SUCCESS)
1089 {
1090 return EFI_DEVICE_ERROR;
1091 }
1092
1093 Context->CurrentOpcode = CurrentOpcode;
1094 CONTEXT_CONSUME_BYTES (Context, PkgLength);
1095 CONTEXT_DECREASE_NESTING (Context);
1096 return EFI_NOT_FOUND;
1097}
1098
1108STATIC
1109EFI_STATUS
1111 IN OUT ACPI_PARSER_CONTEXT *Context
1112 )
1113{
1114 UINT8 *CurrentOpcode;
1115 UINT32 PkgLength;
1116
1117 CONTEXT_ENTER (Context, "Processor");
1118 CONTEXT_HAS_WORK (Context);
1119 CONTEXT_INCREASE_NESTING (Context);
1120
1121 CurrentOpcode = Context->CurrentOpcode;
1122
1123 if (ParsePkgLength (
1124 Context,
1125 &PkgLength
1126 ) != EFI_SUCCESS)
1127 {
1128 return EFI_DEVICE_ERROR;
1129 }
1130
1131 Context->CurrentOpcode = CurrentOpcode;
1132 CONTEXT_CONSUME_BYTES (Context, PkgLength);
1133 CONTEXT_DECREASE_NESTING (Context);
1134 return EFI_NOT_FOUND;
1135}
1136
1146STATIC
1147EFI_STATUS
1149 IN OUT ACPI_PARSER_CONTEXT *Context
1150 )
1151{
1152 UINT8 *CurrentOpcode;
1153 UINT32 PkgLength;
1154
1155 CONTEXT_ENTER (Context, "ThermalZone");
1156 CONTEXT_HAS_WORK (Context);
1157 CONTEXT_INCREASE_NESTING (Context);
1158
1159 CurrentOpcode = Context->CurrentOpcode;
1160
1161 if (ParsePkgLength (
1162 Context,
1163 &PkgLength
1164 ) != EFI_SUCCESS)
1165 {
1166 return EFI_DEVICE_ERROR;
1167 }
1168
1169 Context->CurrentOpcode = CurrentOpcode;
1170 CONTEXT_CONSUME_BYTES (Context, PkgLength);
1171 CONTEXT_DECREASE_NESTING (Context);
1172 return EFI_NOT_FOUND;
1173}
1174
1188STATIC
1189EFI_STATUS
1191 IN OUT ACPI_PARSER_CONTEXT *Context,
1192 OUT UINT8 **Result
1193 )
1194{
1195 UINT8 *MethodStart;
1196 UINT32 *CurrentPath;
1197 UINT32 PkgLength;
1198 UINT8 *MethodEnd;
1199 UINT8 *MethodName;
1200 UINT8 MethodNameLength;
1201 UINT8 Index;
1202 UINT8 Index2;
1203
1204 CONTEXT_ENTER (Context, "Method");
1205 CONTEXT_HAS_WORK (Context);
1206 CONTEXT_INCREASE_NESTING (Context);
1207
1208 MethodStart = Context->CurrentOpcode;
1209 CurrentPath = Context->CurrentIdentifier;
1210
1211 if (ParsePkgLength (
1212 Context,
1213 &PkgLength
1214 ) != EFI_SUCCESS)
1215 {
1216 return EFI_DEVICE_ERROR;
1217 }
1218
1219 if ((UINT32)(Context->TableEnd - MethodStart) < PkgLength) {
1220 return EFI_DEVICE_ERROR;
1221 }
1222
1223 MethodEnd = MethodStart + PkgLength;
1224
1225 if (Context->CurrentOpcode >= MethodEnd) {
1226 return EFI_DEVICE_ERROR;
1227 }
1228
1229 if (ParseNameString (
1230 Context,
1231 &MethodName,
1232 &MethodNameLength,
1233 NULL
1234 ) != EFI_SUCCESS)
1235 {
1236 return EFI_DEVICE_ERROR;
1237 }
1238
1239 if (Context->CurrentOpcode > MethodEnd) {
1240 return EFI_DEVICE_ERROR;
1241 }
1242
1243 for (Index = 0; Index < MethodNameLength; ++Index) {
1244 //
1245 // If the method is within our lookup path but not at it, this is not a match.
1246 //
1247 if (Context->CurrentIdentifier == Context->PathEnd) {
1248 Context->CurrentOpcode = MethodEnd;
1249 Context->CurrentIdentifier = CurrentPath;
1250 CONTEXT_DECREASE_NESTING (Context);
1251 return EFI_NOT_FOUND;
1252 }
1253
1254 for (Index2 = 0; Index2 < IDENT_LEN; Index2++) {
1255 if (*(MethodName + Index2) != *((UINT8 *)Context->CurrentIdentifier + (IDENT_LEN - Index2 - 1))) {
1256 Context->CurrentOpcode = MethodEnd;
1257 Context->CurrentIdentifier = CurrentPath;
1258 CONTEXT_DECREASE_NESTING (Context);
1259 return EFI_NOT_FOUND;
1260 }
1261 }
1262
1263 Context->CurrentIdentifier += 1;
1264 MethodName += 4;
1265 }
1266
1267 if (Context->CurrentIdentifier != Context->PathEnd) {
1268 Context->CurrentOpcode = MethodEnd;
1269 Context->CurrentIdentifier = CurrentPath;
1270 CONTEXT_DECREASE_NESTING (Context);
1271 return EFI_NOT_FOUND;
1272 }
1273
1274 Context->EntriesFound += 1;
1275
1276 if (Context->EntriesFound != Context->RequiredEntry) {
1277 Context->CurrentOpcode = MethodEnd;
1278 Context->CurrentIdentifier = CurrentPath;
1279 CONTEXT_DECREASE_NESTING (Context);
1280 return EFI_NOT_FOUND;
1281 }
1282
1283 *Result = MethodStart - 1;
1284 return EFI_SUCCESS;
1285}
1286
1298STATIC
1299EFI_STATUS
1301 IN OUT ACPI_PARSER_CONTEXT *Context,
1302 OUT UINT8 **Result
1303 )
1304{
1305 UINT32 PkgLength;
1306 UINT8 *IfStart;
1307 UINT32 *CurrentPath;
1308 UINT8 *IfEnd;
1309 EFI_STATUS Status;
1310
1311 CONTEXT_ENTER (Context, "IfElse");
1312 CONTEXT_HAS_WORK (Context);
1313 CONTEXT_INCREASE_NESTING (Context);
1314
1315 IfStart = Context->CurrentOpcode;
1316 CurrentPath = Context->CurrentIdentifier;
1317
1318 if (ParsePkgLength (
1319 Context,
1320 &PkgLength
1321 ) != EFI_SUCCESS)
1322 {
1323 return EFI_DEVICE_ERROR;
1324 }
1325
1326 if ((UINT32)(Context->TableEnd - IfStart) < PkgLength) {
1327 return EFI_DEVICE_ERROR;
1328 }
1329
1330 IfEnd = IfStart + PkgLength;
1331
1332 //
1333 // FIXME: This is broken like hell.
1334 //
1335 Status = EFI_NOT_FOUND;
1336 while (Status != EFI_SUCCESS && Context->CurrentOpcode < IfEnd) {
1337 Status = InternalAcpiParseTerm (Context, Result);
1338 if (Status == EFI_DEVICE_ERROR) {
1339 Context->CurrentOpcode += 1;
1340 }
1341 }
1342
1343 if (Status == EFI_DEVICE_ERROR) {
1344 return EFI_DEVICE_ERROR;
1345 }
1346
1347 if (Status == EFI_SUCCESS) {
1348 CONTEXT_DECREASE_NESTING (Context);
1349 return EFI_SUCCESS;
1350 }
1351
1352 if (Context->CurrentOpcode > IfEnd) {
1353 Context->CurrentOpcode = IfEnd;
1354 }
1355
1356 Context->CurrentIdentifier = CurrentPath;
1357
1358 CONTEXT_PEEK_BYTES (Context, 1);
1359
1360 if (Context->CurrentOpcode[0] == AML_ELSE_OP) {
1361 CONTEXT_ADVANCE_OPCODE (Context);
1362 IfStart = Context->CurrentOpcode;
1363
1364 if (ParsePkgLength (
1365 Context,
1366 &PkgLength
1367 ) != EFI_SUCCESS)
1368 {
1369 return EFI_DEVICE_ERROR;
1370 }
1371
1372 if ((UINT32)(Context->TableEnd - IfStart) < PkgLength) {
1373 return EFI_DEVICE_ERROR;
1374 }
1375
1376 IfEnd = IfStart + PkgLength;
1377
1378 //
1379 // FIXME: This is broken like hell.
1380 //
1381 Status = EFI_NOT_FOUND;
1382 while (Status != EFI_SUCCESS && Context->CurrentOpcode < IfEnd) {
1383 Status = InternalAcpiParseTerm (Context, Result);
1384 if (Status == EFI_DEVICE_ERROR) {
1385 Context->CurrentOpcode += 1;
1386 }
1387 }
1388
1389 if ((Context->CurrentOpcode > IfEnd) || (Status == EFI_DEVICE_ERROR)) {
1390 return EFI_DEVICE_ERROR;
1391 }
1392
1393 if (Status == EFI_SUCCESS) {
1394 CONTEXT_DECREASE_NESTING (Context);
1395 return EFI_SUCCESS;
1396 }
1397
1398 Context->CurrentIdentifier = CurrentPath;
1399 }
1400
1401 CONTEXT_DECREASE_NESTING (Context);
1402 return EFI_NOT_FOUND;
1403}
1404
1414STATIC
1415EFI_STATUS
1417 IN OUT ACPI_PARSER_CONTEXT *Context
1418 )
1419{
1420 CONTEXT_ENTER (Context, "Event");
1421 CONTEXT_HAS_WORK (Context);
1422 CONTEXT_INCREASE_NESTING (Context);
1423
1424 if (ParseNameString (
1425 Context,
1426 NULL,
1427 NULL,
1428 NULL
1429 ) != EFI_SUCCESS)
1430 {
1431 return EFI_DEVICE_ERROR;
1432 }
1433
1434 CONTEXT_DECREASE_NESTING (Context);
1435 return EFI_NOT_FOUND;
1436}
1437
1451STATIC
1452EFI_STATUS
1454 IN OUT ACPI_PARSER_CONTEXT *Context,
1455 OUT UINT8 **Result
1456 )
1457{
1458 UINT8 *FieldStart;
1459 UINT32 PkgLength;
1460 UINT8 *FieldEnd;
1461 UINT8 *FieldName;
1462 UINT8 FieldNameLength;
1463 UINT32 *CurrentPath;
1464 UINT8 Index;
1465 UINT8 Index2;
1466
1467 CONTEXT_ENTER (Context, "Field");
1468 CONTEXT_HAS_WORK (Context);
1469 CONTEXT_INCREASE_NESTING (Context);
1470
1471 FieldStart = Context->CurrentOpcode;
1472
1473 if (ParsePkgLength (
1474 Context,
1475 &PkgLength
1476 ) != EFI_SUCCESS)
1477 {
1478 return EFI_DEVICE_ERROR;
1479 }
1480
1481 if ((UINT32)(Context->TableEnd - FieldStart) < PkgLength) {
1482 return EFI_DEVICE_ERROR;
1483 }
1484
1485 FieldEnd = FieldStart + PkgLength;
1486
1487 if (Context->CurrentOpcode >= FieldEnd) {
1488 return EFI_DEVICE_ERROR;
1489 }
1490
1491 if (ParseNameString (
1492 Context,
1493 &FieldName,
1494 &FieldNameLength,
1495 NULL
1496 ) != EFI_SUCCESS)
1497 {
1498 return EFI_DEVICE_ERROR;
1499 }
1500
1501 if (Context->CurrentOpcode > FieldEnd) {
1502 return EFI_DEVICE_ERROR;
1503 }
1504
1505 CurrentPath = Context->CurrentIdentifier;
1506
1507 for (Index = 0; Index < FieldNameLength; Index++) {
1508 if (Context->CurrentIdentifier == Context->PathEnd) {
1509 Context->CurrentOpcode = FieldEnd;
1510 Context->CurrentIdentifier = CurrentPath;
1511 CONTEXT_DECREASE_NESTING (Context);
1512 return EFI_NOT_FOUND;
1513 }
1514
1515 for (Index2 = 0; Index2 < IDENT_LEN; Index2++) {
1516 if (*(FieldName + Index2) != *((UINT8 *)Context->CurrentIdentifier + (IDENT_LEN - Index2 - 1))) {
1517 Context->CurrentOpcode = FieldEnd;
1518 Context->CurrentIdentifier = CurrentPath;
1519 CONTEXT_DECREASE_NESTING (Context);
1520 return EFI_NOT_FOUND;
1521 }
1522 }
1523
1524 Context->CurrentIdentifier += 1;
1525 FieldName += 4;
1526 }
1527
1528 if (Context->CurrentIdentifier != Context->PathEnd) {
1529 Context->CurrentOpcode = FieldEnd;
1530 Context->CurrentIdentifier = CurrentPath;
1531 CONTEXT_DECREASE_NESTING (Context);
1532 return EFI_NOT_FOUND;
1533 }
1534
1535 Context->EntriesFound += 1;
1536
1537 if (Context->EntriesFound != Context->RequiredEntry) {
1538 Context->CurrentOpcode = FieldEnd;
1539 Context->CurrentIdentifier = CurrentPath;
1540 CONTEXT_DECREASE_NESTING (Context);
1541 return EFI_NOT_FOUND;
1542 }
1543
1544 *Result = FieldStart - 1;
1545 return EFI_SUCCESS;
1546}
1547
1557STATIC
1558EFI_STATUS
1560 IN OUT ACPI_PARSER_CONTEXT *Context
1561 )
1562{
1563 CONTEXT_ENTER (Context, "Mutex");
1564 CONTEXT_HAS_WORK (Context);
1565 CONTEXT_INCREASE_NESTING (Context);
1566
1567 if (ParseNameString (
1568 Context,
1569 NULL,
1570 NULL,
1571 NULL
1572 ) != EFI_SUCCESS)
1573 {
1574 return EFI_DEVICE_ERROR;
1575 }
1576
1577 CONTEXT_CONSUME_BYTES (Context, 1);
1578 CONTEXT_DECREASE_NESTING (Context);
1579 return EFI_NOT_FOUND;
1580}
1581
1595STATIC
1596EFI_STATUS
1598 IN OUT ACPI_PARSER_CONTEXT *Context,
1599 OUT UINT8 **Result
1600 )
1601{
1602 UINT8 *FieldStart;
1603 UINT32 PkgLength;
1604 UINT8 *FieldEnd;
1605 UINT8 *FieldName;
1606 UINT8 FieldNameLength;
1607 UINT8 Index;
1608
1609 CONTEXT_ENTER (Context, "IndexField");
1610 CONTEXT_HAS_WORK (Context);
1611 CONTEXT_INCREASE_NESTING (Context);
1612
1613 FieldStart = Context->CurrentOpcode;
1614
1615 if (ParsePkgLength (
1616 Context,
1617 &PkgLength
1618 ) != EFI_SUCCESS)
1619 {
1620 return EFI_DEVICE_ERROR;
1621 }
1622
1623 if ((UINT32)(Context->TableEnd - FieldStart) < PkgLength) {
1624 return EFI_DEVICE_ERROR;
1625 }
1626
1627 FieldEnd = FieldStart + PkgLength;
1628
1629 if (Context->CurrentOpcode >= FieldEnd) {
1630 return EFI_DEVICE_ERROR;
1631 }
1632
1633 if (ParseNameString (
1634 Context,
1635 &FieldName,
1636 &FieldNameLength,
1637 NULL
1638 ) != EFI_SUCCESS)
1639 {
1640 return EFI_DEVICE_ERROR;
1641 }
1642
1643 if (Context->CurrentOpcode >= FieldEnd) {
1644 return EFI_DEVICE_ERROR;
1645 }
1646
1647 if (FieldNameLength != 1) {
1648 return EFI_DEVICE_ERROR;
1649 }
1650
1651 for (Index = 0; Index < IDENT_LEN; ++Index) {
1652 if (*(FieldName + Index) != *((UINT8 *)Context->CurrentIdentifier + (IDENT_LEN - Index - 1))) {
1653 if (ParseNameString (
1654 Context,
1655 &FieldName,
1656 &FieldNameLength,
1657 NULL
1658 ) != EFI_SUCCESS)
1659 {
1660 return EFI_DEVICE_ERROR;
1661 }
1662
1663 Context->CurrentOpcode = FieldEnd;
1664 CONTEXT_DECREASE_NESTING (Context);
1665 return EFI_NOT_FOUND;
1666 }
1667 }
1668
1669 Context->CurrentIdentifier += 1;
1670
1671 //
1672 // FIXME: Not sure what to do.
1673 //
1674 if (Context->CurrentIdentifier == Context->PathEnd) {
1675 return EFI_DEVICE_ERROR;
1676 }
1677
1678 CONTEXT_PEEK_BYTES (Context, 1);
1679
1680 if (ParseNameString (
1681 Context,
1682 &FieldName,
1683 &FieldNameLength,
1684 NULL
1685 ) != EFI_SUCCESS)
1686 {
1687 return EFI_DEVICE_ERROR;
1688 }
1689
1690 if (Context->CurrentOpcode >= FieldEnd) {
1691 return EFI_DEVICE_ERROR;
1692 }
1693
1694 if (FieldNameLength != 1) {
1695 return EFI_DEVICE_ERROR;
1696 }
1697
1698 for (Index = 0; Index < IDENT_LEN; Index++) {
1699 if (*(FieldName + Index) != *((UINT8 *)Context->CurrentIdentifier + (IDENT_LEN - Index - 1))) {
1700 Context->CurrentOpcode = FieldEnd;
1701 Context->CurrentIdentifier -= 1;
1702 CONTEXT_DECREASE_NESTING (Context);
1703 return EFI_NOT_FOUND;
1704 }
1705 }
1706
1707 if (Context->CurrentIdentifier + 1 != Context->PathEnd) {
1708 Context->CurrentOpcode = FieldEnd;
1709 Context->CurrentIdentifier -= 1;
1710 CONTEXT_DECREASE_NESTING (Context);
1711 return EFI_NOT_FOUND;
1712 }
1713
1714 Context->EntriesFound += 1;
1715
1716 if (Context->EntriesFound != Context->RequiredEntry) {
1717 Context->CurrentOpcode = FieldEnd;
1718 Context->CurrentIdentifier -= 1;
1719 CONTEXT_DECREASE_NESTING (Context);
1720 return EFI_NOT_FOUND;
1721 }
1722
1723 *Result = FieldStart - 1;
1724 return EFI_SUCCESS;
1725}
1726
1727EFI_STATUS
1729 IN OUT ACPI_PARSER_CONTEXT *Context,
1730 OUT UINT8 **Result
1731 )
1732{
1733 EFI_STATUS Status;
1734
1735 CONTEXT_ENTER (Context, "Term");
1736 CONTEXT_HAS_WORK (Context);
1737 ASSERT (Result != NULL);
1738 CONTEXT_INCREASE_NESTING (Context);
1739
1740 DEBUG ((DEBUG_VERBOSE, "Opcode: %x\n", Context->CurrentOpcode[0]));
1741
1742 switch (Context->CurrentOpcode[0]) {
1743 case AML_ALIAS_OP: // Alias
1744 CONTEXT_ADVANCE_OPCODE (Context);
1745 Status = ParseAlias (Context);
1746 break;
1747
1748 case AML_SCOPE_OP: // Scope
1749 CONTEXT_ADVANCE_OPCODE (Context);
1750 Status = ParseScopeOrDevice (Context, Result);
1751 break;
1752
1753 case AML_NAME_OP: // Name
1754 CONTEXT_ADVANCE_OPCODE (Context);
1755 Status = ParseName (Context);
1756 break;
1757
1758 case AML_ZERO_OP: // ZeroOp
1759 case AML_EXT_OP: // ExtOpPrefix
1760 CONTEXT_ADVANCE_OPCODE (Context);
1761 Status = EFI_NOT_FOUND;
1762 break;
1763
1764 case AML_EXT_BANK_FIELD_OP: // BankField
1765 CONTEXT_ADVANCE_OPCODE (Context);
1766 Status = ParseBankField (Context, Result);
1767 break;
1768
1769 case AML_CREATE_DWORD_FIELD_OP: // CreateDwordField
1770 case AML_CREATE_WORD_FIELD_OP: // CreateWordField
1771 case AML_CREATE_BYTE_FIELD_OP: // CreateByteField
1772 case AML_CREATE_BIT_FIELD_OP: // CreateBitField
1773 case AML_CREATE_QWORD_FIELD_OP: // CreateQWordField
1774 case AML_EXT_CREATE_FIELD_OP: // CreateField
1775 CONTEXT_ADVANCE_OPCODE (Context);
1776 Status = ParseCreateField (Context, Result);
1777 break;
1778
1779 case AML_EXTERNAL_OP: // External
1780 CONTEXT_ADVANCE_OPCODE (Context);
1781 Status = ParseExternal (Context);
1782 break;
1783
1784 case AML_EXT_REGION_OP: // OpRegion
1785 CONTEXT_ADVANCE_OPCODE (Context);
1786 Status = ParseOpRegion (Context);
1787 break;
1788
1789 case AML_EXT_POWER_RES_OP: // PowerRes
1790 CONTEXT_ADVANCE_OPCODE (Context);
1791 Status = ParsePowerRes (Context);
1792 break;
1793
1794 case AML_EXT_PROCESSOR_OP: // Processor
1795 CONTEXT_ADVANCE_OPCODE (Context);
1796 Status = ParseProcessor (Context);
1797 break;
1798
1799 case AML_EXT_THERMAL_ZONE_OP: // ThermalZone
1800 CONTEXT_ADVANCE_OPCODE (Context);
1801 Status = ParseThermalZone (Context);
1802 break;
1803
1804 case AML_METHOD_OP: // Method
1805 CONTEXT_ADVANCE_OPCODE (Context);
1806 Status = ParseMethod (Context, Result);
1807 break;
1808
1809 case AML_IF_OP: // IfElse
1810 CONTEXT_ADVANCE_OPCODE (Context);
1811 Status = ParseIfElse (Context, Result);
1812 break;
1813
1814 case AML_EXT_DEVICE_OP: // Device
1815 CONTEXT_ADVANCE_OPCODE (Context);
1816 Status = ParseScopeOrDevice (Context, Result);
1817 break;
1818
1819 case AML_EXT_EVENT_OP: // Event
1820 CONTEXT_ADVANCE_OPCODE (Context);
1821 Status = ParseEvent (Context);
1822 break;
1823
1824 case AML_EXT_FIELD_OP: // Field
1825 CONTEXT_ADVANCE_OPCODE (Context);
1826 Status = ParseField (Context, Result);
1827 break;
1828
1829 case AML_EXT_INDEX_FIELD_OP: // IndexField
1830 CONTEXT_ADVANCE_OPCODE (Context);
1831 Status = ParseIndexField (Context, Result);
1832 break;
1833
1834 case AML_EXT_MUTEX_OP: // Mutex
1835 CONTEXT_ADVANCE_OPCODE (Context);
1836 Status = ParseMutex (Context);
1837 break;
1838
1839 default:
1840 Status = EFI_DEVICE_ERROR;
1841 break;
1842 }
1843
1844 CONTEXT_DECREASE_NESTING (Context);
1845 return Status;
1846}
1847
1859EFI_STATUS
1861 IN CONST CHAR8 *Name,
1862 IN CONST CHAR8 *NameEnd,
1863 OUT UINT32 *OpcodeName
1864 )
1865{
1866 UINT32 CurrentOpcode;
1867 UINT8 NameLength;
1868 UINT8 Index;
1869
1870 CurrentOpcode = 0;
1871 NameLength = (UINT8)(NameEnd - Name);
1872 *OpcodeName = 0;
1873
1874 if (NameLength > IDENT_LEN) {
1875 return EFI_INVALID_PARAMETER;
1876 }
1877
1878 for (Index = 0; Index < IDENT_LEN; ++Index) {
1879 if (Index < NameLength) {
1880 if ((Name[Index] >= 'a') && (Name[Index] <= 'z')) {
1881 CurrentOpcode = AML_NAME_CHAR_A + (Name[Index] - 'a');
1882 } else if ((Name[Index] >= 'A') && (Name[Index] <= 'Z')) {
1883 CurrentOpcode = AML_NAME_CHAR_A + (Name[Index] - 'A');
1884 } else if ((Name[Index] >= '0') && (Name[Index] <= '9')) {
1885 // AML_EXT_REVISION_OP == AML_NAME_INTEGER_0
1886 CurrentOpcode = AML_EXT_REVISION_OP + (Name[Index] - '0');
1887 } else if (Name[Index] == '_') {
1888 CurrentOpcode = AML_NAME_CHAR__;
1889 } else if (Name[Index] == '\\') {
1890 *OpcodeName = 0;
1891 return EFI_INVALID_PARAMETER;
1892 } else {
1893 *OpcodeName = 0;
1894 return EFI_INVALID_PARAMETER;
1895 }
1896 } else {
1897 CurrentOpcode = AML_NAME_CHAR__;
1898 }
1899
1900 *OpcodeName = *OpcodeName << OPCODE_LEN;
1901 *OpcodeName |= CurrentOpcode;
1902 }
1903
1904 return EFI_SUCCESS;
1905}
1906
1916EFI_STATUS
1918 IN OUT ACPI_PARSER_CONTEXT *Context,
1919 IN CONST CHAR8 *PathString
1920 )
1921{
1922 EFI_STATUS Status;
1923 UINT32 Index;
1924 UINT32 PathLength;
1925 CHAR8 *Walker;
1926 CHAR8 *IdentifierStart;
1927 CONST CHAR8 *PathStringEnd;
1928 UINTN AsciiLength;
1929
1930 ASSERT (Context != NULL);
1931 ASSERT (PathString != NULL);
1932
1933 if (PathString[0] == '\\') {
1934 PathString += 1;
1935 }
1936
1937 AsciiLength = AsciiStrLen (PathString);
1938 if (AsciiLength == 0) {
1939 return EFI_INVALID_PARAMETER;
1940 }
1941
1942 PathLength = 0;
1943 PathStringEnd = PathString + AsciiLength;
1944
1945 for (Index = 0; Index < AsciiLength; Index++) {
1946 if (PathString[Index] == '.') {
1947 PathLength += 1;
1948 }
1949 }
1950
1951 PathLength += 1;
1952 Context->PathStart = (UINT32 *)AllocateZeroPool (sizeof (UINT32) * PathLength);
1953 if (Context->PathStart == NULL) {
1954 return EFI_OUT_OF_RESOURCES;
1955 }
1956
1957 Context->CurrentIdentifier = Context->PathStart;
1958 Walker = (CHAR8 *)PathString;
1959 IdentifierStart = (CHAR8 *)PathString;
1960
1961 for (Index = 0; Index < PathLength; ++Index) {
1962 while (*Walker != '.' && Walker < PathStringEnd) {
1963 Walker++;
1964 }
1965
1966 if (Walker - IdentifierStart < 1) {
1967 return EFI_INVALID_PARAMETER;
1968 }
1969
1970 Status = TranslateNameToOpcodes (
1971 IdentifierStart,
1972 Walker,
1973 (UINT32 *)(Context->CurrentIdentifier + Index)
1974 );
1975 if (EFI_ERROR (Status)) {
1976 return Status;
1977 }
1978
1979 ++Walker;
1980 IdentifierStart = Walker;
1981 }
1982
1983 Context->PathEnd = Context->CurrentIdentifier + PathLength;
1984 return EFI_SUCCESS;
1985}
1986
1992VOID
1994 OUT ACPI_PARSER_CONTEXT *Context
1995 )
1996{
1997 ASSERT (Context != NULL);
1998
1999 ZeroMem (Context, sizeof (*Context));
2000}
2001
2007VOID
2009 IN OUT ACPI_PARSER_CONTEXT *Context
2010 )
2011{
2012 if (Context->PathStart != NULL) {
2013 FreePool (Context->PathStart);
2014 Context->PathStart = NULL;
2015 }
2016
2017 ZeroMem (Context, sizeof (*Context));
2018}
2019
2020EFI_STATUS
2022 IN UINT8 *Table,
2023 IN CONST CHAR8 *PathString,
2024 IN UINT8 Entry,
2025 OUT UINT32 *Offset,
2026 IN UINT32 TableLength OPTIONAL
2027 )
2028{
2029 EFI_STATUS Status;
2030 UINT8 *Result;
2031 ACPI_PARSER_CONTEXT Context;
2032
2033 ASSERT (Table != NULL);
2034 ASSERT (PathString != NULL);
2035 ASSERT (Offset != NULL);
2036
2037 if (TableLength > 0) {
2038 if (TableLength < sizeof (EFI_ACPI_COMMON_HEADER)) {
2039 DEBUG ((DEBUG_VERBOSE, "OCA: Got bad table format which does not specify its length!\n"));
2040 return EFI_LOAD_ERROR;
2041 }
2042
2043 //
2044 // We do not check length here, mainly because TableLength > 0 is for fuzzing.
2045 //
2046 } else {
2047 TableLength = ((EFI_ACPI_COMMON_HEADER *)Table)->Length;
2048 }
2049
2050 if (TableLength <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
2051 DEBUG ((DEBUG_VERBOSE, "OCA: Bad or unsupported table header!\n"));
2052 return EFI_DEVICE_ERROR;
2053 }
2054
2055 InitContext (&Context);
2056
2057 Context.CurrentOpcode = Table;
2058 Context.RequiredEntry = Entry;
2059 Context.TableStart = Table;
2060 Context.TableEnd = Table + TableLength;
2061 Context.CurrentOpcode += sizeof (EFI_ACPI_DESCRIPTION_HEADER);
2062
2063 Status = GetOpcodeArray (
2064 &Context,
2065 PathString
2066 );
2067
2068 if (EFI_ERROR (Status)) {
2069 ClearContext (&Context);
2070 return Status;
2071 }
2072
2073 while (Context.CurrentOpcode < Context.TableEnd) {
2074 Status = InternalAcpiParseTerm (&Context, &Result);
2075
2076 if (!EFI_ERROR (Status)) {
2077 *Offset = (UINT32)(Result - Table);
2078 ClearContext (&Context);
2079 return EFI_SUCCESS;
2080 }
2081
2082 if (Status != EFI_NOT_FOUND) {
2083 ClearContext (&Context);
2084 return Status;
2085 }
2086 }
2087
2088 ClearContext (&Context);
2089 return EFI_NOT_FOUND;
2090}
STATIC EFI_STATUS ParseIndexField(IN OUT ACPI_PARSER_CONTEXT *Context, OUT UINT8 **Result)
STATIC EFI_STATUS ParseOpRegion(IN OUT ACPI_PARSER_CONTEXT *Context)
Definition AcpiParser.c:801
STATIC EFI_STATUS ParseExternal(IN OUT ACPI_PARSER_CONTEXT *Context)
Definition AcpiParser.c:767
STATIC EFI_STATUS ParseNameString(IN OUT ACPI_PARSER_CONTEXT *Context, IN OUT UINT8 **NamePathStart OPTIONAL, IN OUT UINT8 *PathLength OPTIONAL, IN OUT UINT8 *IsRootPath OPTIONAL)
Definition AcpiParser.c:35
VOID InitContext(OUT ACPI_PARSER_CONTEXT *Context)
STATIC EFI_STATUS ParsePowerRes(IN OUT ACPI_PARSER_CONTEXT *Context)
STATIC EFI_STATUS ParsePkgLength(IN OUT ACPI_PARSER_CONTEXT *Context, OUT UINT32 *PkgLength)
Definition AcpiParser.c:123
STATIC EFI_STATUS ParseMethod(IN OUT ACPI_PARSER_CONTEXT *Context, OUT UINT8 **Result)
STATIC EFI_STATUS ParseName(IN OUT ACPI_PARSER_CONTEXT *Context)
Definition AcpiParser.c:354
STATIC EFI_STATUS ParseCreateField(IN OUT ACPI_PARSER_CONTEXT *Context, OUT UINT8 **Result)
Definition AcpiParser.c:603
STATIC EFI_STATUS ParseProcessor(IN OUT ACPI_PARSER_CONTEXT *Context)
EFI_STATUS InternalAcpiParseTerm(IN OUT ACPI_PARSER_CONTEXT *Context, OUT UINT8 **Result)
EFI_STATUS TranslateNameToOpcodes(IN CONST CHAR8 *Name, IN CONST CHAR8 *NameEnd, OUT UINT32 *OpcodeName)
STATIC EFI_STATUS ParseScopeOrDevice(IN OUT ACPI_PARSER_CONTEXT *Context, OUT UINT8 **Result)
Definition AcpiParser.c:221
STATIC EFI_STATUS ParseEvent(IN OUT ACPI_PARSER_CONTEXT *Context)
EFI_STATUS GetOpcodeArray(IN OUT ACPI_PARSER_CONTEXT *Context, IN CONST CHAR8 *PathString)
STATIC EFI_STATUS ParseAlias(IN OUT ACPI_PARSER_CONTEXT *Context)
Definition AcpiParser.c:172
STATIC EFI_STATUS ParseField(IN OUT ACPI_PARSER_CONTEXT *Context, OUT UINT8 **Result)
EFI_STATUS AcpiFindEntryInMemory(IN UINT8 *Table, IN CONST CHAR8 *PathString, IN UINT8 Entry, OUT UINT32 *Offset, IN UINT32 TableLength OPTIONAL)
STATIC EFI_STATUS ParseMutex(IN OUT ACPI_PARSER_CONTEXT *Context)
STATIC EFI_STATUS ParseIfElse(IN OUT ACPI_PARSER_CONTEXT *Context, OUT UINT8 **Result)
VOID ClearContext(IN OUT ACPI_PARSER_CONTEXT *Context)
STATIC EFI_STATUS ParseThermalZone(IN OUT ACPI_PARSER_CONTEXT *Context)
STATIC EFI_STATUS ParseBankField(IN OUT ACPI_PARSER_CONTEXT *Context, OUT UINT8 **Result)
Definition AcpiParser.c:456
#define IDENT_LEN
Definition AcpiParser.h:51
#define CONTEXT_CONSUME_BYTES(Context, Bytes)
Definition AcpiParser.h:129
#define CONTEXT_ADVANCE_OPCODE(Context)
Definition AcpiParser.h:141
#define CONTEXT_PEEK_BYTES(Context, Bytes)
Definition AcpiParser.h:120
#define PRINT_ACPI_NAME(Str, Name, Length)
Definition AcpiParser.h:70
#define CONTEXT_INCREASE_NESTING(Context)
Definition AcpiParser.h:101
#define CONTEXT_HAS_WORK(Context)
Definition AcpiParser.h:85
#define CONTEXT_DECREASE_NESTING(Context)
Definition AcpiParser.h:112
#define OPCODE_LEN
Definition AcpiParser.h:52
#define CONTEXT_ENTER(Context, Name)
Definition AcpiParser.h:58
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define ASSERT(x)
Definition coder.h:55