xref: /openbmc/linux/drivers/acpi/acpica/utresrc.c (revision 97028ce6)
1 /*******************************************************************************
2  *
3  * Module Name: utresrc - Resource management utilities
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2017, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include <acpi/acpi.h>
45 #include "accommon.h"
46 #include "acresrc.h"
47 
48 #define _COMPONENT          ACPI_UTILITIES
49 ACPI_MODULE_NAME("utresrc")
50 
51 #if defined(ACPI_DEBUG_OUTPUT) || defined (ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER)
52 /*
53  * Strings used to decode resource descriptors.
54  * Used by both the disassembler and the debugger resource dump routines
55  */
56 const char *acpi_gbl_bm_decode[] = {
57 	"NotBusMaster",
58 	"BusMaster"
59 };
60 
61 const char *acpi_gbl_config_decode[] = {
62 	"0 - Good Configuration",
63 	"1 - Acceptable Configuration",
64 	"2 - Suboptimal Configuration",
65 	"3 - ***Invalid Configuration***",
66 };
67 
68 const char *acpi_gbl_consume_decode[] = {
69 	"ResourceProducer",
70 	"ResourceConsumer"
71 };
72 
73 const char *acpi_gbl_dec_decode[] = {
74 	"PosDecode",
75 	"SubDecode"
76 };
77 
78 const char *acpi_gbl_he_decode[] = {
79 	"Level",
80 	"Edge"
81 };
82 
83 const char *acpi_gbl_io_decode[] = {
84 	"Decode10",
85 	"Decode16"
86 };
87 
88 const char *acpi_gbl_ll_decode[] = {
89 	"ActiveHigh",
90 	"ActiveLow",
91 	"ActiveBoth",
92 	"Reserved"
93 };
94 
95 const char *acpi_gbl_max_decode[] = {
96 	"MaxNotFixed",
97 	"MaxFixed"
98 };
99 
100 const char *acpi_gbl_mem_decode[] = {
101 	"NonCacheable",
102 	"Cacheable",
103 	"WriteCombining",
104 	"Prefetchable"
105 };
106 
107 const char *acpi_gbl_min_decode[] = {
108 	"MinNotFixed",
109 	"MinFixed"
110 };
111 
112 const char *acpi_gbl_mtp_decode[] = {
113 	"AddressRangeMemory",
114 	"AddressRangeReserved",
115 	"AddressRangeACPI",
116 	"AddressRangeNVS"
117 };
118 
119 const char *acpi_gbl_rng_decode[] = {
120 	"InvalidRanges",
121 	"NonISAOnlyRanges",
122 	"ISAOnlyRanges",
123 	"EntireRange"
124 };
125 
126 const char *acpi_gbl_rw_decode[] = {
127 	"ReadOnly",
128 	"ReadWrite"
129 };
130 
131 const char *acpi_gbl_shr_decode[] = {
132 	"Exclusive",
133 	"Shared",
134 	"ExclusiveAndWake",	/* ACPI 5.0 */
135 	"SharedAndWake"		/* ACPI 5.0 */
136 };
137 
138 const char *acpi_gbl_siz_decode[] = {
139 	"Transfer8",
140 	"Transfer8_16",
141 	"Transfer16",
142 	"InvalidSize"
143 };
144 
145 const char *acpi_gbl_trs_decode[] = {
146 	"DenseTranslation",
147 	"SparseTranslation"
148 };
149 
150 const char *acpi_gbl_ttp_decode[] = {
151 	"TypeStatic",
152 	"TypeTranslation"
153 };
154 
155 const char *acpi_gbl_typ_decode[] = {
156 	"Compatibility",
157 	"TypeA",
158 	"TypeB",
159 	"TypeF"
160 };
161 
162 const char *acpi_gbl_ppc_decode[] = {
163 	"PullDefault",
164 	"PullUp",
165 	"PullDown",
166 	"PullNone"
167 };
168 
169 const char *acpi_gbl_ior_decode[] = {
170 	"IoRestrictionNone",
171 	"IoRestrictionInputOnly",
172 	"IoRestrictionOutputOnly",
173 	"IoRestrictionNoneAndPreserve"
174 };
175 
176 const char *acpi_gbl_dts_decode[] = {
177 	"Width8bit",
178 	"Width16bit",
179 	"Width32bit",
180 	"Width64bit",
181 	"Width128bit",
182 	"Width256bit",
183 };
184 
185 /* GPIO connection type */
186 
187 const char *acpi_gbl_ct_decode[] = {
188 	"Interrupt",
189 	"I/O"
190 };
191 
192 /* Serial bus type */
193 
194 const char *acpi_gbl_sbt_decode[] = {
195 	"/* UNKNOWN serial bus type */",
196 	"I2C",
197 	"SPI",
198 	"UART"
199 };
200 
201 /* I2C serial bus access mode */
202 
203 const char *acpi_gbl_am_decode[] = {
204 	"AddressingMode7Bit",
205 	"AddressingMode10Bit"
206 };
207 
208 /* I2C serial bus slave mode */
209 
210 const char *acpi_gbl_sm_decode[] = {
211 	"ControllerInitiated",
212 	"DeviceInitiated"
213 };
214 
215 /* SPI serial bus wire mode */
216 
217 const char *acpi_gbl_wm_decode[] = {
218 	"FourWireMode",
219 	"ThreeWireMode"
220 };
221 
222 /* SPI serial clock phase */
223 
224 const char *acpi_gbl_cph_decode[] = {
225 	"ClockPhaseFirst",
226 	"ClockPhaseSecond"
227 };
228 
229 /* SPI serial bus clock polarity */
230 
231 const char *acpi_gbl_cpo_decode[] = {
232 	"ClockPolarityLow",
233 	"ClockPolarityHigh"
234 };
235 
236 /* SPI serial bus device polarity */
237 
238 const char *acpi_gbl_dp_decode[] = {
239 	"PolarityLow",
240 	"PolarityHigh"
241 };
242 
243 /* UART serial bus endian */
244 
245 const char *acpi_gbl_ed_decode[] = {
246 	"LittleEndian",
247 	"BigEndian"
248 };
249 
250 /* UART serial bus bits per byte */
251 
252 const char *acpi_gbl_bpb_decode[] = {
253 	"DataBitsFive",
254 	"DataBitsSix",
255 	"DataBitsSeven",
256 	"DataBitsEight",
257 	"DataBitsNine",
258 	"/* UNKNOWN Bits per byte */",
259 	"/* UNKNOWN Bits per byte */",
260 	"/* UNKNOWN Bits per byte */"
261 };
262 
263 /* UART serial bus stop bits */
264 
265 const char *acpi_gbl_sb_decode[] = {
266 	"StopBitsZero",
267 	"StopBitsOne",
268 	"StopBitsOnePlusHalf",
269 	"StopBitsTwo"
270 };
271 
272 /* UART serial bus flow control */
273 
274 const char *acpi_gbl_fc_decode[] = {
275 	"FlowControlNone",
276 	"FlowControlHardware",
277 	"FlowControlXON",
278 	"/* UNKNOWN flow control keyword */"
279 };
280 
281 /* UART serial bus parity type */
282 
283 const char *acpi_gbl_pt_decode[] = {
284 	"ParityTypeNone",
285 	"ParityTypeEven",
286 	"ParityTypeOdd",
287 	"ParityTypeMark",
288 	"ParityTypeSpace",
289 	"/* UNKNOWN parity keyword */",
290 	"/* UNKNOWN parity keyword */",
291 	"/* UNKNOWN parity keyword */"
292 };
293 
294 /* pin_config type */
295 
296 const char *acpi_gbl_ptyp_decode[] = {
297 	"Default",
298 	"Bias Pull-up",
299 	"Bias Pull-down",
300 	"Bias Default",
301 	"Bias Disable",
302 	"Bias High Impedance",
303 	"Bias Bus Hold",
304 	"Drive Open Drain",
305 	"Drive Open Source",
306 	"Drive Push Pull",
307 	"Drive Strength",
308 	"Slew Rate",
309 	"Input Debounce",
310 	"Input Schmitt Trigger",
311 };
312 
313 #endif
314 
315 /*
316  * Base sizes of the raw AML resource descriptors, indexed by resource type.
317  * Zero indicates a reserved (and therefore invalid) resource type.
318  */
319 const u8 acpi_gbl_resource_aml_sizes[] = {
320 	/* Small descriptors */
321 
322 	0,
323 	0,
324 	0,
325 	0,
326 	ACPI_AML_SIZE_SMALL(struct aml_resource_irq),
327 	ACPI_AML_SIZE_SMALL(struct aml_resource_dma),
328 	ACPI_AML_SIZE_SMALL(struct aml_resource_start_dependent),
329 	ACPI_AML_SIZE_SMALL(struct aml_resource_end_dependent),
330 	ACPI_AML_SIZE_SMALL(struct aml_resource_io),
331 	ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_io),
332 	ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_dma),
333 	0,
334 	0,
335 	0,
336 	ACPI_AML_SIZE_SMALL(struct aml_resource_vendor_small),
337 	ACPI_AML_SIZE_SMALL(struct aml_resource_end_tag),
338 
339 	/* Large descriptors */
340 
341 	0,
342 	ACPI_AML_SIZE_LARGE(struct aml_resource_memory24),
343 	ACPI_AML_SIZE_LARGE(struct aml_resource_generic_register),
344 	0,
345 	ACPI_AML_SIZE_LARGE(struct aml_resource_vendor_large),
346 	ACPI_AML_SIZE_LARGE(struct aml_resource_memory32),
347 	ACPI_AML_SIZE_LARGE(struct aml_resource_fixed_memory32),
348 	ACPI_AML_SIZE_LARGE(struct aml_resource_address32),
349 	ACPI_AML_SIZE_LARGE(struct aml_resource_address16),
350 	ACPI_AML_SIZE_LARGE(struct aml_resource_extended_irq),
351 	ACPI_AML_SIZE_LARGE(struct aml_resource_address64),
352 	ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64),
353 	ACPI_AML_SIZE_LARGE(struct aml_resource_gpio),
354 	ACPI_AML_SIZE_LARGE(struct aml_resource_pin_function),
355 	ACPI_AML_SIZE_LARGE(struct aml_resource_common_serialbus),
356 	ACPI_AML_SIZE_LARGE(struct aml_resource_pin_config),
357 };
358 
359 const u8 acpi_gbl_resource_aml_serial_bus_sizes[] = {
360 	0,
361 	ACPI_AML_SIZE_LARGE(struct aml_resource_i2c_serialbus),
362 	ACPI_AML_SIZE_LARGE(struct aml_resource_spi_serialbus),
363 	ACPI_AML_SIZE_LARGE(struct aml_resource_uart_serialbus),
364 };
365 
366 /*
367  * Resource types, used to validate the resource length field.
368  * The length of fixed-length types must match exactly, variable
369  * lengths must meet the minimum required length, etc.
370  * Zero indicates a reserved (and therefore invalid) resource type.
371  */
372 static const u8 acpi_gbl_resource_types[] = {
373 	/* Small descriptors */
374 
375 	0,
376 	0,
377 	0,
378 	0,
379 	ACPI_SMALL_VARIABLE_LENGTH,	/* 04 IRQ */
380 	ACPI_FIXED_LENGTH,	/* 05 DMA */
381 	ACPI_SMALL_VARIABLE_LENGTH,	/* 06 start_dependent_functions */
382 	ACPI_FIXED_LENGTH,	/* 07 end_dependent_functions */
383 	ACPI_FIXED_LENGTH,	/* 08 IO */
384 	ACPI_FIXED_LENGTH,	/* 09 fixed_IO */
385 	ACPI_FIXED_LENGTH,	/* 0A fixed_DMA */
386 	0,
387 	0,
388 	0,
389 	ACPI_VARIABLE_LENGTH,	/* 0E vendor_short */
390 	ACPI_FIXED_LENGTH,	/* 0F end_tag */
391 
392 	/* Large descriptors */
393 
394 	0,
395 	ACPI_FIXED_LENGTH,	/* 01 Memory24 */
396 	ACPI_FIXED_LENGTH,	/* 02 generic_register */
397 	0,
398 	ACPI_VARIABLE_LENGTH,	/* 04 vendor_long */
399 	ACPI_FIXED_LENGTH,	/* 05 Memory32 */
400 	ACPI_FIXED_LENGTH,	/* 06 memory32_fixed */
401 	ACPI_VARIABLE_LENGTH,	/* 07 Dword* address */
402 	ACPI_VARIABLE_LENGTH,	/* 08 Word* address */
403 	ACPI_VARIABLE_LENGTH,	/* 09 extended_IRQ */
404 	ACPI_VARIABLE_LENGTH,	/* 0A Qword* address */
405 	ACPI_FIXED_LENGTH,	/* 0B Extended* address */
406 	ACPI_VARIABLE_LENGTH,	/* 0C Gpio* */
407 	ACPI_VARIABLE_LENGTH,	/* 0D pin_function */
408 	ACPI_VARIABLE_LENGTH,	/* 0E *serial_bus */
409 	ACPI_VARIABLE_LENGTH,	/* 0F pin_config */
410 };
411 
412 /*******************************************************************************
413  *
414  * FUNCTION:    acpi_ut_walk_aml_resources
415  *
416  * PARAMETERS:  walk_state          - Current walk info
417  * PARAMETERS:  aml                 - Pointer to the raw AML resource template
418  *              aml_length          - Length of the entire template
419  *              user_function       - Called once for each descriptor found. If
420  *                                    NULL, a pointer to the end_tag is returned
421  *              context             - Passed to user_function
422  *
423  * RETURN:      Status
424  *
425  * DESCRIPTION: Walk a raw AML resource list(buffer). User function called
426  *              once for each resource found.
427  *
428  ******************************************************************************/
429 
430 acpi_status
431 acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,
432 			   u8 *aml,
433 			   acpi_size aml_length,
434 			   acpi_walk_aml_callback user_function, void **context)
435 {
436 	acpi_status status;
437 	u8 *end_aml;
438 	u8 resource_index;
439 	u32 length;
440 	u32 offset = 0;
441 	u8 end_tag[2] = { 0x79, 0x00 };
442 
443 	ACPI_FUNCTION_TRACE(ut_walk_aml_resources);
444 
445 	/* The absolute minimum resource template is one end_tag descriptor */
446 
447 	if (aml_length < sizeof(struct aml_resource_end_tag)) {
448 		return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
449 	}
450 
451 	/* Point to the end of the resource template buffer */
452 
453 	end_aml = aml + aml_length;
454 
455 	/* Walk the byte list, abort on any invalid descriptor type or length */
456 
457 	while (aml < end_aml) {
458 
459 		/* Validate the Resource Type and Resource Length */
460 
461 		status =
462 		    acpi_ut_validate_resource(walk_state, aml, &resource_index);
463 		if (ACPI_FAILURE(status)) {
464 			/*
465 			 * Exit on failure. Cannot continue because the descriptor
466 			 * length may be bogus also.
467 			 */
468 			return_ACPI_STATUS(status);
469 		}
470 
471 		/* Get the length of this descriptor */
472 
473 		length = acpi_ut_get_descriptor_length(aml);
474 
475 		/* Invoke the user function */
476 
477 		if (user_function) {
478 			status =
479 			    user_function(aml, length, offset, resource_index,
480 					  context);
481 			if (ACPI_FAILURE(status)) {
482 				return_ACPI_STATUS(status);
483 			}
484 		}
485 
486 		/* An end_tag descriptor terminates this resource template */
487 
488 		if (acpi_ut_get_resource_type(aml) ==
489 		    ACPI_RESOURCE_NAME_END_TAG) {
490 			/*
491 			 * There must be at least one more byte in the buffer for
492 			 * the 2nd byte of the end_tag
493 			 */
494 			if ((aml + 1) >= end_aml) {
495 				return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
496 			}
497 
498 			/*
499 			 * The end_tag opcode must be followed by a zero byte.
500 			 * Although this byte is technically defined to be a checksum,
501 			 * in practice, all ASL compilers set this byte to zero.
502 			 */
503 			if (*(aml + 1) != 0) {
504 				return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
505 			}
506 
507 			/* Return the pointer to the end_tag if requested */
508 
509 			if (!user_function) {
510 				*context = aml;
511 			}
512 
513 			/* Normal exit */
514 
515 			return_ACPI_STATUS(AE_OK);
516 		}
517 
518 		aml += length;
519 		offset += length;
520 	}
521 
522 	/* Did not find an end_tag descriptor */
523 
524 	if (user_function) {
525 
526 		/* Insert an end_tag anyway. acpi_rs_get_list_length always leaves room */
527 
528 		(void)acpi_ut_validate_resource(walk_state, end_tag,
529 						&resource_index);
530 		status =
531 		    user_function(end_tag, 2, offset, resource_index, context);
532 		if (ACPI_FAILURE(status)) {
533 			return_ACPI_STATUS(status);
534 		}
535 	}
536 
537 	return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
538 }
539 
540 /*******************************************************************************
541  *
542  * FUNCTION:    acpi_ut_validate_resource
543  *
544  * PARAMETERS:  walk_state          - Current walk info
545  *              aml                 - Pointer to the raw AML resource descriptor
546  *              return_index        - Where the resource index is returned. NULL
547  *                                    if the index is not required.
548  *
549  * RETURN:      Status, and optionally the Index into the global resource tables
550  *
551  * DESCRIPTION: Validate an AML resource descriptor by checking the Resource
552  *              Type and Resource Length. Returns an index into the global
553  *              resource information/dispatch tables for later use.
554  *
555  ******************************************************************************/
556 
557 acpi_status
558 acpi_ut_validate_resource(struct acpi_walk_state *walk_state,
559 			  void *aml, u8 *return_index)
560 {
561 	union aml_resource *aml_resource;
562 	u8 resource_type;
563 	u8 resource_index;
564 	acpi_rs_length resource_length;
565 	acpi_rs_length minimum_resource_length;
566 
567 	ACPI_FUNCTION_ENTRY();
568 
569 	/*
570 	 * 1) Validate the resource_type field (Byte 0)
571 	 */
572 	resource_type = ACPI_GET8(aml);
573 
574 	/*
575 	 * Byte 0 contains the descriptor name (Resource Type)
576 	 * Examine the large/small bit in the resource header
577 	 */
578 	if (resource_type & ACPI_RESOURCE_NAME_LARGE) {
579 
580 		/* Verify the large resource type (name) against the max */
581 
582 		if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) {
583 			goto invalid_resource;
584 		}
585 
586 		/*
587 		 * Large Resource Type -- bits 6:0 contain the name
588 		 * Translate range 0x80-0x8B to index range 0x10-0x1B
589 		 */
590 		resource_index = (u8) (resource_type - 0x70);
591 	} else {
592 		/*
593 		 * Small Resource Type -- bits 6:3 contain the name
594 		 * Shift range to index range 0x00-0x0F
595 		 */
596 		resource_index = (u8)
597 		    ((resource_type & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3);
598 	}
599 
600 	/*
601 	 * Check validity of the resource type, via acpi_gbl_resource_types.
602 	 * Zero indicates an invalid resource.
603 	 */
604 	if (!acpi_gbl_resource_types[resource_index]) {
605 		goto invalid_resource;
606 	}
607 
608 	/*
609 	 * Validate the resource_length field. This ensures that the length
610 	 * is at least reasonable, and guarantees that it is non-zero.
611 	 */
612 	resource_length = acpi_ut_get_resource_length(aml);
613 	minimum_resource_length = acpi_gbl_resource_aml_sizes[resource_index];
614 
615 	/* Validate based upon the type of resource - fixed length or variable */
616 
617 	switch (acpi_gbl_resource_types[resource_index]) {
618 	case ACPI_FIXED_LENGTH:
619 
620 		/* Fixed length resource, length must match exactly */
621 
622 		if (resource_length != minimum_resource_length) {
623 			goto bad_resource_length;
624 		}
625 		break;
626 
627 	case ACPI_VARIABLE_LENGTH:
628 
629 		/* Variable length resource, length must be at least the minimum */
630 
631 		if (resource_length < minimum_resource_length) {
632 			goto bad_resource_length;
633 		}
634 		break;
635 
636 	case ACPI_SMALL_VARIABLE_LENGTH:
637 
638 		/* Small variable length resource, length can be (Min) or (Min-1) */
639 
640 		if ((resource_length > minimum_resource_length) ||
641 		    (resource_length < (minimum_resource_length - 1))) {
642 			goto bad_resource_length;
643 		}
644 		break;
645 
646 	default:
647 
648 		/* Shouldn't happen (because of validation earlier), but be sure */
649 
650 		goto invalid_resource;
651 	}
652 
653 	aml_resource = ACPI_CAST_PTR(union aml_resource, aml);
654 	if (resource_type == ACPI_RESOURCE_NAME_SERIAL_BUS) {
655 
656 		/* Validate the bus_type field */
657 
658 		if ((aml_resource->common_serial_bus.type == 0) ||
659 		    (aml_resource->common_serial_bus.type >
660 		     AML_RESOURCE_MAX_SERIALBUSTYPE)) {
661 			if (walk_state) {
662 				ACPI_ERROR((AE_INFO,
663 					    "Invalid/unsupported SerialBus resource descriptor: BusType 0x%2.2X",
664 					    aml_resource->common_serial_bus.
665 					    type));
666 			}
667 			return (AE_AML_INVALID_RESOURCE_TYPE);
668 		}
669 	}
670 
671 	/* Optionally return the resource table index */
672 
673 	if (return_index) {
674 		*return_index = resource_index;
675 	}
676 
677 	return (AE_OK);
678 
679 invalid_resource:
680 
681 	if (walk_state) {
682 		ACPI_ERROR((AE_INFO,
683 			    "Invalid/unsupported resource descriptor: Type 0x%2.2X",
684 			    resource_type));
685 	}
686 	return (AE_AML_INVALID_RESOURCE_TYPE);
687 
688 bad_resource_length:
689 
690 	if (walk_state) {
691 		ACPI_ERROR((AE_INFO,
692 			    "Invalid resource descriptor length: Type "
693 			    "0x%2.2X, Length 0x%4.4X, MinLength 0x%4.4X",
694 			    resource_type, resource_length,
695 			    minimum_resource_length));
696 	}
697 	return (AE_AML_BAD_RESOURCE_LENGTH);
698 }
699 
700 /*******************************************************************************
701  *
702  * FUNCTION:    acpi_ut_get_resource_type
703  *
704  * PARAMETERS:  aml             - Pointer to the raw AML resource descriptor
705  *
706  * RETURN:      The Resource Type with no extraneous bits (except the
707  *              Large/Small descriptor bit -- this is left alone)
708  *
709  * DESCRIPTION: Extract the Resource Type/Name from the first byte of
710  *              a resource descriptor.
711  *
712  ******************************************************************************/
713 
714 u8 acpi_ut_get_resource_type(void *aml)
715 {
716 	ACPI_FUNCTION_ENTRY();
717 
718 	/*
719 	 * Byte 0 contains the descriptor name (Resource Type)
720 	 * Examine the large/small bit in the resource header
721 	 */
722 	if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
723 
724 		/* Large Resource Type -- bits 6:0 contain the name */
725 
726 		return (ACPI_GET8(aml));
727 	} else {
728 		/* Small Resource Type -- bits 6:3 contain the name */
729 
730 		return ((u8) (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_SMALL_MASK));
731 	}
732 }
733 
734 /*******************************************************************************
735  *
736  * FUNCTION:    acpi_ut_get_resource_length
737  *
738  * PARAMETERS:  aml             - Pointer to the raw AML resource descriptor
739  *
740  * RETURN:      Byte Length
741  *
742  * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By
743  *              definition, this does not include the size of the descriptor
744  *              header or the length field itself.
745  *
746  ******************************************************************************/
747 
748 u16 acpi_ut_get_resource_length(void *aml)
749 {
750 	acpi_rs_length resource_length;
751 
752 	ACPI_FUNCTION_ENTRY();
753 
754 	/*
755 	 * Byte 0 contains the descriptor name (Resource Type)
756 	 * Examine the large/small bit in the resource header
757 	 */
758 	if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
759 
760 		/* Large Resource type -- bytes 1-2 contain the 16-bit length */
761 
762 		ACPI_MOVE_16_TO_16(&resource_length, ACPI_ADD_PTR(u8, aml, 1));
763 
764 	} else {
765 		/* Small Resource type -- bits 2:0 of byte 0 contain the length */
766 
767 		resource_length = (u16) (ACPI_GET8(aml) &
768 					 ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK);
769 	}
770 
771 	return (resource_length);
772 }
773 
774 /*******************************************************************************
775  *
776  * FUNCTION:    acpi_ut_get_resource_header_length
777  *
778  * PARAMETERS:  aml             - Pointer to the raw AML resource descriptor
779  *
780  * RETURN:      Length of the AML header (depends on large/small descriptor)
781  *
782  * DESCRIPTION: Get the length of the header for this resource.
783  *
784  ******************************************************************************/
785 
786 u8 acpi_ut_get_resource_header_length(void *aml)
787 {
788 	ACPI_FUNCTION_ENTRY();
789 
790 	/* Examine the large/small bit in the resource header */
791 
792 	if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
793 		return (sizeof(struct aml_resource_large_header));
794 	} else {
795 		return (sizeof(struct aml_resource_small_header));
796 	}
797 }
798 
799 /*******************************************************************************
800  *
801  * FUNCTION:    acpi_ut_get_descriptor_length
802  *
803  * PARAMETERS:  aml             - Pointer to the raw AML resource descriptor
804  *
805  * RETURN:      Byte length
806  *
807  * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the
808  *              length of the descriptor header and the length field itself.
809  *              Used to walk descriptor lists.
810  *
811  ******************************************************************************/
812 
813 u32 acpi_ut_get_descriptor_length(void *aml)
814 {
815 	ACPI_FUNCTION_ENTRY();
816 
817 	/*
818 	 * Get the Resource Length (does not include header length) and add
819 	 * the header length (depends on if this is a small or large resource)
820 	 */
821 	return (acpi_ut_get_resource_length(aml) +
822 		acpi_ut_get_resource_header_length(aml));
823 }
824 
825 /*******************************************************************************
826  *
827  * FUNCTION:    acpi_ut_get_resource_end_tag
828  *
829  * PARAMETERS:  obj_desc        - The resource template buffer object
830  *              end_tag         - Where the pointer to the end_tag is returned
831  *
832  * RETURN:      Status, pointer to the end tag
833  *
834  * DESCRIPTION: Find the end_tag resource descriptor in an AML resource template
835  *              Note: allows a buffer length of zero.
836  *
837  ******************************************************************************/
838 
839 acpi_status
840 acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc, u8 **end_tag)
841 {
842 	acpi_status status;
843 
844 	ACPI_FUNCTION_TRACE(ut_get_resource_end_tag);
845 
846 	/* Allow a buffer length of zero */
847 
848 	if (!obj_desc->buffer.length) {
849 		*end_tag = obj_desc->buffer.pointer;
850 		return_ACPI_STATUS(AE_OK);
851 	}
852 
853 	/* Validate the template and get a pointer to the end_tag */
854 
855 	status = acpi_ut_walk_aml_resources(NULL, obj_desc->buffer.pointer,
856 					    obj_desc->buffer.length, NULL,
857 					    (void **)end_tag);
858 
859 	return_ACPI_STATUS(status);
860 }
861