1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acresrc.h"
47
48#define _COMPONENT ACPI_UTILITIES
49ACPI_MODULE_NAME("utresrc")
50#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER)
51
52
53
54
55const char *acpi_gbl_bm_decode[] = {
56 "NotBusMaster",
57 "BusMaster"
58};
59
60const char *acpi_gbl_config_decode[] = {
61 "0 - Good Configuration",
62 "1 - Acceptable Configuration",
63 "2 - Suboptimal Configuration",
64 "3 - ***Invalid Configuration***",
65};
66
67const char *acpi_gbl_consume_decode[] = {
68 "ResourceProducer",
69 "ResourceConsumer"
70};
71
72const char *acpi_gbl_dec_decode[] = {
73 "PosDecode",
74 "SubDecode"
75};
76
77const char *acpi_gbl_he_decode[] = {
78 "Level",
79 "Edge"
80};
81
82const char *acpi_gbl_io_decode[] = {
83 "Decode10",
84 "Decode16"
85};
86
87const char *acpi_gbl_ll_decode[] = {
88 "ActiveHigh",
89 "ActiveLow"
90};
91
92const char *acpi_gbl_max_decode[] = {
93 "MaxNotFixed",
94 "MaxFixed"
95};
96
97const char *acpi_gbl_mem_decode[] = {
98 "NonCacheable",
99 "Cacheable",
100 "WriteCombining",
101 "Prefetchable"
102};
103
104const char *acpi_gbl_min_decode[] = {
105 "MinNotFixed",
106 "MinFixed"
107};
108
109const char *acpi_gbl_mtp_decode[] = {
110 "AddressRangeMemory",
111 "AddressRangeReserved",
112 "AddressRangeACPI",
113 "AddressRangeNVS"
114};
115
116const char *acpi_gbl_rng_decode[] = {
117 "InvalidRanges",
118 "NonISAOnlyRanges",
119 "ISAOnlyRanges",
120 "EntireRange"
121};
122
123const char *acpi_gbl_rw_decode[] = {
124 "ReadOnly",
125 "ReadWrite"
126};
127
128const char *acpi_gbl_shr_decode[] = {
129 "Exclusive",
130 "Shared"
131};
132
133const char *acpi_gbl_siz_decode[] = {
134 "Transfer8",
135 "Transfer8_16",
136 "Transfer16",
137 "InvalidSize"
138};
139
140const char *acpi_gbl_trs_decode[] = {
141 "DenseTranslation",
142 "SparseTranslation"
143};
144
145const char *acpi_gbl_ttp_decode[] = {
146 "TypeStatic",
147 "TypeTranslation"
148};
149
150const char *acpi_gbl_typ_decode[] = {
151 "Compatibility",
152 "TypeA",
153 "TypeB",
154 "TypeF"
155};
156
157const char *acpi_gbl_ppc_decode[] = {
158 "PullDefault",
159 "PullUp",
160 "PullDown",
161 "PullNone"
162};
163
164const char *acpi_gbl_ior_decode[] = {
165 "IoRestrictionNone",
166 "IoRestrictionInputOnly",
167 "IoRestrictionOutputOnly",
168 "IoRestrictionNoneAndPreserve"
169};
170
171const char *acpi_gbl_dts_decode[] = {
172 "Width8bit",
173 "Width16bit",
174 "Width32bit",
175 "Width64bit",
176 "Width128bit",
177 "Width256bit",
178};
179
180
181
182const char *acpi_gbl_ct_decode[] = {
183 "Interrupt",
184 "I/O"
185};
186
187
188
189const char *acpi_gbl_sbt_decode[] = {
190 "/* UNKNOWN serial bus type */",
191 "I2C",
192 "SPI",
193 "UART"
194};
195
196
197
198const char *acpi_gbl_am_decode[] = {
199 "AddressingMode7Bit",
200 "AddressingMode10Bit"
201};
202
203
204
205const char *acpi_gbl_sm_decode[] = {
206 "ControllerInitiated",
207 "DeviceInitiated"
208};
209
210
211
212const char *acpi_gbl_wm_decode[] = {
213 "FourWireMode",
214 "ThreeWireMode"
215};
216
217
218
219const char *acpi_gbl_cph_decode[] = {
220 "ClockPhaseFirst",
221 "ClockPhaseSecond"
222};
223
224
225
226const char *acpi_gbl_cpo_decode[] = {
227 "ClockPolarityLow",
228 "ClockPolarityHigh"
229};
230
231
232
233const char *acpi_gbl_dp_decode[] = {
234 "PolarityLow",
235 "PolarityHigh"
236};
237
238
239
240const char *acpi_gbl_ed_decode[] = {
241 "LittleEndian",
242 "BigEndian"
243};
244
245
246
247const char *acpi_gbl_bpb_decode[] = {
248 "DataBitsFive",
249 "DataBitsSix",
250 "DataBitsSeven",
251 "DataBitsEight",
252 "DataBitsNine",
253 "/* UNKNOWN Bits per byte */",
254 "/* UNKNOWN Bits per byte */",
255 "/* UNKNOWN Bits per byte */"
256};
257
258
259
260const char *acpi_gbl_sb_decode[] = {
261 "StopBitsNone",
262 "StopBitsOne",
263 "StopBitsOnePlusHalf",
264 "StopBitsTwo"
265};
266
267
268
269const char *acpi_gbl_fc_decode[] = {
270 "FlowControlNone",
271 "FlowControlHardware",
272 "FlowControlXON",
273 "/* UNKNOWN flow control keyword */"
274};
275
276
277
278const char *acpi_gbl_pt_decode[] = {
279 "ParityTypeNone",
280 "ParityTypeEven",
281 "ParityTypeOdd",
282 "ParityTypeMark",
283 "ParityTypeSpace",
284 "/* UNKNOWN parity keyword */",
285 "/* UNKNOWN parity keyword */",
286 "/* UNKNOWN parity keyword */"
287};
288
289#endif
290
291
292
293
294
295const u8 acpi_gbl_resource_aml_sizes[] = {
296
297
298 0,
299 0,
300 0,
301 0,
302 ACPI_AML_SIZE_SMALL(struct aml_resource_irq),
303 ACPI_AML_SIZE_SMALL(struct aml_resource_dma),
304 ACPI_AML_SIZE_SMALL(struct aml_resource_start_dependent),
305 ACPI_AML_SIZE_SMALL(struct aml_resource_end_dependent),
306 ACPI_AML_SIZE_SMALL(struct aml_resource_io),
307 ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_io),
308 ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_dma),
309 0,
310 0,
311 0,
312 ACPI_AML_SIZE_SMALL(struct aml_resource_vendor_small),
313 ACPI_AML_SIZE_SMALL(struct aml_resource_end_tag),
314
315
316
317 0,
318 ACPI_AML_SIZE_LARGE(struct aml_resource_memory24),
319 ACPI_AML_SIZE_LARGE(struct aml_resource_generic_register),
320 0,
321 ACPI_AML_SIZE_LARGE(struct aml_resource_vendor_large),
322 ACPI_AML_SIZE_LARGE(struct aml_resource_memory32),
323 ACPI_AML_SIZE_LARGE(struct aml_resource_fixed_memory32),
324 ACPI_AML_SIZE_LARGE(struct aml_resource_address32),
325 ACPI_AML_SIZE_LARGE(struct aml_resource_address16),
326 ACPI_AML_SIZE_LARGE(struct aml_resource_extended_irq),
327 ACPI_AML_SIZE_LARGE(struct aml_resource_address64),
328 ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64),
329 ACPI_AML_SIZE_LARGE(struct aml_resource_gpio),
330 0,
331 ACPI_AML_SIZE_LARGE(struct aml_resource_common_serialbus),
332};
333
334const u8 acpi_gbl_resource_aml_serial_bus_sizes[] = {
335 0,
336 ACPI_AML_SIZE_LARGE(struct aml_resource_i2c_serialbus),
337 ACPI_AML_SIZE_LARGE(struct aml_resource_spi_serialbus),
338 ACPI_AML_SIZE_LARGE(struct aml_resource_uart_serialbus),
339};
340
341
342
343
344
345
346
347static const u8 acpi_gbl_resource_types[] = {
348
349
350 0,
351 0,
352 0,
353 0,
354 ACPI_SMALL_VARIABLE_LENGTH,
355 ACPI_FIXED_LENGTH,
356 ACPI_SMALL_VARIABLE_LENGTH,
357 ACPI_FIXED_LENGTH,
358 ACPI_FIXED_LENGTH,
359 ACPI_FIXED_LENGTH,
360 ACPI_FIXED_LENGTH,
361 0,
362 0,
363 0,
364 ACPI_VARIABLE_LENGTH,
365 ACPI_FIXED_LENGTH,
366
367
368
369 0,
370 ACPI_FIXED_LENGTH,
371 ACPI_FIXED_LENGTH,
372 0,
373 ACPI_VARIABLE_LENGTH,
374 ACPI_FIXED_LENGTH,
375 ACPI_FIXED_LENGTH,
376 ACPI_VARIABLE_LENGTH,
377 ACPI_VARIABLE_LENGTH,
378 ACPI_VARIABLE_LENGTH,
379 ACPI_VARIABLE_LENGTH,
380 ACPI_FIXED_LENGTH,
381 ACPI_VARIABLE_LENGTH,
382 0,
383 ACPI_VARIABLE_LENGTH
384};
385
386
387
388
389
390
391#ifdef ACPI_ASL_COMPILER
392#define ACPI_RESOURCE_ERROR(plist)
393#else
394#define ACPI_RESOURCE_ERROR(plist) ACPI_ERROR(plist)
395#endif
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414acpi_status
415acpi_ut_walk_aml_resources(u8 * aml,
416 acpi_size aml_length,
417 acpi_walk_aml_callback user_function, void **context)
418{
419 acpi_status status;
420 u8 *end_aml;
421 u8 resource_index;
422 u32 length;
423 u32 offset = 0;
424 u8 end_tag[2] = { 0x79, 0x00 };
425
426 ACPI_FUNCTION_TRACE(ut_walk_aml_resources);
427
428
429
430 if (aml_length < sizeof(struct aml_resource_end_tag)) {
431 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
432 }
433
434
435
436 end_aml = aml + aml_length;
437
438
439
440 while (aml < end_aml) {
441
442
443
444 status = acpi_ut_validate_resource(aml, &resource_index);
445 if (ACPI_FAILURE(status)) {
446
447
448
449
450 return_ACPI_STATUS(status);
451 }
452
453
454
455 length = acpi_ut_get_descriptor_length(aml);
456
457
458
459 if (user_function) {
460 status =
461 user_function(aml, length, offset, resource_index,
462 context);
463 if (ACPI_FAILURE(status)) {
464 return_ACPI_STATUS(status);
465 }
466 }
467
468
469
470 if (acpi_ut_get_resource_type(aml) ==
471 ACPI_RESOURCE_NAME_END_TAG) {
472
473
474
475
476 if ((aml + 1) >= end_aml) {
477 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
478 }
479
480
481
482 if (!user_function) {
483 *context = aml;
484 }
485
486
487
488 return_ACPI_STATUS(AE_OK);
489 }
490
491 aml += length;
492 offset += length;
493 }
494
495
496
497 if (user_function) {
498
499
500
501 (void)acpi_ut_validate_resource(end_tag, &resource_index);
502 status =
503 user_function(end_tag, 2, offset, resource_index, context);
504 if (ACPI_FAILURE(status)) {
505 return_ACPI_STATUS(status);
506 }
507 }
508
509 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
510}
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
529{
530 union aml_resource *aml_resource;
531 u8 resource_type;
532 u8 resource_index;
533 acpi_rs_length resource_length;
534 acpi_rs_length minimum_resource_length;
535
536 ACPI_FUNCTION_ENTRY();
537
538
539
540
541 resource_type = ACPI_GET8(aml);
542
543
544
545
546
547 if (resource_type & ACPI_RESOURCE_NAME_LARGE) {
548
549
550
551 if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) {
552 goto invalid_resource;
553 }
554
555
556
557
558
559 resource_index = (u8) (resource_type - 0x70);
560 } else {
561
562
563
564
565 resource_index = (u8)
566 ((resource_type & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3);
567 }
568
569
570
571
572
573 if (!acpi_gbl_resource_types[resource_index]) {
574 goto invalid_resource;
575 }
576
577
578
579
580
581 resource_length = acpi_ut_get_resource_length(aml);
582 minimum_resource_length = acpi_gbl_resource_aml_sizes[resource_index];
583
584
585
586 switch (acpi_gbl_resource_types[resource_index]) {
587 case ACPI_FIXED_LENGTH:
588
589
590
591 if (resource_length != minimum_resource_length) {
592 goto bad_resource_length;
593 }
594 break;
595
596 case ACPI_VARIABLE_LENGTH:
597
598
599
600 if (resource_length < minimum_resource_length) {
601 goto bad_resource_length;
602 }
603 break;
604
605 case ACPI_SMALL_VARIABLE_LENGTH:
606
607
608
609 if ((resource_length > minimum_resource_length) ||
610 (resource_length < (minimum_resource_length - 1))) {
611 goto bad_resource_length;
612 }
613 break;
614
615 default:
616
617
618
619 goto invalid_resource;
620 }
621
622 aml_resource = ACPI_CAST_PTR(union aml_resource, aml);
623 if (resource_type == ACPI_RESOURCE_NAME_SERIAL_BUS) {
624
625
626
627 if ((aml_resource->common_serial_bus.type == 0) ||
628 (aml_resource->common_serial_bus.type >
629 AML_RESOURCE_MAX_SERIALBUSTYPE)) {
630 ACPI_RESOURCE_ERROR((AE_INFO,
631 "Invalid/unsupported SerialBus resource descriptor: BusType 0x%2.2X",
632 aml_resource->common_serial_bus.
633 type));
634 return (AE_AML_INVALID_RESOURCE_TYPE);
635 }
636 }
637
638
639
640 if (return_index) {
641 *return_index = resource_index;
642 }
643
644 return (AE_OK);
645
646 invalid_resource:
647
648 ACPI_RESOURCE_ERROR((AE_INFO,
649 "Invalid/unsupported resource descriptor: Type 0x%2.2X",
650 resource_type));
651 return (AE_AML_INVALID_RESOURCE_TYPE);
652
653 bad_resource_length:
654
655 ACPI_RESOURCE_ERROR((AE_INFO,
656 "Invalid resource descriptor length: Type "
657 "0x%2.2X, Length 0x%4.4X, MinLength 0x%4.4X",
658 resource_type, resource_length,
659 minimum_resource_length));
660 return (AE_AML_BAD_RESOURCE_LENGTH);
661}
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677u8 acpi_ut_get_resource_type(void *aml)
678{
679 ACPI_FUNCTION_ENTRY();
680
681
682
683
684
685 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
686
687
688
689 return (ACPI_GET8(aml));
690 } else {
691
692
693 return ((u8) (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_SMALL_MASK));
694 }
695}
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711u16 acpi_ut_get_resource_length(void *aml)
712{
713 acpi_rs_length resource_length;
714
715 ACPI_FUNCTION_ENTRY();
716
717
718
719
720
721 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
722
723
724
725 ACPI_MOVE_16_TO_16(&resource_length, ACPI_ADD_PTR(u8, aml, 1));
726
727 } else {
728
729
730 resource_length = (u16) (ACPI_GET8(aml) &
731 ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK);
732 }
733
734 return (resource_length);
735}
736
737
738
739
740
741
742
743
744
745
746
747
748
749u8 acpi_ut_get_resource_header_length(void *aml)
750{
751 ACPI_FUNCTION_ENTRY();
752
753
754
755 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
756 return (sizeof(struct aml_resource_large_header));
757 } else {
758 return (sizeof(struct aml_resource_small_header));
759 }
760}
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776u32 acpi_ut_get_descriptor_length(void *aml)
777{
778 ACPI_FUNCTION_ENTRY();
779
780
781
782
783
784 return (acpi_ut_get_resource_length(aml) +
785 acpi_ut_get_resource_header_length(aml));
786}
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802acpi_status
803acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc,
804 u8 ** end_tag)
805{
806 acpi_status status;
807
808 ACPI_FUNCTION_TRACE(ut_get_resource_end_tag);
809
810
811
812 if (!obj_desc->buffer.length) {
813 *end_tag = obj_desc->buffer.pointer;
814 return_ACPI_STATUS(AE_OK);
815 }
816
817
818
819 status = acpi_ut_walk_aml_resources(obj_desc->buffer.pointer,
820 obj_desc->buffer.length, NULL,
821 (void **)end_tag);
822
823 return_ACPI_STATUS(status);
824}
825