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