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 "amlresrc.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
157#endif
158
159
160
161
162
163const u8 acpi_gbl_resource_aml_sizes[] = {
164
165
166 0,
167 0,
168 0,
169 0,
170 ACPI_AML_SIZE_SMALL(struct aml_resource_irq),
171 ACPI_AML_SIZE_SMALL(struct aml_resource_dma),
172 ACPI_AML_SIZE_SMALL(struct aml_resource_start_dependent),
173 ACPI_AML_SIZE_SMALL(struct aml_resource_end_dependent),
174 ACPI_AML_SIZE_SMALL(struct aml_resource_io),
175 ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_io),
176 0,
177 0,
178 0,
179 0,
180 ACPI_AML_SIZE_SMALL(struct aml_resource_vendor_small),
181 ACPI_AML_SIZE_SMALL(struct aml_resource_end_tag),
182
183
184
185 0,
186 ACPI_AML_SIZE_LARGE(struct aml_resource_memory24),
187 ACPI_AML_SIZE_LARGE(struct aml_resource_generic_register),
188 0,
189 ACPI_AML_SIZE_LARGE(struct aml_resource_vendor_large),
190 ACPI_AML_SIZE_LARGE(struct aml_resource_memory32),
191 ACPI_AML_SIZE_LARGE(struct aml_resource_fixed_memory32),
192 ACPI_AML_SIZE_LARGE(struct aml_resource_address32),
193 ACPI_AML_SIZE_LARGE(struct aml_resource_address16),
194 ACPI_AML_SIZE_LARGE(struct aml_resource_extended_irq),
195 ACPI_AML_SIZE_LARGE(struct aml_resource_address64),
196 ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64)
197};
198
199
200
201
202
203
204
205static const u8 acpi_gbl_resource_types[] = {
206
207
208 0,
209 0,
210 0,
211 0,
212 ACPI_SMALL_VARIABLE_LENGTH,
213 ACPI_FIXED_LENGTH,
214 ACPI_SMALL_VARIABLE_LENGTH,
215 ACPI_FIXED_LENGTH,
216 ACPI_FIXED_LENGTH,
217 ACPI_FIXED_LENGTH,
218 0,
219 0,
220 0,
221 0,
222 ACPI_VARIABLE_LENGTH,
223 ACPI_FIXED_LENGTH,
224
225
226
227 0,
228 ACPI_FIXED_LENGTH,
229 ACPI_FIXED_LENGTH,
230 0,
231 ACPI_VARIABLE_LENGTH,
232 ACPI_FIXED_LENGTH,
233 ACPI_FIXED_LENGTH,
234 ACPI_VARIABLE_LENGTH,
235 ACPI_VARIABLE_LENGTH,
236 ACPI_VARIABLE_LENGTH,
237 ACPI_VARIABLE_LENGTH,
238 ACPI_FIXED_LENGTH
239};
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258acpi_status
259acpi_ut_walk_aml_resources(u8 * aml,
260 acpi_size aml_length,
261 acpi_walk_aml_callback user_function, void **context)
262{
263 acpi_status status;
264 u8 *end_aml;
265 u8 resource_index;
266 u32 length;
267 u32 offset = 0;
268
269 ACPI_FUNCTION_TRACE(ut_walk_aml_resources);
270
271
272
273 if (aml_length < sizeof(struct aml_resource_end_tag)) {
274 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
275 }
276
277
278
279 end_aml = aml + aml_length;
280
281
282
283 while (aml < end_aml) {
284
285
286
287 status = acpi_ut_validate_resource(aml, &resource_index);
288 if (ACPI_FAILURE(status)) {
289 return_ACPI_STATUS(status);
290 }
291
292
293
294 length = acpi_ut_get_descriptor_length(aml);
295
296
297
298 if (user_function) {
299 status =
300 user_function(aml, length, offset, resource_index,
301 context);
302 if (ACPI_FAILURE(status)) {
303 return (status);
304 }
305 }
306
307
308
309 if (acpi_ut_get_resource_type(aml) ==
310 ACPI_RESOURCE_NAME_END_TAG) {
311
312
313
314
315 if ((aml + 1) >= end_aml) {
316 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
317 }
318
319
320
321 if (!user_function) {
322 *context = aml;
323 }
324
325
326
327 return_ACPI_STATUS(AE_OK);
328 }
329
330 aml += length;
331 offset += length;
332 }
333
334
335
336 return (AE_AML_NO_RESOURCE_END_TAG);
337}
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
356{
357 u8 resource_type;
358 u8 resource_index;
359 acpi_rs_length resource_length;
360 acpi_rs_length minimum_resource_length;
361
362 ACPI_FUNCTION_ENTRY();
363
364
365
366
367 resource_type = ACPI_GET8(aml);
368
369
370
371
372
373 if (resource_type & ACPI_RESOURCE_NAME_LARGE) {
374
375
376
377 if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) {
378 return (AE_AML_INVALID_RESOURCE_TYPE);
379 }
380
381
382
383
384
385 resource_index = (u8) (resource_type - 0x70);
386 } else {
387
388
389
390
391 resource_index = (u8)
392 ((resource_type & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3);
393 }
394
395
396
397 if (!acpi_gbl_resource_types[resource_index]) {
398 return (AE_AML_INVALID_RESOURCE_TYPE);
399 }
400
401
402
403
404
405 resource_length = acpi_ut_get_resource_length(aml);
406 minimum_resource_length = acpi_gbl_resource_aml_sizes[resource_index];
407
408
409
410 switch (acpi_gbl_resource_types[resource_index]) {
411 case ACPI_FIXED_LENGTH:
412
413
414
415 if (resource_length != minimum_resource_length) {
416 return (AE_AML_BAD_RESOURCE_LENGTH);
417 }
418 break;
419
420 case ACPI_VARIABLE_LENGTH:
421
422
423
424 if (resource_length < minimum_resource_length) {
425 return (AE_AML_BAD_RESOURCE_LENGTH);
426 }
427 break;
428
429 case ACPI_SMALL_VARIABLE_LENGTH:
430
431
432
433 if ((resource_length > minimum_resource_length) ||
434 (resource_length < (minimum_resource_length - 1))) {
435 return (AE_AML_BAD_RESOURCE_LENGTH);
436 }
437 break;
438
439 default:
440
441
442
443 return (AE_AML_INVALID_RESOURCE_TYPE);
444 }
445
446
447
448 if (return_index) {
449 *return_index = resource_index;
450 }
451
452 return (AE_OK);
453}
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469u8 acpi_ut_get_resource_type(void *aml)
470{
471 ACPI_FUNCTION_ENTRY();
472
473
474
475
476
477 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
478
479
480
481 return (ACPI_GET8(aml));
482 } else {
483
484
485 return ((u8) (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_SMALL_MASK));
486 }
487}
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503u16 acpi_ut_get_resource_length(void *aml)
504{
505 acpi_rs_length resource_length;
506
507 ACPI_FUNCTION_ENTRY();
508
509
510
511
512
513 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
514
515
516
517 ACPI_MOVE_16_TO_16(&resource_length, ACPI_ADD_PTR(u8, aml, 1));
518
519 } else {
520
521
522 resource_length = (u16) (ACPI_GET8(aml) &
523 ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK);
524 }
525
526 return (resource_length);
527}
528
529
530
531
532
533
534
535
536
537
538
539
540
541u8 acpi_ut_get_resource_header_length(void *aml)
542{
543 ACPI_FUNCTION_ENTRY();
544
545
546
547 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
548 return (sizeof(struct aml_resource_large_header));
549 } else {
550 return (sizeof(struct aml_resource_small_header));
551 }
552}
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568u32 acpi_ut_get_descriptor_length(void *aml)
569{
570 ACPI_FUNCTION_ENTRY();
571
572
573
574
575
576 return (acpi_ut_get_resource_length(aml) +
577 acpi_ut_get_resource_header_length(aml));
578}
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594acpi_status
595acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc,
596 u8 ** end_tag)
597{
598 acpi_status status;
599
600 ACPI_FUNCTION_TRACE(ut_get_resource_end_tag);
601
602
603
604 if (!obj_desc->buffer.length) {
605 *end_tag = obj_desc->buffer.pointer;
606 return_ACPI_STATUS(AE_OK);
607 }
608
609
610
611 status = acpi_ut_walk_aml_resources(obj_desc->buffer.pointer,
612 obj_desc->buffer.length, NULL,
613 (void **)end_tag);
614
615 return_ACPI_STATUS(status);
616}
617