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