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