1 /*******************************************************************************
3 * Module Name: rsmisc - Miscellaneous resource descriptors
5 ******************************************************************************/
8 * Copyright (C) 2000 - 2005, R. Byron Moore
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
44 #include <acpi/acpi.h>
45 #include <acpi/acresrc.h>
47 #define _COMPONENT ACPI_RESOURCES
48 ACPI_MODULE_NAME("rsmisc")
50 /*******************************************************************************
52 * FUNCTION: acpi_rs_generic_register_resource
54 * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
56 * bytes_consumed - Pointer to where the number of bytes
57 * consumed the byte_stream_buffer is
59 * output_buffer - Pointer to the return data buffer
60 * structure_size - Pointer to where the number of bytes
61 * in the return data struct is returned
65 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
66 * structure pointed to by the output_buffer. Return the
67 * number of bytes consumed from the byte stream.
69 ******************************************************************************/
71 acpi_rs_generic_register_resource(u8 * byte_stream_buffer,
72 acpi_size * bytes_consumed,
74 acpi_size * structure_size)
76 u8 *buffer = byte_stream_buffer;
77 struct acpi_resource *output_struct = (void *)*output_buffer;
80 acpi_size struct_size =
81 ACPI_SIZEOF_RESOURCE(struct acpi_resource_generic_reg);
83 ACPI_FUNCTION_TRACE("rs_generic_register_resource");
85 /* Byte 0 is the Descriptor Type */
89 /* Get the Descriptor Length field (Bytes 1-2) */
91 ACPI_MOVE_16_TO_16(&temp16, buffer);
94 /* Validate the descriptor length */
97 return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
100 /* The number of bytes consumed is fixed (12 + 3) */
102 *bytes_consumed = 15;
104 /* Fill out the structure */
106 output_struct->type = ACPI_RSTYPE_GENERIC_REG;
108 /* Get space_id (Byte 3) */
111 output_struct->data.generic_reg.space_id = temp8;
114 /* Get register_bit_width (Byte 4) */
117 output_struct->data.generic_reg.bit_width = temp8;
120 /* Get register_bit_offset (Byte 5) */
123 output_struct->data.generic_reg.bit_offset = temp8;
126 /* Get address_size (Byte 6) */
129 output_struct->data.generic_reg.address_size = temp8;
132 /* Get register_address (Bytes 7-14) */
134 ACPI_MOVE_64_TO_64(&output_struct->data.generic_reg.address, buffer);
136 /* Set the Length parameter */
138 output_struct->length = (u32) struct_size;
140 /* Return the final size of the structure */
142 *structure_size = struct_size;
143 return_ACPI_STATUS(AE_OK);
146 /*******************************************************************************
148 * FUNCTION: acpi_rs_generic_register_stream
150 * PARAMETERS: Resource - Pointer to the resource linked list
151 * output_buffer - Pointer to the user's return buffer
152 * bytes_consumed - Pointer to where the number of bytes
153 * used in the output_buffer is returned
157 * DESCRIPTION: Take the linked list resource structure and fills in the
158 * the appropriate bytes in a byte stream
160 ******************************************************************************/
163 acpi_rs_generic_register_stream(struct acpi_resource *resource,
164 u8 ** output_buffer, acpi_size * bytes_consumed)
166 u8 *buffer = *output_buffer;
169 ACPI_FUNCTION_TRACE("rs_generic_register_stream");
171 /* Set the Descriptor Type (Byte 0) */
173 *buffer = ACPI_RDESC_TYPE_GENERIC_REGISTER;
176 /* Set the Descriptor Length (Bytes 1-2) */
179 ACPI_MOVE_16_TO_16(buffer, &temp16);
182 /* Set space_id (Byte 3) */
184 *buffer = (u8) resource->data.generic_reg.space_id;
187 /* Set register_bit_width (Byte 4) */
189 *buffer = (u8) resource->data.generic_reg.bit_width;
192 /* Set register_bit_offset (Byte 5) */
194 *buffer = (u8) resource->data.generic_reg.bit_offset;
197 /* Set address_size (Byte 6) */
199 *buffer = (u8) resource->data.generic_reg.address_size;
202 /* Set register_address (Bytes 7-14) */
204 ACPI_MOVE_64_TO_64(buffer, &resource->data.generic_reg.address);
207 /* Return the number of bytes consumed in this operation */
209 *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
210 return_ACPI_STATUS(AE_OK);
213 /*******************************************************************************
215 * FUNCTION: acpi_rs_end_tag_resource
217 * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
219 * bytes_consumed - Pointer to where the number of bytes
220 * consumed the byte_stream_buffer is
222 * output_buffer - Pointer to the return data buffer
223 * structure_size - Pointer to where the number of bytes
224 * in the return data struct is returned
228 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
229 * structure pointed to by the output_buffer. Return the
230 * number of bytes consumed from the byte stream.
232 ******************************************************************************/
235 acpi_rs_end_tag_resource(u8 * byte_stream_buffer,
236 acpi_size * bytes_consumed,
237 u8 ** output_buffer, acpi_size * structure_size)
239 struct acpi_resource *output_struct = (void *)*output_buffer;
240 acpi_size struct_size = ACPI_RESOURCE_LENGTH;
242 ACPI_FUNCTION_TRACE("rs_end_tag_resource");
244 /* The number of bytes consumed is static */
248 /* Fill out the structure */
250 output_struct->type = ACPI_RSTYPE_END_TAG;
252 /* Set the Length parameter */
254 output_struct->length = 0;
256 /* Return the final size of the structure */
258 *structure_size = struct_size;
259 return_ACPI_STATUS(AE_OK);
262 /*******************************************************************************
264 * FUNCTION: acpi_rs_end_tag_stream
266 * PARAMETERS: Resource - Pointer to the resource linked list
267 * output_buffer - Pointer to the user's return buffer
268 * bytes_consumed - Pointer to where the number of bytes
269 * used in the output_buffer is returned
273 * DESCRIPTION: Take the linked list resource structure and fills in the
274 * the appropriate bytes in a byte stream
276 ******************************************************************************/
279 acpi_rs_end_tag_stream(struct acpi_resource *resource,
280 u8 ** output_buffer, acpi_size * bytes_consumed)
282 u8 *buffer = *output_buffer;
285 ACPI_FUNCTION_TRACE("rs_end_tag_stream");
287 /* The Descriptor Type field is static */
289 *buffer = ACPI_RDESC_TYPE_END_TAG | 0x01;
293 * Set the Checksum - zero means that the resource data is treated as if
294 * the checksum operation succeeded (ACPI Spec 1.0b Section 6.4.2.8)
301 /* Return the number of bytes consumed in this operation */
303 *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
304 return_ACPI_STATUS(AE_OK);
307 /*******************************************************************************
309 * FUNCTION: acpi_rs_vendor_resource
311 * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
313 * bytes_consumed - Pointer to where the number of bytes
314 * consumed the byte_stream_buffer is
316 * output_buffer - Pointer to the return data buffer
317 * structure_size - Pointer to where the number of bytes
318 * in the return data struct is returned
322 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
323 * structure pointed to by the output_buffer. Return the
324 * number of bytes consumed from the byte stream.
326 ******************************************************************************/
329 acpi_rs_vendor_resource(u8 * byte_stream_buffer,
330 acpi_size * bytes_consumed,
331 u8 ** output_buffer, acpi_size * structure_size)
333 u8 *buffer = byte_stream_buffer;
334 struct acpi_resource *output_struct = (void *)*output_buffer;
338 acpi_size struct_size =
339 ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor);
341 ACPI_FUNCTION_TRACE("rs_vendor_resource");
343 /* Dereference the Descriptor to find if this is a large or small item. */
347 if (temp8 & ACPI_RDESC_TYPE_LARGE) {
348 /* Large Item, point to the length field */
354 ACPI_MOVE_16_TO_16(&temp16, buffer);
356 /* Calculate bytes consumed */
358 *bytes_consumed = (acpi_size) temp16 + 3;
360 /* Point to the first vendor byte */
364 /* Small Item, dereference the size */
366 temp16 = (u8) (*buffer & 0x07);
368 /* Calculate bytes consumed */
370 *bytes_consumed = (acpi_size) temp16 + 1;
372 /* Point to the first vendor byte */
377 output_struct->type = ACPI_RSTYPE_VENDOR;
378 output_struct->data.vendor_specific.length = temp16;
380 for (index = 0; index < temp16; index++) {
381 output_struct->data.vendor_specific.reserved[index] = *buffer;
386 * In order for the struct_size to fall on a 32-bit boundary,
387 * calculate the length of the vendor string and expand the
388 * struct_size to the next 32-bit boundary.
390 struct_size += ACPI_ROUND_UP_to_32_bITS(temp16);
392 /* Set the Length parameter */
394 output_struct->length = (u32) struct_size;
396 /* Return the final size of the structure */
398 *structure_size = struct_size;
399 return_ACPI_STATUS(AE_OK);
402 /*******************************************************************************
404 * FUNCTION: acpi_rs_vendor_stream
406 * PARAMETERS: Resource - Pointer to the resource linked list
407 * output_buffer - Pointer to the user's return buffer
408 * bytes_consumed - Pointer to where the number of bytes
409 * used in the output_buffer is returned
413 * DESCRIPTION: Take the linked list resource structure and fills in the
414 * the appropriate bytes in a byte stream
416 ******************************************************************************/
419 acpi_rs_vendor_stream(struct acpi_resource *resource,
420 u8 ** output_buffer, acpi_size * bytes_consumed)
422 u8 *buffer = *output_buffer;
427 ACPI_FUNCTION_TRACE("rs_vendor_stream");
429 /* Dereference the length to find if this is a large or small item. */
431 if (resource->data.vendor_specific.length > 7) {
432 /* Large Item, Set the descriptor field and length bytes */
434 *buffer = ACPI_RDESC_TYPE_LARGE_VENDOR;
437 temp16 = (u16) resource->data.vendor_specific.length;
439 ACPI_MOVE_16_TO_16(buffer, &temp16);
442 /* Small Item, Set the descriptor field */
444 temp8 = ACPI_RDESC_TYPE_SMALL_VENDOR;
445 temp8 |= (u8) resource->data.vendor_specific.length;
451 /* Loop through all of the Vendor Specific fields */
453 for (index = 0; index < resource->data.vendor_specific.length; index++) {
454 temp8 = resource->data.vendor_specific.reserved[index];
460 /* Return the number of bytes consumed in this operation */
462 *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
463 return_ACPI_STATUS(AE_OK);
466 /*******************************************************************************
468 * FUNCTION: acpi_rs_start_depend_fns_resource
470 * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
472 * bytes_consumed - Pointer to where the number of bytes
473 * consumed the byte_stream_buffer is
475 * output_buffer - Pointer to the return data buffer
476 * structure_size - Pointer to where the number of bytes
477 * in the return data struct is returned
481 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
482 * structure pointed to by the output_buffer. Return the
483 * number of bytes consumed from the byte stream.
485 ******************************************************************************/
488 acpi_rs_start_depend_fns_resource(u8 * byte_stream_buffer,
489 acpi_size * bytes_consumed,
491 acpi_size * structure_size)
493 u8 *buffer = byte_stream_buffer;
494 struct acpi_resource *output_struct = (void *)*output_buffer;
496 acpi_size struct_size =
497 ACPI_SIZEOF_RESOURCE(struct acpi_resource_start_dpf);
499 ACPI_FUNCTION_TRACE("rs_start_depend_fns_resource");
501 /* The number of bytes consumed are found in the descriptor (Bits:0-1) */
505 *bytes_consumed = (temp8 & 0x01) + 1;
507 output_struct->type = ACPI_RSTYPE_START_DPF;
509 /* Point to Byte 1 if it is used */
511 if (2 == *bytes_consumed) {
515 /* Check Compatibility priority */
517 output_struct->data.start_dpf.compatibility_priority =
520 if (3 == output_struct->data.start_dpf.compatibility_priority) {
521 return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE);
524 /* Check Performance/Robustness preference */
526 output_struct->data.start_dpf.performance_robustness =
529 if (3 == output_struct->data.start_dpf.performance_robustness) {
530 return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE);
533 output_struct->data.start_dpf.compatibility_priority =
534 ACPI_ACCEPTABLE_CONFIGURATION;
536 output_struct->data.start_dpf.performance_robustness =
537 ACPI_ACCEPTABLE_CONFIGURATION;
540 /* Set the Length parameter */
542 output_struct->length = (u32) struct_size;
544 /* Return the final size of the structure */
546 *structure_size = struct_size;
547 return_ACPI_STATUS(AE_OK);
550 /*******************************************************************************
552 * FUNCTION: acpi_rs_end_depend_fns_resource
554 * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
556 * bytes_consumed - Pointer to where the number of bytes
557 * consumed the byte_stream_buffer is
559 * output_buffer - Pointer to the return data buffer
560 * structure_size - Pointer to where the number of bytes
561 * in the return data struct is returned
565 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
566 * structure pointed to by the output_buffer. Return the
567 * number of bytes consumed from the byte stream.
569 ******************************************************************************/
572 acpi_rs_end_depend_fns_resource(u8 * byte_stream_buffer,
573 acpi_size * bytes_consumed,
574 u8 ** output_buffer, acpi_size * structure_size)
576 struct acpi_resource *output_struct = (void *)*output_buffer;
577 acpi_size struct_size = ACPI_RESOURCE_LENGTH;
579 ACPI_FUNCTION_TRACE("rs_end_depend_fns_resource");
581 /* The number of bytes consumed is static */
585 /* Fill out the structure */
587 output_struct->type = ACPI_RSTYPE_END_DPF;
589 /* Set the Length parameter */
591 output_struct->length = (u32) struct_size;
593 /* Return the final size of the structure */
595 *structure_size = struct_size;
596 return_ACPI_STATUS(AE_OK);
599 /*******************************************************************************
601 * FUNCTION: acpi_rs_start_depend_fns_stream
603 * PARAMETERS: Resource - Pointer to the resource linked list
604 * output_buffer - Pointer to the user's return buffer
605 * bytes_consumed - u32 pointer that is filled with
606 * the number of bytes of the
611 * DESCRIPTION: Take the linked list resource structure and fills in the
612 * the appropriate bytes in a byte stream
614 ******************************************************************************/
617 acpi_rs_start_depend_fns_stream(struct acpi_resource *resource,
618 u8 ** output_buffer, acpi_size * bytes_consumed)
620 u8 *buffer = *output_buffer;
623 ACPI_FUNCTION_TRACE("rs_start_depend_fns_stream");
626 * The descriptor type field is set based upon whether a byte is needed
627 * to contain Priority data.
629 if (ACPI_ACCEPTABLE_CONFIGURATION ==
630 resource->data.start_dpf.compatibility_priority &&
631 ACPI_ACCEPTABLE_CONFIGURATION ==
632 resource->data.start_dpf.performance_robustness) {
633 *buffer = ACPI_RDESC_TYPE_START_DEPENDENT;
635 *buffer = ACPI_RDESC_TYPE_START_DEPENDENT | 0x01;
638 /* Set the Priority Byte Definition */
641 temp8 = (u8) ((resource->data.start_dpf.performance_robustness &
643 temp8 |= (resource->data.start_dpf.compatibility_priority &
650 /* Return the number of bytes consumed in this operation */
652 *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
653 return_ACPI_STATUS(AE_OK);
656 /*******************************************************************************
658 * FUNCTION: acpi_rs_end_depend_fns_stream
660 * PARAMETERS: Resource - Pointer to the resource linked list
661 * output_buffer - Pointer to the user's return buffer
662 * bytes_consumed - Pointer to where the number of bytes
663 * used in the output_buffer is returned
667 * DESCRIPTION: Take the linked list resource structure and fills in the
668 * the appropriate bytes in a byte stream
670 ******************************************************************************/
673 acpi_rs_end_depend_fns_stream(struct acpi_resource *resource,
674 u8 ** output_buffer, acpi_size * bytes_consumed)
676 u8 *buffer = *output_buffer;
678 ACPI_FUNCTION_TRACE("rs_end_depend_fns_stream");
680 /* The Descriptor Type field is static */
682 *buffer = ACPI_RDESC_TYPE_END_DEPENDENT;
685 /* Return the number of bytes consumed in this operation */
687 *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
688 return_ACPI_STATUS(AE_OK);