1 /*******************************************************************************
3 * Module Name: rsaddr - Address resource descriptors (16/32/64)
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.
45 #include <acpi/acpi.h>
46 #include <acpi/acresrc.h>
48 #define _COMPONENT ACPI_RESOURCES
49 ACPI_MODULE_NAME ("rsaddr")
52 /*******************************************************************************
54 * FUNCTION: acpi_rs_address16_resource
56 * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
58 * bytes_consumed - Pointer to where the number of bytes
59 * consumed the byte_stream_buffer is
61 * output_buffer - Pointer to the return data buffer
62 * structure_size - Pointer to where the number of bytes
63 * in the return data struct is returned
67 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
68 * structure pointed to by the output_buffer. Return the
69 * number of bytes consumed from the byte stream.
71 ******************************************************************************/
74 acpi_rs_address16_resource (
75 u8 *byte_stream_buffer,
76 acpi_size *bytes_consumed,
78 acpi_size *structure_size)
84 u8 *buffer = byte_stream_buffer;
85 struct acpi_resource *output_struct = (void *) *output_buffer;
86 acpi_size struct_size = ACPI_SIZEOF_RESOURCE (
87 struct acpi_resource_address16);
90 ACPI_FUNCTION_TRACE ("rs_address16_resource");
93 /* Point past the Descriptor to get the number of bytes consumed */
96 ACPI_MOVE_16_TO_16 (&temp16, buffer);
98 /* Validate minimum descriptor length */
101 return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
104 *bytes_consumed = temp16 + 3;
105 output_struct->id = ACPI_RSTYPE_ADDRESS16;
107 /* Get the Resource Type (Byte3) */
112 /* Values 0-2 and 0xC0-0xFF are valid */
114 if ((temp8 > 2) && (temp8 < 0xC0)) {
115 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
118 output_struct->data.address16.resource_type = temp8;
120 /* Get the General Flags (Byte4) */
125 /* Producer / Consumer */
127 output_struct->data.address16.producer_consumer = temp8 & 0x01;
131 output_struct->data.address16.decode = (temp8 >> 1) & 0x01;
133 /* Min Address Fixed */
135 output_struct->data.address16.min_address_fixed = (temp8 >> 2) & 0x01;
137 /* Max Address Fixed */
139 output_struct->data.address16.max_address_fixed = (temp8 >> 3) & 0x01;
141 /* Get the Type Specific Flags (Byte5) */
146 if (ACPI_MEMORY_RANGE == output_struct->data.address16.resource_type) {
147 output_struct->data.address16.attribute.memory.read_write_attribute =
148 (u16) (temp8 & 0x01);
149 output_struct->data.address16.attribute.memory.cache_attribute =
150 (u16) ((temp8 >> 1) & 0x03);
153 if (ACPI_IO_RANGE == output_struct->data.address16.resource_type) {
154 output_struct->data.address16.attribute.io.range_attribute =
155 (u16) (temp8 & 0x03);
156 output_struct->data.address16.attribute.io.translation_attribute =
157 (u16) ((temp8 >> 4) & 0x03);
160 /* BUS_NUMBER_RANGE == Address16.Data->resource_type */
161 /* Nothing needs to be filled in */
165 /* Get Granularity (Bytes 6-7) */
168 ACPI_MOVE_16_TO_32 (&output_struct->data.address16.granularity, buffer);
170 /* Get min_address_range (Bytes 8-9) */
173 ACPI_MOVE_16_TO_32 (&output_struct->data.address16.min_address_range, buffer);
175 /* Get max_address_range (Bytes 10-11) */
178 ACPI_MOVE_16_TO_32 (&output_struct->data.address16.max_address_range, buffer);
180 /* Get address_translation_offset (Bytes 12-13) */
183 ACPI_MOVE_16_TO_32 (&output_struct->data.address16.address_translation_offset,
186 /* Get address_length (Bytes 14-15) */
189 ACPI_MOVE_16_TO_32 (&output_struct->data.address16.address_length, buffer);
191 /* Resource Source Index (if present) */
196 * This will leave us pointing to the Resource Source Index
197 * If it is present, then save it off and calculate the
198 * pointer to where the null terminated string goes:
199 * Each Interrupt takes 32-bits + the 5 bytes of the
200 * stream that are default.
202 * Note: Some resource descriptors will have an additional null, so
203 * we add 1 to the length.
205 if (*bytes_consumed > (16 + 1)) {
206 /* Dereference the Index */
209 output_struct->data.address16.resource_source.index = (u32) temp8;
211 /* Point to the String */
215 /* Point the String pointer to the end of this structure */
217 output_struct->data.address16.resource_source.string_ptr =
218 (char *)((u8 * )output_struct + struct_size);
221 output_struct->data.address16.resource_source.string_ptr;
223 /* Copy the string into the buffer */
227 while (0x00 != *buffer) {
235 /* Add the terminating null */
239 output_struct->data.address16.resource_source.string_length = index + 1;
242 * In order for the struct_size to fall on a 32-bit boundary,
243 * calculate the length of the string and expand the
244 * struct_size to the next 32-bit boundary.
246 temp8 = (u8) (index + 1);
247 struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
250 output_struct->data.address16.resource_source.index = 0x00;
251 output_struct->data.address16.resource_source.string_length = 0;
252 output_struct->data.address16.resource_source.string_ptr = NULL;
255 /* Set the Length parameter */
257 output_struct->length = (u32) struct_size;
259 /* Return the final size of the structure */
261 *structure_size = struct_size;
262 return_ACPI_STATUS (AE_OK);
266 /*******************************************************************************
268 * FUNCTION: acpi_rs_address16_stream
270 * PARAMETERS: linked_list - Pointer to the resource linked list
271 * output_buffer - Pointer to the user's return buffer
272 * bytes_consumed - Pointer to where the number of bytes
273 * used in the output_buffer is returned
277 * DESCRIPTION: Take the linked list resource structure and fills in the
278 * the appropriate bytes in a byte stream
280 ******************************************************************************/
283 acpi_rs_address16_stream (
284 struct acpi_resource *linked_list,
286 acpi_size *bytes_consumed)
288 u8 *buffer = *output_buffer;
291 char *temp_pointer = NULL;
292 acpi_size actual_bytes;
295 ACPI_FUNCTION_TRACE ("rs_address16_stream");
298 /* The descriptor field is static */
303 /* Save a pointer to the Length field - to be filled in later */
305 length_field = buffer;
308 /* Set the Resource Type (Memory, Io, bus_number) */
310 temp8 = (u8) (linked_list->data.address16.resource_type & 0x03);
314 /* Set the general flags */
316 temp8 = (u8) (linked_list->data.address16.producer_consumer & 0x01);
318 temp8 |= (linked_list->data.address16.decode & 0x01) << 1;
319 temp8 |= (linked_list->data.address16.min_address_fixed & 0x01) << 2;
320 temp8 |= (linked_list->data.address16.max_address_fixed & 0x01) << 3;
325 /* Set the type specific flags */
329 if (ACPI_MEMORY_RANGE == linked_list->data.address16.resource_type) {
331 (linked_list->data.address16.attribute.memory.read_write_attribute &
335 (linked_list->data.address16.attribute.memory.cache_attribute &
338 else if (ACPI_IO_RANGE == linked_list->data.address16.resource_type) {
340 (linked_list->data.address16.attribute.io.range_attribute &
343 (linked_list->data.address16.attribute.io.translation_attribute &
350 /* Set the address space granularity */
352 ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.granularity);
355 /* Set the address range minimum */
357 ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.min_address_range);
360 /* Set the address range maximum */
362 ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.max_address_range);
365 /* Set the address translation offset */
367 ACPI_MOVE_32_TO_16 (buffer,
368 &linked_list->data.address16.address_translation_offset);
371 /* Set the address length */
373 ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.address_length);
376 /* Resource Source Index and Resource Source are optional */
378 if (0 != linked_list->data.address16.resource_source.string_length) {
379 temp8 = (u8) linked_list->data.address16.resource_source.index;
384 temp_pointer = (char *) buffer;
386 /* Copy the string */
388 ACPI_STRCPY (temp_pointer,
389 linked_list->data.address16.resource_source.string_ptr);
392 * Buffer needs to be set to the length of the sting + one for the
395 buffer += (acpi_size)(ACPI_STRLEN (
396 linked_list->data.address16.resource_source.string_ptr) + 1);
399 /* Return the number of bytes consumed in this operation */
401 actual_bytes = ACPI_PTR_DIFF (buffer, *output_buffer);
402 *bytes_consumed = actual_bytes;
405 * Set the length field to the number of bytes consumed
406 * minus the header size (3 bytes)
409 ACPI_MOVE_SIZE_TO_16 (length_field, &actual_bytes);
410 return_ACPI_STATUS (AE_OK);
414 /*******************************************************************************
416 * FUNCTION: acpi_rs_address32_resource
418 * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
420 * bytes_consumed - Pointer to where the number of bytes
421 * consumed the byte_stream_buffer is
423 * output_buffer - Pointer to the return data buffer
424 * structure_size - Pointer to where the number of bytes
425 * in the return data struct is returned
429 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
430 * structure pointed to by the output_buffer. Return the
431 * number of bytes consumed from the byte stream.
433 ******************************************************************************/
436 acpi_rs_address32_resource (
437 u8 *byte_stream_buffer,
438 acpi_size *bytes_consumed,
440 acpi_size *structure_size)
443 struct acpi_resource *output_struct= (void *) *output_buffer;
447 acpi_size struct_size;
451 ACPI_FUNCTION_TRACE ("rs_address32_resource");
454 buffer = byte_stream_buffer;
455 struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address32);
457 /* Point past the Descriptor to get the number of bytes consumed */
460 ACPI_MOVE_16_TO_16 (&temp16, buffer);
462 /* Validate minimum descriptor length */
465 return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
468 *bytes_consumed = temp16 + 3;
469 output_struct->id = ACPI_RSTYPE_ADDRESS32;
471 /* Get the Resource Type (Byte3) */
476 /* Values 0-2 and 0xC0-0xFF are valid */
478 if ((temp8 > 2) && (temp8 < 0xC0)) {
479 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
482 output_struct->data.address32.resource_type = temp8;
484 /* Get the General Flags (Byte4) */
489 /* Producer / Consumer */
491 output_struct->data.address32.producer_consumer = temp8 & 0x01;
495 output_struct->data.address32.decode = (temp8 >> 1) & 0x01;
497 /* Min Address Fixed */
499 output_struct->data.address32.min_address_fixed = (temp8 >> 2) & 0x01;
501 /* Max Address Fixed */
503 output_struct->data.address32.max_address_fixed = (temp8 >> 3) & 0x01;
505 /* Get the Type Specific Flags (Byte5) */
510 if (ACPI_MEMORY_RANGE == output_struct->data.address32.resource_type) {
511 output_struct->data.address32.attribute.memory.read_write_attribute =
512 (u16) (temp8 & 0x01);
514 output_struct->data.address32.attribute.memory.cache_attribute =
515 (u16) ((temp8 >> 1) & 0x03);
518 if (ACPI_IO_RANGE == output_struct->data.address32.resource_type) {
519 output_struct->data.address32.attribute.io.range_attribute =
520 (u16) (temp8 & 0x03);
521 output_struct->data.address32.attribute.io.translation_attribute =
522 (u16) ((temp8 >> 4) & 0x03);
525 /* BUS_NUMBER_RANGE == output_struct->Data.Address32.resource_type */
526 /* Nothing needs to be filled in */
530 /* Get Granularity (Bytes 6-9) */
533 ACPI_MOVE_32_TO_32 (&output_struct->data.address32.granularity, buffer);
535 /* Get min_address_range (Bytes 10-13) */
538 ACPI_MOVE_32_TO_32 (&output_struct->data.address32.min_address_range, buffer);
540 /* Get max_address_range (Bytes 14-17) */
543 ACPI_MOVE_32_TO_32 (&output_struct->data.address32.max_address_range, buffer);
545 /* Get address_translation_offset (Bytes 18-21) */
548 ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_translation_offset,
551 /* Get address_length (Bytes 22-25) */
554 ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_length, buffer);
556 /* Resource Source Index (if present) */
561 * This will leave us pointing to the Resource Source Index
562 * If it is present, then save it off and calculate the
563 * pointer to where the null terminated string goes:
565 * Note: Some resource descriptors will have an additional null, so
566 * we add 1 to the length.
568 if (*bytes_consumed > (26 + 1)) {
569 /* Dereference the Index */
572 output_struct->data.address32.resource_source.index =
575 /* Point to the String */
579 /* Point the String pointer to the end of this structure */
581 output_struct->data.address32.resource_source.string_ptr =
582 (char *)((u8 *)output_struct + struct_size);
585 output_struct->data.address32.resource_source.string_ptr;
587 /* Copy the string into the buffer */
590 while (0x00 != *buffer) {
598 /* Add the terminating null */
601 output_struct->data.address32.resource_source.string_length = index + 1;
604 * In order for the struct_size to fall on a 32-bit boundary,
605 * calculate the length of the string and expand the
606 * struct_size to the next 32-bit boundary.
608 temp8 = (u8) (index + 1);
609 struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
612 output_struct->data.address32.resource_source.index = 0x00;
613 output_struct->data.address32.resource_source.string_length = 0;
614 output_struct->data.address32.resource_source.string_ptr = NULL;
617 /* Set the Length parameter */
619 output_struct->length = (u32) struct_size;
621 /* Return the final size of the structure */
623 *structure_size = struct_size;
624 return_ACPI_STATUS (AE_OK);
628 /*******************************************************************************
630 * FUNCTION: acpi_rs_address32_stream
632 * PARAMETERS: linked_list - Pointer to the resource linked list
633 * output_buffer - Pointer to the user's return buffer
634 * bytes_consumed - Pointer to where the number of bytes
635 * used in the output_buffer is returned
639 * DESCRIPTION: Take the linked list resource structure and fills in the
640 * the appropriate bytes in a byte stream
642 ******************************************************************************/
645 acpi_rs_address32_stream (
646 struct acpi_resource *linked_list,
648 acpi_size *bytes_consumed)
656 ACPI_FUNCTION_TRACE ("rs_address32_stream");
659 buffer = *output_buffer;
661 /* The descriptor field is static */
666 /* Set a pointer to the Length field - to be filled in later */
668 length_field = ACPI_CAST_PTR (u16, buffer);
671 /* Set the Resource Type (Memory, Io, bus_number) */
673 temp8 = (u8) (linked_list->data.address32.resource_type & 0x03);
678 /* Set the general flags */
680 temp8 = (u8) (linked_list->data.address32.producer_consumer & 0x01);
681 temp8 |= (linked_list->data.address32.decode & 0x01) << 1;
682 temp8 |= (linked_list->data.address32.min_address_fixed & 0x01) << 2;
683 temp8 |= (linked_list->data.address32.max_address_fixed & 0x01) << 3;
688 /* Set the type specific flags */
692 if (ACPI_MEMORY_RANGE == linked_list->data.address32.resource_type) {
694 (linked_list->data.address32.attribute.memory.read_write_attribute &
698 (linked_list->data.address32.attribute.memory.cache_attribute &
701 else if (ACPI_IO_RANGE == linked_list->data.address32.resource_type) {
703 (linked_list->data.address32.attribute.io.range_attribute &
706 (linked_list->data.address32.attribute.io.translation_attribute &
713 /* Set the address space granularity */
715 ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.granularity);
718 /* Set the address range minimum */
720 ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.min_address_range);
723 /* Set the address range maximum */
725 ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.max_address_range);
728 /* Set the address translation offset */
730 ACPI_MOVE_32_TO_32 (buffer,
731 &linked_list->data.address32.address_translation_offset);
734 /* Set the address length */
736 ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.address_length);
739 /* Resource Source Index and Resource Source are optional */
741 if (0 != linked_list->data.address32.resource_source.string_length) {
742 temp8 = (u8) linked_list->data.address32.resource_source.index;
747 temp_pointer = (char *) buffer;
749 /* Copy the string */
751 ACPI_STRCPY (temp_pointer,
752 linked_list->data.address32.resource_source.string_ptr);
755 * Buffer needs to be set to the length of the sting + one for the
758 buffer += (acpi_size)(ACPI_STRLEN (
759 linked_list->data.address32.resource_source.string_ptr) + 1);
762 /* Return the number of bytes consumed in this operation */
764 *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
767 * Set the length field to the number of bytes consumed
768 * minus the header size (3 bytes)
770 *length_field = (u16) (*bytes_consumed - 3);
771 return_ACPI_STATUS (AE_OK);
775 /*******************************************************************************
777 * FUNCTION: acpi_rs_address64_resource
779 * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
781 * bytes_consumed - Pointer to where the number of bytes
782 * consumed the byte_stream_buffer is
784 * output_buffer - Pointer to the return data buffer
785 * structure_size - Pointer to where the number of bytes
786 * in the return data struct is returned
790 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
791 * structure pointed to by the output_buffer. Return the
792 * number of bytes consumed from the byte stream.
794 ******************************************************************************/
797 acpi_rs_address64_resource (
798 u8 *byte_stream_buffer,
799 acpi_size *bytes_consumed,
801 acpi_size *structure_size)
804 struct acpi_resource *output_struct = (void *) *output_buffer;
809 acpi_size struct_size;
813 ACPI_FUNCTION_TRACE ("rs_address64_resource");
816 buffer = byte_stream_buffer;
817 struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64);
818 resource_type = *buffer;
820 /* Point past the Descriptor to get the number of bytes consumed */
823 ACPI_MOVE_16_TO_16 (&temp16, buffer);
825 /* Validate minimum descriptor length */
828 return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
831 *bytes_consumed = temp16 + 3;
832 output_struct->id = ACPI_RSTYPE_ADDRESS64;
834 /* Get the Resource Type (Byte3) */
839 /* Values 0-2 and 0xC0-0xFF are valid */
841 if ((temp8 > 2) && (temp8 < 0xC0)) {
842 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
845 output_struct->data.address64.resource_type = temp8;
847 /* Get the General Flags (Byte4) */
852 /* Producer / Consumer */
854 output_struct->data.address64.producer_consumer = temp8 & 0x01;
858 output_struct->data.address64.decode = (temp8 >> 1) & 0x01;
860 /* Min Address Fixed */
862 output_struct->data.address64.min_address_fixed = (temp8 >> 2) & 0x01;
864 /* Max Address Fixed */
866 output_struct->data.address64.max_address_fixed = (temp8 >> 3) & 0x01;
868 /* Get the Type Specific Flags (Byte5) */
873 if (ACPI_MEMORY_RANGE == output_struct->data.address64.resource_type) {
874 output_struct->data.address64.attribute.memory.read_write_attribute =
875 (u16) (temp8 & 0x01);
877 output_struct->data.address64.attribute.memory.cache_attribute =
878 (u16) ((temp8 >> 1) & 0x03);
881 if (ACPI_IO_RANGE == output_struct->data.address64.resource_type) {
882 output_struct->data.address64.attribute.io.range_attribute =
883 (u16) (temp8 & 0x03);
884 output_struct->data.address64.attribute.io.translation_attribute =
885 (u16) ((temp8 >> 4) & 0x03);
888 /* BUS_NUMBER_RANGE == output_struct->Data.Address64.resource_type */
889 /* Nothing needs to be filled in */
893 if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) {
894 /* Move past revision_id and Reserved byte */
899 /* Get Granularity (Bytes 6-13) or (Bytes 8-15) */
902 ACPI_MOVE_64_TO_64 (&output_struct->data.address64.granularity, buffer);
904 /* Get min_address_range (Bytes 14-21) or (Bytes 16-23) */
907 ACPI_MOVE_64_TO_64 (&output_struct->data.address64.min_address_range, buffer);
909 /* Get max_address_range (Bytes 22-29) or (Bytes 24-31) */
912 ACPI_MOVE_64_TO_64 (&output_struct->data.address64.max_address_range, buffer);
914 /* Get address_translation_offset (Bytes 30-37) or (Bytes 32-39) */
917 ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_translation_offset,
920 /* Get address_length (Bytes 38-45) or (Bytes 40-47) */
923 ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_length, buffer);
925 output_struct->data.address64.resource_source.index = 0x00;
926 output_struct->data.address64.resource_source.string_length = 0;
927 output_struct->data.address64.resource_source.string_ptr = NULL;
929 if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) {
930 /* Get type_specific_attribute (Bytes 48-55) */
934 &output_struct->data.address64.type_specific_attributes,
938 output_struct->data.address64.type_specific_attributes = 0;
940 /* Resource Source Index (if present) */
945 * This will leave us pointing to the Resource Source Index
946 * If it is present, then save it off and calculate the
947 * pointer to where the null terminated string goes:
948 * Each Interrupt takes 32-bits + the 5 bytes of the
949 * stream that are default.
951 * Note: Some resource descriptors will have an additional null, so
952 * we add 1 to the length.
954 if (*bytes_consumed > (46 + 1)) {
955 /* Dereference the Index */
958 output_struct->data.address64.resource_source.index =
961 /* Point to the String */
965 /* Point the String pointer to the end of this structure */
967 output_struct->data.address64.resource_source.string_ptr =
968 (char *)((u8 *)output_struct + struct_size);
971 output_struct->data.address64.resource_source.string_ptr;
973 /* Copy the string into the buffer */
976 while (0x00 != *buffer) {
985 * Add the terminating null
988 output_struct->data.address64.resource_source.string_length =
992 * In order for the struct_size to fall on a 32-bit boundary,
993 * calculate the length of the string and expand the
994 * struct_size to the next 32-bit boundary.
996 temp8 = (u8) (index + 1);
997 struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
1001 /* Set the Length parameter */
1003 output_struct->length = (u32) struct_size;
1005 /* Return the final size of the structure */
1007 *structure_size = struct_size;
1008 return_ACPI_STATUS (AE_OK);
1012 /*******************************************************************************
1014 * FUNCTION: acpi_rs_address64_stream
1016 * PARAMETERS: linked_list - Pointer to the resource linked list
1017 * output_buffer - Pointer to the user's return buffer
1018 * bytes_consumed - Pointer to where the number of bytes
1019 * used in the output_buffer is returned
1023 * DESCRIPTION: Take the linked list resource structure and fills in the
1024 * the appropriate bytes in a byte stream
1026 ******************************************************************************/
1029 acpi_rs_address64_stream (
1030 struct acpi_resource *linked_list,
1032 acpi_size *bytes_consumed)
1040 ACPI_FUNCTION_TRACE ("rs_address64_stream");
1043 buffer = *output_buffer;
1045 /* The descriptor field is static */
1050 /* Set a pointer to the Length field - to be filled in later */
1052 length_field = ACPI_CAST_PTR (u16, buffer);
1055 /* Set the Resource Type (Memory, Io, bus_number) */
1057 temp8 = (u8) (linked_list->data.address64.resource_type & 0x03);
1062 /* Set the general flags */
1064 temp8 = (u8) (linked_list->data.address64.producer_consumer & 0x01);
1065 temp8 |= (linked_list->data.address64.decode & 0x01) << 1;
1066 temp8 |= (linked_list->data.address64.min_address_fixed & 0x01) << 2;
1067 temp8 |= (linked_list->data.address64.max_address_fixed & 0x01) << 3;
1072 /* Set the type specific flags */
1076 if (ACPI_MEMORY_RANGE == linked_list->data.address64.resource_type) {
1078 (linked_list->data.address64.attribute.memory.read_write_attribute &
1082 (linked_list->data.address64.attribute.memory.cache_attribute &
1085 else if (ACPI_IO_RANGE == linked_list->data.address64.resource_type) {
1087 (linked_list->data.address64.attribute.io.range_attribute &
1090 (linked_list->data.address64.attribute.io.range_attribute &
1097 /* Set the address space granularity */
1099 ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.granularity);
1102 /* Set the address range minimum */
1104 ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.min_address_range);
1107 /* Set the address range maximum */
1109 ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.max_address_range);
1112 /* Set the address translation offset */
1114 ACPI_MOVE_64_TO_64 (buffer,
1115 &linked_list->data.address64.address_translation_offset);
1118 /* Set the address length */
1120 ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.address_length);
1123 /* Resource Source Index and Resource Source are optional */
1125 if (0 != linked_list->data.address64.resource_source.string_length) {
1126 temp8 = (u8) linked_list->data.address64.resource_source.index;
1131 temp_pointer = (char *) buffer;
1133 /* Copy the string */
1135 ACPI_STRCPY (temp_pointer,
1136 linked_list->data.address64.resource_source.string_ptr);
1139 * Buffer needs to be set to the length of the sting + one for the
1142 buffer += (acpi_size)(ACPI_STRLEN (
1143 linked_list->data.address64.resource_source.string_ptr) + 1);
1146 /* Return the number of bytes consumed in this operation */
1148 *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
1151 * Set the length field to the number of bytes consumed
1152 * minus the header size (3 bytes)
1154 *length_field = (u16) (*bytes_consumed - 3);
1155 return_ACPI_STATUS (AE_OK);