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
);