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 /* Local prototypes */
52 acpi_rs_decode_general_flags(union acpi_resource_data
*resource
, u8 flags
);
54 static u8
acpi_rs_encode_general_flags(union acpi_resource_data
*resource
);
57 acpi_rs_decode_specific_flags(union acpi_resource_data
*resource
, u8 flags
);
59 static u8
acpi_rs_encode_specific_flags(union acpi_resource_data
*resource
);
62 acpi_rs_set_address_common(union aml_resource
*aml
,
63 struct acpi_resource
*resource
);
66 acpi_rs_get_address_common(struct acpi_resource
*resource
,
67 union aml_resource
*aml
);
69 /*******************************************************************************
71 * FUNCTION: acpi_rs_decode_general_flags
73 * PARAMETERS: Resource - Address resource data struct
74 * Flags - Raw AML flag byte
76 * RETURN: Decoded flag bits in resource struct
78 * DESCRIPTION: Decode a general flag byte to an address resource struct
80 ******************************************************************************/
83 acpi_rs_decode_general_flags(union acpi_resource_data
*resource
, u8 flags
)
85 ACPI_FUNCTION_ENTRY();
87 /* Producer / Consumer - flag bit[0] */
89 resource
->address
.producer_consumer
= (u32
) (flags
& 0x01);
91 /* Decode (_DEC) - flag bit[1] */
93 resource
->address
.decode
= (u32
) ((flags
>> 1) & 0x01);
95 /* Min Address Fixed (_MIF) - flag bit[2] */
97 resource
->address
.min_address_fixed
= (u32
) ((flags
>> 2) & 0x01);
99 /* Max Address Fixed (_MAF) - flag bit[3] */
101 resource
->address
.max_address_fixed
= (u32
) ((flags
>> 3) & 0x01);
104 /*******************************************************************************
106 * FUNCTION: acpi_rs_encode_general_flags
108 * PARAMETERS: Resource - Address resource data struct
110 * RETURN: Encoded general flag byte
112 * DESCRIPTION: Construct a general flag byte from an address resource struct
114 ******************************************************************************/
116 static u8
acpi_rs_encode_general_flags(union acpi_resource_data
*resource
)
118 ACPI_FUNCTION_ENTRY();
122 /* Producer / Consumer - flag bit[0] */
123 ((resource
->address
.producer_consumer
& 0x01) |
124 /* Decode (_DEC) - flag bit[1] */
125 ((resource
->address
.decode
& 0x01) << 1) |
126 /* Min Address Fixed (_MIF) - flag bit[2] */
127 ((resource
->address
.min_address_fixed
& 0x01) << 2) |
128 /* Max Address Fixed (_MAF) - flag bit[3] */
129 ((resource
->address
.max_address_fixed
& 0x01) << 3))
133 /*******************************************************************************
135 * FUNCTION: acpi_rs_decode_specific_flags
137 * PARAMETERS: Resource - Address resource data struct
138 * Flags - Raw AML flag byte
140 * RETURN: Decoded flag bits in attribute struct
142 * DESCRIPTION: Decode a type-specific flag byte to an attribute struct.
143 * Type-specific flags are only defined for the Memory and IO
146 ******************************************************************************/
149 acpi_rs_decode_specific_flags(union acpi_resource_data
*resource
, u8 flags
)
151 ACPI_FUNCTION_ENTRY();
153 if (resource
->address
.resource_type
== ACPI_MEMORY_RANGE
) {
154 /* Write Status (_RW) - flag bit[0] */
156 resource
->address
.attribute
.memory
.read_write_attribute
=
157 (u16
) (flags
& 0x01);
159 /* Memory Attributes (_MEM) - flag bits[2:1] */
161 resource
->address
.attribute
.memory
.cache_attribute
=
162 (u16
) ((flags
>> 1) & 0x03);
163 } else if (resource
->address
.resource_type
== ACPI_IO_RANGE
) {
164 /* Ranges (_RNG) - flag bits[1:0] */
166 resource
->address
.attribute
.io
.range_attribute
=
167 (u16
) (flags
& 0x03);
169 /* Translations (_TTP and _TRS) - flag bits[5:4] */
171 resource
->address
.attribute
.io
.translation_attribute
=
172 (u16
) ((flags
>> 4) & 0x03);
176 /*******************************************************************************
178 * FUNCTION: acpi_rs_encode_specific_flags
180 * PARAMETERS: Resource - Address resource data struct
182 * RETURN: Encoded type-specific flag byte
184 * DESCRIPTION: Construct a type-specific flag byte from an attribute struct.
185 * Type-specific flags are only defined for the Memory and IO
188 ******************************************************************************/
190 static u8
acpi_rs_encode_specific_flags(union acpi_resource_data
*resource
)
192 ACPI_FUNCTION_ENTRY();
194 if (resource
->address
.resource_type
== ACPI_MEMORY_RANGE
) {
197 /* Write Status (_RW) - flag bit[0] */
198 ((resource
->address
.attribute
.memory
.
199 read_write_attribute
& 0x01) |
200 /* Memory Attributes (_MEM) - flag bits[2:1] */
201 ((resource
->address
.attribute
.memory
.
202 cache_attribute
& 0x03) << 1)));
203 } else if (resource
->address
.resource_type
== ACPI_IO_RANGE
) {
206 /* Ranges (_RNG) - flag bits[1:0] */
207 ((resource
->address
.attribute
.io
.
208 range_attribute
& 0x03) |
209 /* Translations (_TTP and _TRS) - flag bits[5:4] */
210 ((resource
->address
.attribute
.io
.
211 translation_attribute
& 0x03) << 4)));
217 /*******************************************************************************
219 * FUNCTION: acpi_rs_set_address_common
221 * PARAMETERS: Aml - Pointer to the AML resource descriptor
222 * Resource - Pointer to the internal resource struct
226 * DESCRIPTION: Convert common flag fields from a resource descriptor to an
229 ******************************************************************************/
232 acpi_rs_set_address_common(union aml_resource
*aml
,
233 struct acpi_resource
*resource
)
235 ACPI_FUNCTION_ENTRY();
237 /* Set the Resource Type (Memory, Io, bus_number, etc.) */
239 aml
->address
.resource_type
= (u8
) resource
->data
.address
.resource_type
;
241 /* Set the general flags */
243 aml
->address
.flags
= acpi_rs_encode_general_flags(&resource
->data
);
245 /* Set the type-specific flags */
247 aml
->address
.specific_flags
=
248 acpi_rs_encode_specific_flags(&resource
->data
);
251 /*******************************************************************************
253 * FUNCTION: acpi_rs_get_address_common
255 * PARAMETERS: Resource - Pointer to the internal resource struct
256 * Aml - Pointer to the AML resource descriptor
258 * RETURN: TRUE if the resource_type field is OK, FALSE otherwise
260 * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor
261 * to an internal resource descriptor
263 ******************************************************************************/
266 acpi_rs_get_address_common(struct acpi_resource
*resource
,
267 union aml_resource
*aml
)
269 ACPI_FUNCTION_ENTRY();
271 /* Validate resource type */
273 if ((aml
->address
.resource_type
> 2)
274 && (aml
->address
.resource_type
< 0xC0)) {
278 /* Get the Resource Type (Memory, Io, bus_number, etc.) */
280 resource
->data
.address
.resource_type
= aml
->address
.resource_type
;
282 /* Get the General Flags */
284 acpi_rs_decode_general_flags(&resource
->data
, aml
->address
.flags
);
286 /* Get the Type-Specific Flags */
288 acpi_rs_decode_specific_flags(&resource
->data
,
289 aml
->address
.specific_flags
);
293 /*******************************************************************************
295 * FUNCTION: acpi_rs_get_address16
297 * PARAMETERS: Aml - Pointer to the AML resource descriptor
298 * aml_resource_length - Length of the resource from the AML header
299 * Resource - Where the internal resource is returned
303 * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding
304 * internal resource descriptor, simplifying bitflags and handling
305 * alignment and endian issues if necessary.
307 ******************************************************************************/
310 acpi_rs_get_address16(union aml_resource
* aml
,
311 u16 aml_resource_length
, struct acpi_resource
* resource
)
313 ACPI_FUNCTION_TRACE("rs_get_address16");
315 /* Get the Resource Type, general flags, and type-specific flags */
317 if (!acpi_rs_get_address_common(resource
, aml
)) {
318 return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE
);
322 * Get the following contiguous fields from the AML descriptor:
323 * Address Granularity
324 * Address Range Minimum
325 * Address Range Maximum
326 * Address Translation Offset
329 acpi_rs_move_data(&resource
->data
.address16
.granularity
,
330 &aml
->address16
.granularity
, 5,
331 ACPI_MOVE_TYPE_16_TO_32
);
333 /* Get the optional resource_source (index and string) */
336 ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16
) +
337 acpi_rs_get_resource_source(aml_resource_length
,
338 sizeof(struct aml_resource_address16
),
339 &resource
->data
.address16
.
340 resource_source
, aml
, NULL
);
342 /* Complete the resource header */
344 resource
->type
= ACPI_RESOURCE_TYPE_ADDRESS16
;
345 return_ACPI_STATUS(AE_OK
);
348 /*******************************************************************************
350 * FUNCTION: acpi_rs_set_address16
352 * PARAMETERS: Resource - Pointer to the resource descriptor
353 * Aml - Where the AML descriptor is returned
357 * DESCRIPTION: Convert an internal resource descriptor to the corresponding
358 * external AML resource descriptor.
360 ******************************************************************************/
363 acpi_rs_set_address16(struct acpi_resource
*resource
, union aml_resource
*aml
)
365 acpi_size descriptor_length
;
367 ACPI_FUNCTION_TRACE("rs_set_address16");
369 /* Set the Resource Type, General Flags, and Type-Specific Flags */
371 acpi_rs_set_address_common(aml
, resource
);
374 * Set the following contiguous fields in the AML descriptor:
375 * Address Granularity
376 * Address Range Minimum
377 * Address Range Maximum
378 * Address Translation Offset
381 acpi_rs_move_data(&aml
->address16
.granularity
,
382 &resource
->data
.address16
.granularity
, 5,
383 ACPI_MOVE_TYPE_32_TO_16
);
385 /* Resource Source Index and Resource Source are optional */
387 descriptor_length
= acpi_rs_set_resource_source(aml
,
389 aml_resource_address16
),
394 /* Complete the AML descriptor header */
396 acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS16
,
397 descriptor_length
, aml
);
398 return_ACPI_STATUS(AE_OK
);
401 /*******************************************************************************
403 * FUNCTION: acpi_rs_get_address32
405 * PARAMETERS: Aml - Pointer to the AML resource descriptor
406 * aml_resource_length - Length of the resource from the AML header
407 * Resource - Where the internal resource is returned
411 * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding
412 * internal resource descriptor, simplifying bitflags and handling
413 * alignment and endian issues if necessary.
415 ******************************************************************************/
418 acpi_rs_get_address32(union aml_resource
*aml
,
419 u16 aml_resource_length
, struct acpi_resource
*resource
)
422 ACPI_FUNCTION_TRACE("rs_get_address32");
424 /* Get the Resource Type, general flags, and type-specific flags */
426 if (!acpi_rs_get_address_common(resource
, (void *)aml
)) {
427 return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE
);
431 * Get the following contiguous fields from the AML descriptor:
432 * Address Granularity
433 * Address Range Minimum
434 * Address Range Maximum
435 * Address Translation Offset
438 acpi_rs_move_data(&resource
->data
.address32
.granularity
,
439 &aml
->address32
.granularity
, 5,
440 ACPI_MOVE_TYPE_32_TO_32
);
442 /* Get the optional resource_source (index and string) */
445 ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32
) +
446 acpi_rs_get_resource_source(aml_resource_length
,
447 sizeof(struct aml_resource_address32
),
448 &resource
->data
.address32
.
449 resource_source
, aml
, NULL
);
451 /* Complete the resource header */
453 resource
->type
= ACPI_RESOURCE_TYPE_ADDRESS32
;
454 return_ACPI_STATUS(AE_OK
);
457 /*******************************************************************************
459 * FUNCTION: acpi_rs_set_address32
461 * PARAMETERS: Resource - Pointer to the resource descriptor
462 * Aml - Where the AML descriptor is returned
466 * DESCRIPTION: Convert an internal resource descriptor to the corresponding
467 * external AML resource descriptor.
469 ******************************************************************************/
472 acpi_rs_set_address32(struct acpi_resource
*resource
, union aml_resource
*aml
)
474 acpi_size descriptor_length
;
476 ACPI_FUNCTION_TRACE("rs_set_address32");
478 /* Set the Resource Type, General Flags, and Type-Specific Flags */
480 acpi_rs_set_address_common(aml
, resource
);
483 * Set the following contiguous fields in the AML descriptor:
484 * Address Granularity
485 * Address Range Minimum
486 * Address Range Maximum
487 * Address Translation Offset
490 acpi_rs_move_data(&aml
->address32
.granularity
,
491 &resource
->data
.address32
.granularity
, 5,
492 ACPI_MOVE_TYPE_32_TO_32
);
494 /* Resource Source Index and Resource Source are optional */
496 descriptor_length
= acpi_rs_set_resource_source(aml
,
498 aml_resource_address32
),
503 /* Complete the AML descriptor header */
505 acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS32
,
506 descriptor_length
, aml
);
507 return_ACPI_STATUS(AE_OK
);
510 /*******************************************************************************
512 * FUNCTION: acpi_rs_get_address64
514 * PARAMETERS: Aml - Pointer to the AML resource descriptor
515 * aml_resource_length - Length of the resource from the AML header
516 * Resource - Where the internal resource is returned
520 * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding
521 * internal resource descriptor, simplifying bitflags and handling
522 * alignment and endian issues if necessary.
524 ******************************************************************************/
527 acpi_rs_get_address64(union aml_resource
*aml
,
528 u16 aml_resource_length
, struct acpi_resource
*resource
)
530 ACPI_FUNCTION_TRACE("rs_get_address64");
532 /* Get the Resource Type, general Flags, and type-specific Flags */
534 if (!acpi_rs_get_address_common(resource
, aml
)) {
535 return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE
);
539 * Get the following contiguous fields from the AML descriptor:
540 * Address Granularity
541 * Address Range Minimum
542 * Address Range Maximum
543 * Address Translation Offset
546 acpi_rs_move_data(&resource
->data
.address64
.granularity
,
547 &aml
->address64
.granularity
, 5,
548 ACPI_MOVE_TYPE_64_TO_64
);
550 /* Get the optional resource_source (index and string) */
553 ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64
) +
554 acpi_rs_get_resource_source(aml_resource_length
,
555 sizeof(struct aml_resource_address64
),
556 &resource
->data
.address64
.
557 resource_source
, aml
, NULL
);
559 /* Complete the resource header */
561 resource
->type
= ACPI_RESOURCE_TYPE_ADDRESS64
;
562 return_ACPI_STATUS(AE_OK
);
565 /*******************************************************************************
567 * FUNCTION: acpi_rs_set_address64
569 * PARAMETERS: Resource - Pointer to the resource descriptor
570 * Aml - Where the AML descriptor is returned
574 * DESCRIPTION: Convert an internal resource descriptor to the corresponding
575 * external AML resource descriptor.
577 ******************************************************************************/
580 acpi_rs_set_address64(struct acpi_resource
*resource
, union aml_resource
*aml
)
582 acpi_size descriptor_length
;
584 ACPI_FUNCTION_TRACE("rs_set_address64");
586 /* Set the Resource Type, General Flags, and Type-Specific Flags */
588 acpi_rs_set_address_common(aml
, resource
);
591 * Set the following contiguous fields in the AML descriptor:
592 * Address Granularity
593 * Address Range Minimum
594 * Address Range Maximum
595 * Address Translation Offset
598 acpi_rs_move_data(&aml
->address64
.granularity
,
599 &resource
->data
.address64
.granularity
, 5,
600 ACPI_MOVE_TYPE_64_TO_64
);
602 /* Resource Source Index and Resource Source are optional */
604 descriptor_length
= acpi_rs_set_resource_source(aml
,
606 aml_resource_address64
),
611 /* Complete the AML descriptor header */
613 acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS64
,
614 descriptor_length
, aml
);
615 return_ACPI_STATUS(AE_OK
);
618 /*******************************************************************************
620 * FUNCTION: acpi_rs_get_ext_address64
622 * PARAMETERS: Aml - Pointer to the AML resource descriptor
623 * aml_resource_length - Length of the resource from the AML header
624 * Resource - Where the internal resource is returned
628 * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding
629 * internal resource descriptor, simplifying bitflags and handling
630 * alignment and endian issues if necessary.
632 ******************************************************************************/
635 acpi_rs_get_ext_address64(union aml_resource
*aml
,
636 u16 aml_resource_length
,
637 struct acpi_resource
*resource
)
640 ACPI_FUNCTION_TRACE("rs_get_ext_address64");
642 /* Get the Resource Type, general flags, and type-specific flags */
644 if (!acpi_rs_get_address_common(resource
, aml
)) {
645 return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE
);
649 * Get and validate the Revision ID
650 * Note: Only one revision ID is currently supported
652 resource
->data
.ext_address64
.revision_iD
=
653 aml
->ext_address64
.revision_iD
;
654 if (aml
->ext_address64
.revision_iD
!=
655 AML_RESOURCE_EXTENDED_ADDRESS_REVISION
) {
656 return_ACPI_STATUS(AE_SUPPORT
);
660 * Get the following contiguous fields from the AML descriptor:
661 * Address Granularity
662 * Address Range Minimum
663 * Address Range Maximum
664 * Address Translation Offset
666 * Type-Specific Attribute
668 acpi_rs_move_data(&resource
->data
.ext_address64
.granularity
,
669 &aml
->ext_address64
.granularity
, 6,
670 ACPI_MOVE_TYPE_64_TO_64
);
672 /* Complete the resource header */
674 resource
->type
= ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
;
676 ACPI_SIZEOF_RESOURCE(struct acpi_resource_extended_address64
);
677 return_ACPI_STATUS(AE_OK
);
680 /*******************************************************************************
682 * FUNCTION: acpi_rs_set_ext_address64
684 * PARAMETERS: Resource - Pointer to the resource descriptor
685 * Aml - Where the AML descriptor is returned
689 * DESCRIPTION: Convert an internal resource descriptor to the corresponding
690 * external AML resource descriptor.
692 ******************************************************************************/
695 acpi_rs_set_ext_address64(struct acpi_resource
*resource
,
696 union aml_resource
*aml
)
698 ACPI_FUNCTION_TRACE("rs_set_ext_address64");
700 /* Set the Resource Type, General Flags, and Type-Specific Flags */
702 acpi_rs_set_address_common(aml
, resource
);
704 /* Only one Revision ID is currently supported */
706 aml
->ext_address64
.revision_iD
= AML_RESOURCE_EXTENDED_ADDRESS_REVISION
;
707 aml
->ext_address64
.reserved
= 0;
710 * Set the following contiguous fields in the AML descriptor:
711 * Address Granularity
712 * Address Range Minimum
713 * Address Range Maximum
714 * Address Translation Offset
716 * Type-Specific Attribute
718 acpi_rs_move_data(&aml
->ext_address64
.granularity
,
719 &resource
->data
.address64
.granularity
, 6,
720 ACPI_MOVE_TYPE_64_TO_64
);
722 /* Complete the AML descriptor header */
724 acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64
,
726 aml_resource_extended_address64
),
728 return_ACPI_STATUS(AE_OK
);