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.
44 #include <acpi/acpi.h>
45 #include <acpi/acresrc.h>
47 #define _COMPONENT ACPI_RESOURCES
48 ACPI_MODULE_NAME("rsaddr")
50 /*******************************************************************************
52 * FUNCTION: acpi_rs_address16_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_address16_resource(u8 * byte_stream_buffer,
72 acpi_size * bytes_consumed,
73 u8 ** output_buffer, acpi_size * structure_size)
79 u8 *buffer = byte_stream_buffer;
80 struct acpi_resource *output_struct = (void *)*output_buffer;
81 acpi_size struct_size =
82 ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16);
84 ACPI_FUNCTION_TRACE("rs_address16_resource");
86 /* Point past the Descriptor to get the number of bytes consumed */
89 ACPI_MOVE_16_TO_16(&temp16, buffer);
91 /* Validate minimum descriptor length */
94 return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
97 *bytes_consumed = temp16 + 3;
98 output_struct->id = ACPI_RSTYPE_ADDRESS16;
100 /* Get the Resource Type (Byte3) */
105 /* Values 0-2 and 0xC0-0xFF are valid */
107 if ((temp8 > 2) && (temp8 < 0xC0)) {
108 return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
111 output_struct->data.address16.resource_type = temp8;
113 /* Get the General Flags (Byte4) */
118 /* Producer / Consumer */
120 output_struct->data.address16.producer_consumer = temp8 & 0x01;
124 output_struct->data.address16.decode = (temp8 >> 1) & 0x01;
126 /* Min Address Fixed */
128 output_struct->data.address16.min_address_fixed = (temp8 >> 2) & 0x01;
130 /* Max Address Fixed */
132 output_struct->data.address16.max_address_fixed = (temp8 >> 3) & 0x01;
134 /* Get the Type Specific Flags (Byte5) */
139 if (ACPI_MEMORY_RANGE == output_struct->data.address16.resource_type) {
140 output_struct->data.address16.attribute.memory.
141 read_write_attribute = (u16) (temp8 & 0x01);
142 output_struct->data.address16.attribute.memory.cache_attribute =
143 (u16) ((temp8 >> 1) & 0x03);
146 output_struct->data.address16.resource_type) {
147 output_struct->data.address16.attribute.io.
148 range_attribute = (u16) (temp8 & 0x03);
149 output_struct->data.address16.attribute.io.
150 translation_attribute = (u16) ((temp8 >> 4) & 0x03);
152 /* BUS_NUMBER_RANGE == Address16.Data->resource_type */
153 /* Nothing needs to be filled in */
157 /* Get Granularity (Bytes 6-7) */
160 ACPI_MOVE_16_TO_32(&output_struct->data.address16.granularity, buffer);
162 /* Get min_address_range (Bytes 8-9) */
165 ACPI_MOVE_16_TO_32(&output_struct->data.address16.min_address_range,
168 /* Get max_address_range (Bytes 10-11) */
171 ACPI_MOVE_16_TO_32(&output_struct->data.address16.max_address_range,
174 /* Get address_translation_offset (Bytes 12-13) */
177 ACPI_MOVE_16_TO_32(&output_struct->data.address16.
178 address_translation_offset, buffer);
180 /* Get address_length (Bytes 14-15) */
183 ACPI_MOVE_16_TO_32(&output_struct->data.address16.address_length,
186 /* Resource Source Index (if present) */
191 * This will leave us pointing to the Resource Source Index
192 * If it is present, then save it off and calculate the
193 * pointer to where the null terminated string goes:
194 * Each Interrupt takes 32-bits + the 5 bytes of the
195 * stream that are default.
197 * Note: Some resource descriptors will have an additional null, so
198 * we add 1 to the length.
200 if (*bytes_consumed > (16 + 1)) {
201 /* Dereference the Index */
204 output_struct->data.address16.resource_source.index =
207 /* Point to the String */
211 /* Point the String pointer to the end of this structure */
213 output_struct->data.address16.resource_source.string_ptr =
214 (char *)((u8 *) output_struct + struct_size);
217 output_struct->data.address16.resource_source.string_ptr;
219 /* Copy the string into the buffer */
223 while (0x00 != *buffer) {
231 /* Add the terminating null */
235 output_struct->data.address16.resource_source.string_length =
239 * In order for the struct_size to fall on a 32-bit boundary,
240 * calculate the length of the string and expand the
241 * struct_size to the next 32-bit boundary.
243 temp8 = (u8) (index + 1);
244 struct_size += ACPI_ROUND_UP_to_32_bITS(temp8);
246 output_struct->data.address16.resource_source.index = 0x00;
247 output_struct->data.address16.resource_source.string_length = 0;
248 output_struct->data.address16.resource_source.string_ptr = NULL;
251 /* Set the Length parameter */
253 output_struct->length = (u32) struct_size;
255 /* Return the final size of the structure */
257 *structure_size = struct_size;
258 return_ACPI_STATUS(AE_OK);
261 /*******************************************************************************
263 * FUNCTION: acpi_rs_address16_stream
265 * PARAMETERS: linked_list - Pointer to the resource linked list
266 * output_buffer - Pointer to the user's return buffer
267 * bytes_consumed - Pointer to where the number of bytes
268 * used in the output_buffer is returned
272 * DESCRIPTION: Take the linked list resource structure and fills in the
273 * the appropriate bytes in a byte stream
275 ******************************************************************************/
278 acpi_rs_address16_stream(struct acpi_resource *linked_list,
279 u8 ** output_buffer, acpi_size * bytes_consumed)
281 u8 *buffer = *output_buffer;
284 char *temp_pointer = NULL;
285 acpi_size actual_bytes;
287 ACPI_FUNCTION_TRACE("rs_address16_stream");
289 /* The descriptor field is static */
294 /* Save a pointer to the Length field - to be filled in later */
296 length_field = buffer;
299 /* Set the Resource Type (Memory, Io, bus_number) */
301 temp8 = (u8) (linked_list->data.address16.resource_type & 0x03);
305 /* Set the general flags */
307 temp8 = (u8) (linked_list->data.address16.producer_consumer & 0x01);
309 temp8 |= (linked_list->data.address16.decode & 0x01) << 1;
310 temp8 |= (linked_list->data.address16.min_address_fixed & 0x01) << 2;
311 temp8 |= (linked_list->data.address16.max_address_fixed & 0x01) << 3;
316 /* Set the type specific flags */
320 if (ACPI_MEMORY_RANGE == linked_list->data.address16.resource_type) {
322 (linked_list->data.address16.attribute.memory.
323 read_write_attribute & 0x01);
326 (linked_list->data.address16.attribute.memory.
327 cache_attribute & 0x03) << 1;
328 } else if (ACPI_IO_RANGE == linked_list->data.address16.resource_type) {
330 (linked_list->data.address16.attribute.io.range_attribute &
333 (linked_list->data.address16.attribute.io.
334 translation_attribute & 0x03) << 4;
340 /* Set the address space granularity */
342 ACPI_MOVE_32_TO_16(buffer, &linked_list->data.address16.granularity);
345 /* Set the address range minimum */
347 ACPI_MOVE_32_TO_16(buffer,
348 &linked_list->data.address16.min_address_range);
351 /* Set the address range maximum */
353 ACPI_MOVE_32_TO_16(buffer,
354 &linked_list->data.address16.max_address_range);
357 /* Set the address translation offset */
359 ACPI_MOVE_32_TO_16(buffer,
360 &linked_list->data.address16.
361 address_translation_offset);
364 /* Set the address length */
366 ACPI_MOVE_32_TO_16(buffer, &linked_list->data.address16.address_length);
369 /* Resource Source Index and Resource Source are optional */
371 if (0 != linked_list->data.address16.resource_source.string_length) {
372 temp8 = (u8) linked_list->data.address16.resource_source.index;
377 temp_pointer = (char *)buffer;
379 /* Copy the string */
381 ACPI_STRCPY(temp_pointer,
382 linked_list->data.address16.resource_source.
386 * Buffer needs to be set to the length of the sting + one for the
390 (acpi_size) (ACPI_STRLEN
391 (linked_list->data.address16.resource_source.
395 /* Return the number of bytes consumed in this operation */
397 actual_bytes = ACPI_PTR_DIFF(buffer, *output_buffer);
398 *bytes_consumed = actual_bytes;
401 * Set the length field to the number of bytes consumed
402 * minus the header size (3 bytes)
405 ACPI_MOVE_SIZE_TO_16(length_field, &actual_bytes);
406 return_ACPI_STATUS(AE_OK);
409 /*******************************************************************************
411 * FUNCTION: acpi_rs_address32_resource
413 * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
415 * bytes_consumed - Pointer to where the number of bytes
416 * consumed the byte_stream_buffer is
418 * output_buffer - Pointer to the return data buffer
419 * structure_size - Pointer to where the number of bytes
420 * in the return data struct is returned
424 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
425 * structure pointed to by the output_buffer. Return the
426 * number of bytes consumed from the byte stream.
428 ******************************************************************************/
431 acpi_rs_address32_resource(u8 * byte_stream_buffer,
432 acpi_size * bytes_consumed,
433 u8 ** output_buffer, acpi_size * structure_size)
436 struct acpi_resource *output_struct = (void *)*output_buffer;
440 acpi_size struct_size;
443 ACPI_FUNCTION_TRACE("rs_address32_resource");
445 buffer = byte_stream_buffer;
446 struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32);
448 /* Point past the Descriptor to get the number of bytes consumed */
451 ACPI_MOVE_16_TO_16(&temp16, buffer);
453 /* Validate minimum descriptor length */
456 return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
459 *bytes_consumed = temp16 + 3;
460 output_struct->id = ACPI_RSTYPE_ADDRESS32;
462 /* Get the Resource Type (Byte3) */
467 /* Values 0-2 and 0xC0-0xFF are valid */
469 if ((temp8 > 2) && (temp8 < 0xC0)) {
470 return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
473 output_struct->data.address32.resource_type = temp8;
475 /* Get the General Flags (Byte4) */
480 /* Producer / Consumer */
482 output_struct->data.address32.producer_consumer = temp8 & 0x01;
486 output_struct->data.address32.decode = (temp8 >> 1) & 0x01;
488 /* Min Address Fixed */
490 output_struct->data.address32.min_address_fixed = (temp8 >> 2) & 0x01;
492 /* Max Address Fixed */
494 output_struct->data.address32.max_address_fixed = (temp8 >> 3) & 0x01;
496 /* Get the Type Specific Flags (Byte5) */
501 if (ACPI_MEMORY_RANGE == output_struct->data.address32.resource_type) {
502 output_struct->data.address32.attribute.memory.
503 read_write_attribute = (u16) (temp8 & 0x01);
505 output_struct->data.address32.attribute.memory.cache_attribute =
506 (u16) ((temp8 >> 1) & 0x03);
509 output_struct->data.address32.resource_type) {
510 output_struct->data.address32.attribute.io.
511 range_attribute = (u16) (temp8 & 0x03);
512 output_struct->data.address32.attribute.io.
513 translation_attribute = (u16) ((temp8 >> 4) & 0x03);
515 /* BUS_NUMBER_RANGE == output_struct->Data.Address32.resource_type */
516 /* Nothing needs to be filled in */
520 /* Get Granularity (Bytes 6-9) */
523 ACPI_MOVE_32_TO_32(&output_struct->data.address32.granularity, buffer);
525 /* Get min_address_range (Bytes 10-13) */
528 ACPI_MOVE_32_TO_32(&output_struct->data.address32.min_address_range,
531 /* Get max_address_range (Bytes 14-17) */
534 ACPI_MOVE_32_TO_32(&output_struct->data.address32.max_address_range,
537 /* Get address_translation_offset (Bytes 18-21) */
540 ACPI_MOVE_32_TO_32(&output_struct->data.address32.
541 address_translation_offset, buffer);
543 /* Get address_length (Bytes 22-25) */
546 ACPI_MOVE_32_TO_32(&output_struct->data.address32.address_length,
549 /* Resource Source Index (if present) */
554 * This will leave us pointing to the Resource Source Index
555 * If it is present, then save it off and calculate the
556 * pointer to where the null terminated string goes:
558 * Note: Some resource descriptors will have an additional null, so
559 * we add 1 to the length.
561 if (*bytes_consumed > (26 + 1)) {
562 /* Dereference the Index */
565 output_struct->data.address32.resource_source.index =
568 /* Point to the String */
572 /* Point the String pointer to the end of this structure */
574 output_struct->data.address32.resource_source.string_ptr =
575 (char *)((u8 *) output_struct + struct_size);
578 output_struct->data.address32.resource_source.string_ptr;
580 /* Copy the string into the buffer */
583 while (0x00 != *buffer) {
591 /* Add the terminating null */
594 output_struct->data.address32.resource_source.string_length =
598 * In order for the struct_size to fall on a 32-bit boundary,
599 * calculate the length of the string and expand the
600 * struct_size to the next 32-bit boundary.
602 temp8 = (u8) (index + 1);
603 struct_size += ACPI_ROUND_UP_to_32_bITS(temp8);
605 output_struct->data.address32.resource_source.index = 0x00;
606 output_struct->data.address32.resource_source.string_length = 0;
607 output_struct->data.address32.resource_source.string_ptr = NULL;
610 /* Set the Length parameter */
612 output_struct->length = (u32) struct_size;
614 /* Return the final size of the structure */
616 *structure_size = struct_size;
617 return_ACPI_STATUS(AE_OK);
620 /*******************************************************************************
622 * FUNCTION: acpi_rs_address32_stream
624 * PARAMETERS: linked_list - Pointer to the resource linked list
625 * output_buffer - Pointer to the user's return buffer
626 * bytes_consumed - Pointer to where the number of bytes
627 * used in the output_buffer is returned
631 * DESCRIPTION: Take the linked list resource structure and fills in the
632 * the appropriate bytes in a byte stream
634 ******************************************************************************/
637 acpi_rs_address32_stream(struct acpi_resource *linked_list,
638 u8 ** output_buffer, acpi_size * bytes_consumed)
645 ACPI_FUNCTION_TRACE("rs_address32_stream");
647 buffer = *output_buffer;
649 /* The descriptor field is static */
654 /* Set a pointer to the Length field - to be filled in later */
656 length_field = ACPI_CAST_PTR(u16, buffer);
659 /* Set the Resource Type (Memory, Io, bus_number) */
661 temp8 = (u8) (linked_list->data.address32.resource_type & 0x03);
666 /* Set the general flags */
668 temp8 = (u8) (linked_list->data.address32.producer_consumer & 0x01);
669 temp8 |= (linked_list->data.address32.decode & 0x01) << 1;
670 temp8 |= (linked_list->data.address32.min_address_fixed & 0x01) << 2;
671 temp8 |= (linked_list->data.address32.max_address_fixed & 0x01) << 3;
676 /* Set the type specific flags */
680 if (ACPI_MEMORY_RANGE == linked_list->data.address32.resource_type) {
682 (linked_list->data.address32.attribute.memory.
683 read_write_attribute & 0x01);
686 (linked_list->data.address32.attribute.memory.
687 cache_attribute & 0x03) << 1;
688 } else if (ACPI_IO_RANGE == linked_list->data.address32.resource_type) {
690 (linked_list->data.address32.attribute.io.range_attribute &
693 (linked_list->data.address32.attribute.io.
694 translation_attribute & 0x03) << 4;
700 /* Set the address space granularity */
702 ACPI_MOVE_32_TO_32(buffer, &linked_list->data.address32.granularity);
705 /* Set the address range minimum */
707 ACPI_MOVE_32_TO_32(buffer,
708 &linked_list->data.address32.min_address_range);
711 /* Set the address range maximum */
713 ACPI_MOVE_32_TO_32(buffer,
714 &linked_list->data.address32.max_address_range);
717 /* Set the address translation offset */
719 ACPI_MOVE_32_TO_32(buffer,
720 &linked_list->data.address32.
721 address_translation_offset);
724 /* Set the address length */
726 ACPI_MOVE_32_TO_32(buffer, &linked_list->data.address32.address_length);
729 /* Resource Source Index and Resource Source are optional */
731 if (0 != linked_list->data.address32.resource_source.string_length) {
732 temp8 = (u8) linked_list->data.address32.resource_source.index;
737 temp_pointer = (char *)buffer;
739 /* Copy the string */
741 ACPI_STRCPY(temp_pointer,
742 linked_list->data.address32.resource_source.
746 * Buffer needs to be set to the length of the sting + one for the
750 (acpi_size) (ACPI_STRLEN
751 (linked_list->data.address32.resource_source.
755 /* Return the number of bytes consumed in this operation */
757 *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
760 * Set the length field to the number of bytes consumed
761 * minus the header size (3 bytes)
763 *length_field = (u16) (*bytes_consumed - 3);
764 return_ACPI_STATUS(AE_OK);
767 /*******************************************************************************
769 * FUNCTION: acpi_rs_address64_resource
771 * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
773 * bytes_consumed - Pointer to where the number of bytes
774 * consumed the byte_stream_buffer is
776 * output_buffer - Pointer to the return data buffer
777 * structure_size - Pointer to where the number of bytes
778 * in the return data struct is returned
782 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
783 * structure pointed to by the output_buffer. Return the
784 * number of bytes consumed from the byte stream.
786 ******************************************************************************/
789 acpi_rs_address64_resource(u8 * byte_stream_buffer,
790 acpi_size * bytes_consumed,
791 u8 ** output_buffer, acpi_size * structure_size)
794 struct acpi_resource *output_struct = (void *)*output_buffer;
799 acpi_size struct_size;
802 ACPI_FUNCTION_TRACE("rs_address64_resource");
804 buffer = byte_stream_buffer;
805 struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64);
806 resource_type = *buffer;
808 /* Point past the Descriptor to get the number of bytes consumed */
811 ACPI_MOVE_16_TO_16(&temp16, buffer);
813 /* Validate minimum descriptor length */
816 return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
819 *bytes_consumed = temp16 + 3;
820 output_struct->id = ACPI_RSTYPE_ADDRESS64;
822 /* Get the Resource Type (Byte3) */
827 /* Values 0-2 and 0xC0-0xFF are valid */
829 if ((temp8 > 2) && (temp8 < 0xC0)) {
830 return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
833 output_struct->data.address64.resource_type = temp8;
835 /* Get the General Flags (Byte4) */
840 /* Producer / Consumer */
842 output_struct->data.address64.producer_consumer = temp8 & 0x01;
846 output_struct->data.address64.decode = (temp8 >> 1) & 0x01;
848 /* Min Address Fixed */
850 output_struct->data.address64.min_address_fixed = (temp8 >> 2) & 0x01;
852 /* Max Address Fixed */
854 output_struct->data.address64.max_address_fixed = (temp8 >> 3) & 0x01;
856 /* Get the Type Specific Flags (Byte5) */
861 if (ACPI_MEMORY_RANGE == output_struct->data.address64.resource_type) {
862 output_struct->data.address64.attribute.memory.
863 read_write_attribute = (u16) (temp8 & 0x01);
865 output_struct->data.address64.attribute.memory.cache_attribute =
866 (u16) ((temp8 >> 1) & 0x03);
869 output_struct->data.address64.resource_type) {
870 output_struct->data.address64.attribute.io.
871 range_attribute = (u16) (temp8 & 0x03);
872 output_struct->data.address64.attribute.io.
873 translation_attribute = (u16) ((temp8 >> 4) & 0x03);
875 /* BUS_NUMBER_RANGE == output_struct->Data.Address64.resource_type */
876 /* Nothing needs to be filled in */
880 if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) {
881 /* Move past revision_id and Reserved byte */
886 /* Get Granularity (Bytes 6-13) or (Bytes 8-15) */
889 ACPI_MOVE_64_TO_64(&output_struct->data.address64.granularity, buffer);
891 /* Get min_address_range (Bytes 14-21) or (Bytes 16-23) */
894 ACPI_MOVE_64_TO_64(&output_struct->data.address64.min_address_range,
897 /* Get max_address_range (Bytes 22-29) or (Bytes 24-31) */
900 ACPI_MOVE_64_TO_64(&output_struct->data.address64.max_address_range,
903 /* Get address_translation_offset (Bytes 30-37) or (Bytes 32-39) */
906 ACPI_MOVE_64_TO_64(&output_struct->data.address64.
907 address_translation_offset, buffer);
909 /* Get address_length (Bytes 38-45) or (Bytes 40-47) */
912 ACPI_MOVE_64_TO_64(&output_struct->data.address64.address_length,
915 output_struct->data.address64.resource_source.index = 0x00;
916 output_struct->data.address64.resource_source.string_length = 0;
917 output_struct->data.address64.resource_source.string_ptr = NULL;
919 if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) {
920 /* Get type_specific_attribute (Bytes 48-55) */
923 ACPI_MOVE_64_TO_64(&output_struct->data.address64.
924 type_specific_attributes, buffer);
926 output_struct->data.address64.type_specific_attributes = 0;
928 /* Resource Source Index (if present) */
933 * This will leave us pointing to the Resource Source Index
934 * If it is present, then save it off and calculate the
935 * pointer to where the null terminated string goes:
936 * Each Interrupt takes 32-bits + the 5 bytes of the
937 * stream that are default.
939 * Note: Some resource descriptors will have an additional null, so
940 * we add 1 to the length.
942 if (*bytes_consumed > (46 + 1)) {
943 /* Dereference the Index */
946 output_struct->data.address64.resource_source.index =
949 /* Point to the String */
953 /* Point the String pointer to the end of this structure */
955 output_struct->data.address64.resource_source.
957 (char *)((u8 *) output_struct + struct_size);
960 output_struct->data.address64.resource_source.
963 /* Copy the string into the buffer */
966 while (0x00 != *buffer) {
975 * Add the terminating null
978 output_struct->data.address64.resource_source.
979 string_length = index + 1;
982 * In order for the struct_size to fall on a 32-bit boundary,
983 * calculate the length of the string and expand the
984 * struct_size to the next 32-bit boundary.
986 temp8 = (u8) (index + 1);
987 struct_size += ACPI_ROUND_UP_to_32_bITS(temp8);
991 /* Set the Length parameter */
993 output_struct->length = (u32) struct_size;
995 /* Return the final size of the structure */
997 *structure_size = struct_size;
998 return_ACPI_STATUS(AE_OK);
1001 /*******************************************************************************
1003 * FUNCTION: acpi_rs_address64_stream
1005 * PARAMETERS: linked_list - Pointer to the resource linked list
1006 * output_buffer - Pointer to the user's return buffer
1007 * bytes_consumed - Pointer to where the number of bytes
1008 * used in the output_buffer is returned
1012 * DESCRIPTION: Take the linked list resource structure and fills in the
1013 * the appropriate bytes in a byte stream
1015 ******************************************************************************/
1018 acpi_rs_address64_stream(struct acpi_resource *linked_list,
1019 u8 ** output_buffer, acpi_size * bytes_consumed)
1026 ACPI_FUNCTION_TRACE("rs_address64_stream");
1028 buffer = *output_buffer;
1030 /* The descriptor field is static */
1035 /* Set a pointer to the Length field - to be filled in later */
1037 length_field = ACPI_CAST_PTR(u16, buffer);
1040 /* Set the Resource Type (Memory, Io, bus_number) */
1042 temp8 = (u8) (linked_list->data.address64.resource_type & 0x03);
1047 /* Set the general flags */
1049 temp8 = (u8) (linked_list->data.address64.producer_consumer & 0x01);
1050 temp8 |= (linked_list->data.address64.decode & 0x01) << 1;
1051 temp8 |= (linked_list->data.address64.min_address_fixed & 0x01) << 2;
1052 temp8 |= (linked_list->data.address64.max_address_fixed & 0x01) << 3;
1057 /* Set the type specific flags */
1061 if (ACPI_MEMORY_RANGE == linked_list->data.address64.resource_type) {
1063 (linked_list->data.address64.attribute.memory.
1064 read_write_attribute & 0x01);
1067 (linked_list->data.address64.attribute.memory.
1068 cache_attribute & 0x03) << 1;
1069 } else if (ACPI_IO_RANGE == linked_list->data.address64.resource_type) {
1071 (linked_list->data.address64.attribute.io.range_attribute &
1074 (linked_list->data.address64.attribute.io.range_attribute &
1081 /* Set the address space granularity */
1083 ACPI_MOVE_64_TO_64(buffer, &linked_list->data.address64.granularity);
1086 /* Set the address range minimum */
1088 ACPI_MOVE_64_TO_64(buffer,
1089 &linked_list->data.address64.min_address_range);
1092 /* Set the address range maximum */
1094 ACPI_MOVE_64_TO_64(buffer,
1095 &linked_list->data.address64.max_address_range);
1098 /* Set the address translation offset */
1100 ACPI_MOVE_64_TO_64(buffer,
1101 &linked_list->data.address64.
1102 address_translation_offset);
1105 /* Set the address length */
1107 ACPI_MOVE_64_TO_64(buffer, &linked_list->data.address64.address_length);
1110 /* Resource Source Index and Resource Source are optional */
1112 if (0 != linked_list->data.address64.resource_source.string_length) {
1113 temp8 = (u8) linked_list->data.address64.resource_source.index;
1118 temp_pointer = (char *)buffer;
1120 /* Copy the string */
1122 ACPI_STRCPY(temp_pointer,
1123 linked_list->data.address64.resource_source.
1127 * Buffer needs to be set to the length of the sting + one for the
1131 (acpi_size) (ACPI_STRLEN
1132 (linked_list->data.address64.resource_source.
1136 /* Return the number of bytes consumed in this operation */
1138 *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
1141 * Set the length field to the number of bytes consumed
1142 * minus the header size (3 bytes)
1144 *length_field = (u16) (*bytes_consumed - 3);
1145 return_ACPI_STATUS(AE_OK);