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
)
80 u8
*buffer
= byte_stream_buffer
;
81 struct acpi_resource
*output_struct
= (void *) *output_buffer
;
83 acpi_size struct_size
= ACPI_SIZEOF_RESOURCE (struct acpi_resource_address16
);
89 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
;
108 * Get the Resource Type (Byte3)
113 /* Values 0-2 and 0xC0-0xFF are valid */
115 if ((temp8
> 2) && (temp8
< 0xC0)) {
116 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE
);
119 output_struct
->data
.address16
.resource_type
= temp8
;
122 * Get the General Flags (Byte4)
127 /* Producer / Consumer */
129 output_struct
->data
.address16
.producer_consumer
= temp8
& 0x01;
133 output_struct
->data
.address16
.decode
= (temp8
>> 1) & 0x01;
135 /* Min Address Fixed */
137 output_struct
->data
.address16
.min_address_fixed
= (temp8
>> 2) & 0x01;
139 /* Max Address Fixed */
141 output_struct
->data
.address16
.max_address_fixed
= (temp8
>> 3) & 0x01;
144 * Get the Type Specific Flags (Byte5)
149 if (ACPI_MEMORY_RANGE
== output_struct
->data
.address16
.resource_type
) {
150 output_struct
->data
.address16
.attribute
.memory
.read_write_attribute
=
151 (u16
) (temp8
& 0x01);
152 output_struct
->data
.address16
.attribute
.memory
.cache_attribute
=
153 (u16
) ((temp8
>> 1) & 0x03);
156 if (ACPI_IO_RANGE
== output_struct
->data
.address16
.resource_type
) {
157 output_struct
->data
.address16
.attribute
.io
.range_attribute
=
158 (u16
) (temp8
& 0x03);
159 output_struct
->data
.address16
.attribute
.io
.translation_attribute
=
160 (u16
) ((temp8
>> 4) & 0x03);
163 /* BUS_NUMBER_RANGE == Address16.Data->resource_type */
164 /* Nothing needs to be filled in */
169 * Get Granularity (Bytes 6-7)
172 ACPI_MOVE_16_TO_32 (&output_struct
->data
.address16
.granularity
, buffer
);
175 * Get min_address_range (Bytes 8-9)
178 ACPI_MOVE_16_TO_32 (&output_struct
->data
.address16
.min_address_range
, buffer
);
181 * Get max_address_range (Bytes 10-11)
184 ACPI_MOVE_16_TO_32 (&output_struct
->data
.address16
.max_address_range
, buffer
);
187 * Get address_translation_offset (Bytes 12-13)
190 ACPI_MOVE_16_TO_32 (&output_struct
->data
.address16
.address_translation_offset
, buffer
);
193 * Get address_length (Bytes 14-15)
196 ACPI_MOVE_16_TO_32 (&output_struct
->data
.address16
.address_length
, buffer
);
199 * Resource Source Index (if present)
204 * This will leave us pointing to the Resource Source Index
205 * If it is present, then save it off and calculate the
206 * pointer to where the null terminated string goes:
207 * Each Interrupt takes 32-bits + the 5 bytes of the
208 * stream that are default.
210 * Note: Some resource descriptors will have an additional null, so
211 * we add 1 to the length.
213 if (*bytes_consumed
> (16 + 1)) {
214 /* Dereference the Index */
217 output_struct
->data
.address16
.resource_source
.index
= (u32
) temp8
;
219 /* Point to the String */
223 /* Point the String pointer to the end of this structure */
225 output_struct
->data
.address16
.resource_source
.string_ptr
=
226 (char *)((u8
* )output_struct
+ struct_size
);
228 temp_ptr
= (u8
*) output_struct
->data
.address16
.resource_source
.string_ptr
;
230 /* Copy the string into the buffer */
234 while (0x00 != *buffer
) {
243 * Add the terminating null
247 output_struct
->data
.address16
.resource_source
.string_length
= index
+ 1;
250 * In order for the struct_size to fall on a 32-bit boundary,
251 * calculate the length of the string and expand the
252 * struct_size to the next 32-bit boundary.
254 temp8
= (u8
) (index
+ 1);
255 struct_size
+= ACPI_ROUND_UP_to_32_bITS (temp8
);
258 output_struct
->data
.address16
.resource_source
.index
= 0x00;
259 output_struct
->data
.address16
.resource_source
.string_length
= 0;
260 output_struct
->data
.address16
.resource_source
.string_ptr
= NULL
;
264 * Set the Length parameter
266 output_struct
->length
= (u32
) struct_size
;
269 * Return the final size of the structure
271 *structure_size
= struct_size
;
272 return_ACPI_STATUS (AE_OK
);
276 /*******************************************************************************
278 * FUNCTION: acpi_rs_address16_stream
280 * PARAMETERS: linked_list - Pointer to the resource linked list
281 * output_buffer - Pointer to the user's return buffer
282 * bytes_consumed - Pointer to where the number of bytes
283 * used in the output_buffer is returned
287 * DESCRIPTION: Take the linked list resource structure and fills in the
288 * the appropriate bytes in a byte stream
290 ******************************************************************************/
293 acpi_rs_address16_stream (
294 struct acpi_resource
*linked_list
,
296 acpi_size
*bytes_consumed
)
298 u8
*buffer
= *output_buffer
;
301 char *temp_pointer
= NULL
;
302 acpi_size actual_bytes
;
305 ACPI_FUNCTION_TRACE ("rs_address16_stream");
309 * The descriptor field is static
315 * Save a pointer to the Length field - to be filled in later
317 length_field
= buffer
;
321 * Set the Resource Type (Memory, Io, bus_number)
323 temp8
= (u8
) (linked_list
->data
.address16
.resource_type
& 0x03);
328 * Set the general flags
330 temp8
= (u8
) (linked_list
->data
.address16
.producer_consumer
& 0x01);
332 temp8
|= (linked_list
->data
.address16
.decode
& 0x01) << 1;
333 temp8
|= (linked_list
->data
.address16
.min_address_fixed
& 0x01) << 2;
334 temp8
|= (linked_list
->data
.address16
.max_address_fixed
& 0x01) << 3;
340 * Set the type specific flags
344 if (ACPI_MEMORY_RANGE
== linked_list
->data
.address16
.resource_type
) {
346 (linked_list
->data
.address16
.attribute
.memory
.read_write_attribute
&
350 (linked_list
->data
.address16
.attribute
.memory
.cache_attribute
&
353 else if (ACPI_IO_RANGE
== linked_list
->data
.address16
.resource_type
) {
355 (linked_list
->data
.address16
.attribute
.io
.range_attribute
&
358 (linked_list
->data
.address16
.attribute
.io
.translation_attribute
&
366 * Set the address space granularity
368 ACPI_MOVE_32_TO_16 (buffer
, &linked_list
->data
.address16
.granularity
);
372 * Set the address range minimum
374 ACPI_MOVE_32_TO_16 (buffer
, &linked_list
->data
.address16
.min_address_range
);
378 * Set the address range maximum
380 ACPI_MOVE_32_TO_16 (buffer
, &linked_list
->data
.address16
.max_address_range
);
384 * Set the address translation offset
386 ACPI_MOVE_32_TO_16 (buffer
, &linked_list
->data
.address16
.address_translation_offset
);
390 * Set the address length
392 ACPI_MOVE_32_TO_16 (buffer
, &linked_list
->data
.address16
.address_length
);
396 * Resource Source Index and Resource Source are optional
398 if (0 != linked_list
->data
.address16
.resource_source
.string_length
) {
399 temp8
= (u8
) linked_list
->data
.address16
.resource_source
.index
;
404 temp_pointer
= (char *) buffer
;
409 ACPI_STRCPY (temp_pointer
,
410 linked_list
->data
.address16
.resource_source
.string_ptr
);
413 * Buffer needs to be set to the length of the sting + one for the
416 buffer
+= (acpi_size
)(ACPI_STRLEN (linked_list
->data
.address16
.resource_source
.string_ptr
) + 1);
420 * Return the number of bytes consumed in this operation
422 actual_bytes
= ACPI_PTR_DIFF (buffer
, *output_buffer
);
423 *bytes_consumed
= actual_bytes
;
426 * Set the length field to the number of bytes consumed
427 * minus the header size (3 bytes)
430 ACPI_MOVE_SIZE_TO_16 (length_field
, &actual_bytes
);
431 return_ACPI_STATUS (AE_OK
);
435 /*******************************************************************************
437 * FUNCTION: acpi_rs_address32_resource
439 * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
441 * bytes_consumed - Pointer to where the number of bytes
442 * consumed the byte_stream_buffer is
444 * output_buffer - Pointer to the return data buffer
445 * structure_size - Pointer to where the number of bytes
446 * in the return data struct is returned
450 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
451 * structure pointed to by the output_buffer. Return the
452 * number of bytes consumed from the byte stream.
454 ******************************************************************************/
457 acpi_rs_address32_resource (
458 u8
*byte_stream_buffer
,
459 acpi_size
*bytes_consumed
,
461 acpi_size
*structure_size
)
464 struct acpi_resource
*output_struct
= (void *) *output_buffer
;
468 acpi_size struct_size
;
472 ACPI_FUNCTION_TRACE ("rs_address32_resource");
475 buffer
= byte_stream_buffer
;
476 struct_size
= ACPI_SIZEOF_RESOURCE (struct acpi_resource_address32
);
479 * Point past the Descriptor to get the number of bytes consumed
482 ACPI_MOVE_16_TO_16 (&temp16
, buffer
);
484 /* Validate minimum descriptor length */
487 return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH
);
490 *bytes_consumed
= temp16
+ 3;
491 output_struct
->id
= ACPI_RSTYPE_ADDRESS32
;
494 * Get the Resource Type (Byte3)
499 /* Values 0-2 and 0xC0-0xFF are valid */
501 if ((temp8
> 2) && (temp8
< 0xC0)) {
502 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE
);
505 output_struct
->data
.address32
.resource_type
= temp8
;
508 * Get the General Flags (Byte4)
514 * Producer / Consumer
516 output_struct
->data
.address32
.producer_consumer
= temp8
& 0x01;
521 output_struct
->data
.address32
.decode
= (temp8
>> 1) & 0x01;
526 output_struct
->data
.address32
.min_address_fixed
= (temp8
>> 2) & 0x01;
531 output_struct
->data
.address32
.max_address_fixed
= (temp8
>> 3) & 0x01;
534 * Get the Type Specific Flags (Byte5)
539 if (ACPI_MEMORY_RANGE
== output_struct
->data
.address32
.resource_type
) {
540 output_struct
->data
.address32
.attribute
.memory
.read_write_attribute
=
541 (u16
) (temp8
& 0x01);
543 output_struct
->data
.address32
.attribute
.memory
.cache_attribute
=
544 (u16
) ((temp8
>> 1) & 0x03);
547 if (ACPI_IO_RANGE
== output_struct
->data
.address32
.resource_type
) {
548 output_struct
->data
.address32
.attribute
.io
.range_attribute
=
549 (u16
) (temp8
& 0x03);
550 output_struct
->data
.address32
.attribute
.io
.translation_attribute
=
551 (u16
) ((temp8
>> 4) & 0x03);
554 /* BUS_NUMBER_RANGE == output_struct->Data.Address32.resource_type */
555 /* Nothing needs to be filled in */
560 * Get Granularity (Bytes 6-9)
563 ACPI_MOVE_32_TO_32 (&output_struct
->data
.address32
.granularity
, buffer
);
566 * Get min_address_range (Bytes 10-13)
569 ACPI_MOVE_32_TO_32 (&output_struct
->data
.address32
.min_address_range
, buffer
);
572 * Get max_address_range (Bytes 14-17)
575 ACPI_MOVE_32_TO_32 (&output_struct
->data
.address32
.max_address_range
, buffer
);
578 * Get address_translation_offset (Bytes 18-21)
581 ACPI_MOVE_32_TO_32 (&output_struct
->data
.address32
.address_translation_offset
, buffer
);
584 * Get address_length (Bytes 22-25)
587 ACPI_MOVE_32_TO_32 (&output_struct
->data
.address32
.address_length
, buffer
);
590 * Resource Source Index (if present)
595 * This will leave us pointing to the Resource Source Index
596 * If it is present, then save it off and calculate the
597 * pointer to where the null terminated string goes:
599 * Note: Some resource descriptors will have an additional null, so
600 * we add 1 to the length.
602 if (*bytes_consumed
> (26 + 1)) {
603 /* Dereference the Index */
606 output_struct
->data
.address32
.resource_source
.index
=
609 /* Point to the String */
613 /* Point the String pointer to the end of this structure */
615 output_struct
->data
.address32
.resource_source
.string_ptr
=
616 (char *)((u8
*)output_struct
+ struct_size
);
618 temp_ptr
= (u8
*) output_struct
->data
.address32
.resource_source
.string_ptr
;
620 /* Copy the string into the buffer */
623 while (0x00 != *buffer
) {
632 * Add the terminating null
635 output_struct
->data
.address32
.resource_source
.string_length
= index
+ 1;
638 * In order for the struct_size to fall on a 32-bit boundary,
639 * calculate the length of the string and expand the
640 * struct_size to the next 32-bit boundary.
642 temp8
= (u8
) (index
+ 1);
643 struct_size
+= ACPI_ROUND_UP_to_32_bITS (temp8
);
646 output_struct
->data
.address32
.resource_source
.index
= 0x00;
647 output_struct
->data
.address32
.resource_source
.string_length
= 0;
648 output_struct
->data
.address32
.resource_source
.string_ptr
= NULL
;
652 * Set the Length parameter
654 output_struct
->length
= (u32
) struct_size
;
657 * Return the final size of the structure
659 *structure_size
= struct_size
;
660 return_ACPI_STATUS (AE_OK
);
664 /*******************************************************************************
666 * FUNCTION: acpi_rs_address32_stream
668 * PARAMETERS: linked_list - Pointer to the resource linked list
669 * output_buffer - Pointer to the user's return buffer
670 * bytes_consumed - Pointer to where the number of bytes
671 * used in the output_buffer is returned
675 * DESCRIPTION: Take the linked list resource structure and fills in the
676 * the appropriate bytes in a byte stream
678 ******************************************************************************/
681 acpi_rs_address32_stream (
682 struct acpi_resource
*linked_list
,
684 acpi_size
*bytes_consumed
)
692 ACPI_FUNCTION_TRACE ("rs_address32_stream");
695 buffer
= *output_buffer
;
698 * The descriptor field is static
704 * Set a pointer to the Length field - to be filled in later
706 length_field
= ACPI_CAST_PTR (u16
, buffer
);
710 * Set the Resource Type (Memory, Io, bus_number)
712 temp8
= (u8
) (linked_list
->data
.address32
.resource_type
& 0x03);
718 * Set the general flags
720 temp8
= (u8
) (linked_list
->data
.address32
.producer_consumer
& 0x01);
721 temp8
|= (linked_list
->data
.address32
.decode
& 0x01) << 1;
722 temp8
|= (linked_list
->data
.address32
.min_address_fixed
& 0x01) << 2;
723 temp8
|= (linked_list
->data
.address32
.max_address_fixed
& 0x01) << 3;
729 * Set the type specific flags
733 if (ACPI_MEMORY_RANGE
== linked_list
->data
.address32
.resource_type
) {
735 (linked_list
->data
.address32
.attribute
.memory
.read_write_attribute
&
739 (linked_list
->data
.address32
.attribute
.memory
.cache_attribute
&
742 else if (ACPI_IO_RANGE
== linked_list
->data
.address32
.resource_type
) {
744 (linked_list
->data
.address32
.attribute
.io
.range_attribute
&
747 (linked_list
->data
.address32
.attribute
.io
.translation_attribute
&
755 * Set the address space granularity
757 ACPI_MOVE_32_TO_32 (buffer
, &linked_list
->data
.address32
.granularity
);
761 * Set the address range minimum
763 ACPI_MOVE_32_TO_32 (buffer
, &linked_list
->data
.address32
.min_address_range
);
767 * Set the address range maximum
769 ACPI_MOVE_32_TO_32 (buffer
, &linked_list
->data
.address32
.max_address_range
);
773 * Set the address translation offset
775 ACPI_MOVE_32_TO_32 (buffer
, &linked_list
->data
.address32
.address_translation_offset
);
779 * Set the address length
781 ACPI_MOVE_32_TO_32 (buffer
, &linked_list
->data
.address32
.address_length
);
785 * Resource Source Index and Resource Source are optional
787 if (0 != linked_list
->data
.address32
.resource_source
.string_length
) {
788 temp8
= (u8
) linked_list
->data
.address32
.resource_source
.index
;
793 temp_pointer
= (char *) buffer
;
798 ACPI_STRCPY (temp_pointer
,
799 linked_list
->data
.address32
.resource_source
.string_ptr
);
802 * Buffer needs to be set to the length of the sting + one for the
805 buffer
+= (acpi_size
)(ACPI_STRLEN (linked_list
->data
.address32
.resource_source
.string_ptr
) + 1);
809 * Return the number of bytes consumed in this operation
811 *bytes_consumed
= ACPI_PTR_DIFF (buffer
, *output_buffer
);
814 * Set the length field to the number of bytes consumed
815 * minus the header size (3 bytes)
817 *length_field
= (u16
) (*bytes_consumed
- 3);
818 return_ACPI_STATUS (AE_OK
);
822 /*******************************************************************************
824 * FUNCTION: acpi_rs_address64_resource
826 * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte
828 * bytes_consumed - Pointer to where the number of bytes
829 * consumed the byte_stream_buffer is
831 * output_buffer - Pointer to the return data buffer
832 * structure_size - Pointer to where the number of bytes
833 * in the return data struct is returned
837 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
838 * structure pointed to by the output_buffer. Return the
839 * number of bytes consumed from the byte stream.
841 ******************************************************************************/
844 acpi_rs_address64_resource (
845 u8
*byte_stream_buffer
,
846 acpi_size
*bytes_consumed
,
848 acpi_size
*structure_size
)
851 struct acpi_resource
*output_struct
= (void *) *output_buffer
;
856 acpi_size struct_size
;
860 ACPI_FUNCTION_TRACE ("rs_address64_resource");
863 buffer
= byte_stream_buffer
;
864 struct_size
= ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64
);
865 resource_type
= *buffer
;
868 * Point past the Descriptor to get the number of bytes consumed
871 ACPI_MOVE_16_TO_16 (&temp16
, buffer
);
873 /* Validate minimum descriptor length */
876 return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH
);
879 *bytes_consumed
= temp16
+ 3;
880 output_struct
->id
= ACPI_RSTYPE_ADDRESS64
;
883 * Get the Resource Type (Byte3)
888 /* Values 0-2 and 0xC0-0xFF are valid */
890 if ((temp8
> 2) && (temp8
< 0xC0)) {
891 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE
);
894 output_struct
->data
.address64
.resource_type
= temp8
;
897 * Get the General Flags (Byte4)
903 * Producer / Consumer
905 output_struct
->data
.address64
.producer_consumer
= temp8
& 0x01;
910 output_struct
->data
.address64
.decode
= (temp8
>> 1) & 0x01;
915 output_struct
->data
.address64
.min_address_fixed
= (temp8
>> 2) & 0x01;
920 output_struct
->data
.address64
.max_address_fixed
= (temp8
>> 3) & 0x01;
923 * Get the Type Specific Flags (Byte5)
928 if (ACPI_MEMORY_RANGE
== output_struct
->data
.address64
.resource_type
) {
929 output_struct
->data
.address64
.attribute
.memory
.read_write_attribute
=
930 (u16
) (temp8
& 0x01);
932 output_struct
->data
.address64
.attribute
.memory
.cache_attribute
=
933 (u16
) ((temp8
>> 1) & 0x03);
936 if (ACPI_IO_RANGE
== output_struct
->data
.address64
.resource_type
) {
937 output_struct
->data
.address64
.attribute
.io
.range_attribute
=
938 (u16
) (temp8
& 0x03);
939 output_struct
->data
.address64
.attribute
.io
.translation_attribute
=
940 (u16
) ((temp8
>> 4) & 0x03);
943 /* BUS_NUMBER_RANGE == output_struct->Data.Address64.resource_type */
944 /* Nothing needs to be filled in */
948 if (resource_type
== ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE
) {
949 /* Move past revision_id and Reserved byte */
955 * Get Granularity (Bytes 6-13) or (Bytes 8-15)
958 ACPI_MOVE_64_TO_64 (&output_struct
->data
.address64
.granularity
, buffer
);
961 * Get min_address_range (Bytes 14-21) or (Bytes 16-23)
964 ACPI_MOVE_64_TO_64 (&output_struct
->data
.address64
.min_address_range
, buffer
);
967 * Get max_address_range (Bytes 22-29) or (Bytes 24-31)
970 ACPI_MOVE_64_TO_64 (&output_struct
->data
.address64
.max_address_range
, buffer
);
973 * Get address_translation_offset (Bytes 30-37) or (Bytes 32-39)
976 ACPI_MOVE_64_TO_64 (&output_struct
->data
.address64
.address_translation_offset
, buffer
);
979 * Get address_length (Bytes 38-45) or (Bytes 40-47)
982 ACPI_MOVE_64_TO_64 (&output_struct
->data
.address64
.address_length
, buffer
);
984 output_struct
->data
.address64
.resource_source
.index
= 0x00;
985 output_struct
->data
.address64
.resource_source
.string_length
= 0;
986 output_struct
->data
.address64
.resource_source
.string_ptr
= NULL
;
988 if (resource_type
== ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE
) {
989 /* Get type_specific_attribute (Bytes 48-55) */
992 ACPI_MOVE_64_TO_64 (&output_struct
->data
.address64
.type_specific_attributes
, buffer
);
995 output_struct
->data
.address64
.type_specific_attributes
= 0;
998 * Resource Source Index (if present)
1003 * This will leave us pointing to the Resource Source Index
1004 * If it is present, then save it off and calculate the
1005 * pointer to where the null terminated string goes:
1006 * Each Interrupt takes 32-bits + the 5 bytes of the
1007 * stream that are default.
1009 * Note: Some resource descriptors will have an additional null, so
1010 * we add 1 to the length.
1012 if (*bytes_consumed
> (46 + 1)) {
1013 /* Dereference the Index */
1016 output_struct
->data
.address64
.resource_source
.index
=
1019 /* Point to the String */
1023 /* Point the String pointer to the end of this structure */
1025 output_struct
->data
.address64
.resource_source
.string_ptr
=
1026 (char *)((u8
*)output_struct
+ struct_size
);
1028 temp_ptr
= (u8
*) output_struct
->data
.address64
.resource_source
.string_ptr
;
1030 /* Copy the string into the buffer */
1033 while (0x00 != *buffer
) {
1034 *temp_ptr
= *buffer
;
1042 * Add the terminating null
1045 output_struct
->data
.address64
.resource_source
.string_length
= index
+ 1;
1048 * In order for the struct_size to fall on a 32-bit boundary,
1049 * calculate the length of the string and expand the
1050 * struct_size to the next 32-bit boundary.
1052 temp8
= (u8
) (index
+ 1);
1053 struct_size
+= ACPI_ROUND_UP_to_32_bITS (temp8
);
1058 * Set the Length parameter
1060 output_struct
->length
= (u32
) struct_size
;
1063 * Return the final size of the structure
1065 *structure_size
= struct_size
;
1066 return_ACPI_STATUS (AE_OK
);
1070 /*******************************************************************************
1072 * FUNCTION: acpi_rs_address64_stream
1074 * PARAMETERS: linked_list - Pointer to the resource linked list
1075 * output_buffer - Pointer to the user's return buffer
1076 * bytes_consumed - Pointer to where the number of bytes
1077 * used in the output_buffer is returned
1081 * DESCRIPTION: Take the linked list resource structure and fills in the
1082 * the appropriate bytes in a byte stream
1084 ******************************************************************************/
1087 acpi_rs_address64_stream (
1088 struct acpi_resource
*linked_list
,
1090 acpi_size
*bytes_consumed
)
1098 ACPI_FUNCTION_TRACE ("rs_address64_stream");
1101 buffer
= *output_buffer
;
1104 * The descriptor field is static
1110 * Set a pointer to the Length field - to be filled in later
1112 length_field
= ACPI_CAST_PTR (u16
, buffer
);
1116 * Set the Resource Type (Memory, Io, bus_number)
1118 temp8
= (u8
) (linked_list
->data
.address64
.resource_type
& 0x03);
1124 * Set the general flags
1126 temp8
= (u8
) (linked_list
->data
.address64
.producer_consumer
& 0x01);
1127 temp8
|= (linked_list
->data
.address64
.decode
& 0x01) << 1;
1128 temp8
|= (linked_list
->data
.address64
.min_address_fixed
& 0x01) << 2;
1129 temp8
|= (linked_list
->data
.address64
.max_address_fixed
& 0x01) << 3;
1135 * Set the type specific flags
1139 if (ACPI_MEMORY_RANGE
== linked_list
->data
.address64
.resource_type
) {
1141 (linked_list
->data
.address64
.attribute
.memory
.read_write_attribute
&
1145 (linked_list
->data
.address64
.attribute
.memory
.cache_attribute
&
1148 else if (ACPI_IO_RANGE
== linked_list
->data
.address64
.resource_type
) {
1150 (linked_list
->data
.address64
.attribute
.io
.range_attribute
&
1153 (linked_list
->data
.address64
.attribute
.io
.range_attribute
&
1161 * Set the address space granularity
1163 ACPI_MOVE_64_TO_64 (buffer
, &linked_list
->data
.address64
.granularity
);
1167 * Set the address range minimum
1169 ACPI_MOVE_64_TO_64 (buffer
, &linked_list
->data
.address64
.min_address_range
);
1173 * Set the address range maximum
1175 ACPI_MOVE_64_TO_64 (buffer
, &linked_list
->data
.address64
.max_address_range
);
1179 * Set the address translation offset
1181 ACPI_MOVE_64_TO_64 (buffer
, &linked_list
->data
.address64
.address_translation_offset
);
1185 * Set the address length
1187 ACPI_MOVE_64_TO_64 (buffer
, &linked_list
->data
.address64
.address_length
);
1191 * Resource Source Index and Resource Source are optional
1193 if (0 != linked_list
->data
.address64
.resource_source
.string_length
) {
1194 temp8
= (u8
) linked_list
->data
.address64
.resource_source
.index
;
1199 temp_pointer
= (char *) buffer
;
1204 ACPI_STRCPY (temp_pointer
, linked_list
->data
.address64
.resource_source
.string_ptr
);
1207 * Buffer needs to be set to the length of the sting + one for the
1210 buffer
+= (acpi_size
)(ACPI_STRLEN (linked_list
->data
.address64
.resource_source
.string_ptr
) + 1);
1214 * Return the number of bytes consumed in this operation
1216 *bytes_consumed
= ACPI_PTR_DIFF (buffer
, *output_buffer
);
1219 * Set the length field to the number of bytes consumed
1220 * minus the header size (3 bytes)
1222 *length_field
= (u16
) (*bytes_consumed
- 3);
1223 return_ACPI_STATUS (AE_OK
);