195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
295b482a8SLen Brown /*******************************************************************************
395b482a8SLen Brown *
495b482a8SLen Brown * Module Name: rsaddr - Address resource descriptors (16/32/64)
595b482a8SLen Brown *
695b482a8SLen Brown ******************************************************************************/
795b482a8SLen Brown
895b482a8SLen Brown #include <acpi/acpi.h>
9e2f7a777SLen Brown #include "accommon.h"
10e2f7a777SLen Brown #include "acresrc.h"
1195b482a8SLen Brown
1295b482a8SLen Brown #define _COMPONENT ACPI_RESOURCES
1395b482a8SLen Brown ACPI_MODULE_NAME("rsaddr")
1495b482a8SLen Brown
1595b482a8SLen Brown /*******************************************************************************
1695b482a8SLen Brown *
1795b482a8SLen Brown * acpi_rs_convert_address16 - All WORD (16-bit) address resources
1895b482a8SLen Brown *
1995b482a8SLen Brown ******************************************************************************/
2095b482a8SLen Brown struct acpi_rsconvert_info acpi_rs_convert_address16[5] = {
2195b482a8SLen Brown {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS16,
2295b482a8SLen Brown ACPI_RS_SIZE(struct acpi_resource_address16),
2395b482a8SLen Brown ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address16)},
2495b482a8SLen Brown
2595b482a8SLen Brown {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS16,
2695b482a8SLen Brown sizeof(struct aml_resource_address16),
2795b482a8SLen Brown 0},
2895b482a8SLen Brown
2995b482a8SLen Brown /* Resource Type, General Flags, and Type-Specific Flags */
3095b482a8SLen Brown
3195b482a8SLen Brown {ACPI_RSC_ADDRESS, 0, 0, 0},
3295b482a8SLen Brown
3395b482a8SLen Brown /*
3495b482a8SLen Brown * These fields are contiguous in both the source and destination:
3595b482a8SLen Brown * Address Granularity
3695b482a8SLen Brown * Address Range Minimum
3795b482a8SLen Brown * Address Range Maximum
3895b482a8SLen Brown * Address Translation Offset
3995b482a8SLen Brown * Address Length
4095b482a8SLen Brown */
41a45de93eSLv Zheng {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.address16.address.granularity),
4295b482a8SLen Brown AML_OFFSET(address16.granularity),
4395b482a8SLen Brown 5},
4495b482a8SLen Brown
4595b482a8SLen Brown /* Optional resource_source (Index and String) */
4695b482a8SLen Brown
4795b482a8SLen Brown {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address16.resource_source),
4895b482a8SLen Brown 0,
4995b482a8SLen Brown sizeof(struct aml_resource_address16)}
5095b482a8SLen Brown };
5195b482a8SLen Brown
5295b482a8SLen Brown /*******************************************************************************
5395b482a8SLen Brown *
5495b482a8SLen Brown * acpi_rs_convert_address32 - All DWORD (32-bit) address resources
5595b482a8SLen Brown *
5695b482a8SLen Brown ******************************************************************************/
5795b482a8SLen Brown
5895b482a8SLen Brown struct acpi_rsconvert_info acpi_rs_convert_address32[5] = {
5995b482a8SLen Brown {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS32,
6095b482a8SLen Brown ACPI_RS_SIZE(struct acpi_resource_address32),
6195b482a8SLen Brown ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address32)},
6295b482a8SLen Brown
6395b482a8SLen Brown {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS32,
6495b482a8SLen Brown sizeof(struct aml_resource_address32),
6595b482a8SLen Brown 0},
6695b482a8SLen Brown
6795b482a8SLen Brown /* Resource Type, General Flags, and Type-Specific Flags */
6895b482a8SLen Brown
6995b482a8SLen Brown {ACPI_RSC_ADDRESS, 0, 0, 0},
7095b482a8SLen Brown
7195b482a8SLen Brown /*
7295b482a8SLen Brown * These fields are contiguous in both the source and destination:
7395b482a8SLen Brown * Address Granularity
7495b482a8SLen Brown * Address Range Minimum
7595b482a8SLen Brown * Address Range Maximum
7695b482a8SLen Brown * Address Translation Offset
7795b482a8SLen Brown * Address Length
7895b482a8SLen Brown */
79a45de93eSLv Zheng {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.address32.address.granularity),
8095b482a8SLen Brown AML_OFFSET(address32.granularity),
8195b482a8SLen Brown 5},
8295b482a8SLen Brown
8395b482a8SLen Brown /* Optional resource_source (Index and String) */
8495b482a8SLen Brown
8595b482a8SLen Brown {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address32.resource_source),
8695b482a8SLen Brown 0,
8795b482a8SLen Brown sizeof(struct aml_resource_address32)}
8895b482a8SLen Brown };
8995b482a8SLen Brown
9095b482a8SLen Brown /*******************************************************************************
9195b482a8SLen Brown *
9295b482a8SLen Brown * acpi_rs_convert_address64 - All QWORD (64-bit) address resources
9395b482a8SLen Brown *
9495b482a8SLen Brown ******************************************************************************/
9595b482a8SLen Brown
9695b482a8SLen Brown struct acpi_rsconvert_info acpi_rs_convert_address64[5] = {
9795b482a8SLen Brown {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS64,
9895b482a8SLen Brown ACPI_RS_SIZE(struct acpi_resource_address64),
9995b482a8SLen Brown ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address64)},
10095b482a8SLen Brown
10195b482a8SLen Brown {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS64,
10295b482a8SLen Brown sizeof(struct aml_resource_address64),
10395b482a8SLen Brown 0},
10495b482a8SLen Brown
10595b482a8SLen Brown /* Resource Type, General Flags, and Type-Specific Flags */
10695b482a8SLen Brown
10795b482a8SLen Brown {ACPI_RSC_ADDRESS, 0, 0, 0},
10895b482a8SLen Brown
10995b482a8SLen Brown /*
11095b482a8SLen Brown * These fields are contiguous in both the source and destination:
11195b482a8SLen Brown * Address Granularity
11295b482a8SLen Brown * Address Range Minimum
11395b482a8SLen Brown * Address Range Maximum
11495b482a8SLen Brown * Address Translation Offset
11595b482a8SLen Brown * Address Length
11695b482a8SLen Brown */
117a45de93eSLv Zheng {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.address64.address.granularity),
11895b482a8SLen Brown AML_OFFSET(address64.granularity),
11995b482a8SLen Brown 5},
12095b482a8SLen Brown
12195b482a8SLen Brown /* Optional resource_source (Index and String) */
12295b482a8SLen Brown
12395b482a8SLen Brown {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address64.resource_source),
12495b482a8SLen Brown 0,
12595b482a8SLen Brown sizeof(struct aml_resource_address64)}
12695b482a8SLen Brown };
12795b482a8SLen Brown
12895b482a8SLen Brown /*******************************************************************************
12995b482a8SLen Brown *
13095b482a8SLen Brown * acpi_rs_convert_ext_address64 - All Extended (64-bit) address resources
13195b482a8SLen Brown *
13295b482a8SLen Brown ******************************************************************************/
13395b482a8SLen Brown
13495b482a8SLen Brown struct acpi_rsconvert_info acpi_rs_convert_ext_address64[5] = {
13595b482a8SLen Brown {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64,
13695b482a8SLen Brown ACPI_RS_SIZE(struct acpi_resource_extended_address64),
13795b482a8SLen Brown ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_address64)},
13895b482a8SLen Brown
13995b482a8SLen Brown {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64,
14095b482a8SLen Brown sizeof(struct aml_resource_extended_address64),
14195b482a8SLen Brown 0},
14295b482a8SLen Brown
14395b482a8SLen Brown /* Resource Type, General Flags, and Type-Specific Flags */
14495b482a8SLen Brown
14595b482a8SLen Brown {ACPI_RSC_ADDRESS, 0, 0, 0},
14695b482a8SLen Brown
14795b482a8SLen Brown /* Revision ID */
14895b482a8SLen Brown
149ba494beeSBob Moore {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.ext_address64.revision_ID),
150ba494beeSBob Moore AML_OFFSET(ext_address64.revision_ID),
15195b482a8SLen Brown 1},
15295b482a8SLen Brown /*
15395b482a8SLen Brown * These fields are contiguous in both the source and destination:
15495b482a8SLen Brown * Address Granularity
15595b482a8SLen Brown * Address Range Minimum
15695b482a8SLen Brown * Address Range Maximum
15795b482a8SLen Brown * Address Translation Offset
15895b482a8SLen Brown * Address Length
15995b482a8SLen Brown * Type-Specific Attribute
16095b482a8SLen Brown */
161a45de93eSLv Zheng {ACPI_RSC_MOVE64,
162a45de93eSLv Zheng ACPI_RS_OFFSET(data.ext_address64.address.granularity),
16395b482a8SLen Brown AML_OFFSET(ext_address64.granularity),
16495b482a8SLen Brown 6}
16595b482a8SLen Brown };
16695b482a8SLen Brown
16795b482a8SLen Brown /*******************************************************************************
16895b482a8SLen Brown *
16995b482a8SLen Brown * acpi_rs_convert_general_flags - Flags common to all address descriptors
17095b482a8SLen Brown *
17195b482a8SLen Brown ******************************************************************************/
17295b482a8SLen Brown
17395b482a8SLen Brown static struct acpi_rsconvert_info acpi_rs_convert_general_flags[6] = {
17495b482a8SLen Brown {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.flags),
17595b482a8SLen Brown ACPI_RSC_TABLE_SIZE(acpi_rs_convert_general_flags)},
17695b482a8SLen Brown
17795b482a8SLen Brown /* Resource Type (Memory, Io, bus_number, etc.) */
17895b482a8SLen Brown
17995b482a8SLen Brown {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.address.resource_type),
18095b482a8SLen Brown AML_OFFSET(address.resource_type),
18195b482a8SLen Brown 1},
18295b482a8SLen Brown
183ba494beeSBob Moore /* General flags - Consume, Decode, min_fixed, max_fixed */
18495b482a8SLen Brown
18595b482a8SLen Brown {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.producer_consumer),
18695b482a8SLen Brown AML_OFFSET(address.flags),
18795b482a8SLen Brown 0},
18895b482a8SLen Brown
18995b482a8SLen Brown {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.decode),
19095b482a8SLen Brown AML_OFFSET(address.flags),
19195b482a8SLen Brown 1},
19295b482a8SLen Brown
19395b482a8SLen Brown {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.min_address_fixed),
19495b482a8SLen Brown AML_OFFSET(address.flags),
19595b482a8SLen Brown 2},
19695b482a8SLen Brown
19795b482a8SLen Brown {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.max_address_fixed),
19895b482a8SLen Brown AML_OFFSET(address.flags),
19995b482a8SLen Brown 3}
20095b482a8SLen Brown };
20195b482a8SLen Brown
20295b482a8SLen Brown /*******************************************************************************
20395b482a8SLen Brown *
20495b482a8SLen Brown * acpi_rs_convert_mem_flags - Flags common to Memory address descriptors
20595b482a8SLen Brown *
20695b482a8SLen Brown ******************************************************************************/
20795b482a8SLen Brown
20895b482a8SLen Brown static struct acpi_rsconvert_info acpi_rs_convert_mem_flags[5] = {
20995b482a8SLen Brown {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags),
21095b482a8SLen Brown ACPI_RSC_TABLE_SIZE(acpi_rs_convert_mem_flags)},
21195b482a8SLen Brown
21295b482a8SLen Brown /* Memory-specific flags */
21395b482a8SLen Brown
21495b482a8SLen Brown {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.write_protect),
21595b482a8SLen Brown AML_OFFSET(address.specific_flags),
21695b482a8SLen Brown 0},
21795b482a8SLen Brown
21895b482a8SLen Brown {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.caching),
21995b482a8SLen Brown AML_OFFSET(address.specific_flags),
22095b482a8SLen Brown 1},
22195b482a8SLen Brown
22295b482a8SLen Brown {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.range_type),
22395b482a8SLen Brown AML_OFFSET(address.specific_flags),
22495b482a8SLen Brown 3},
22595b482a8SLen Brown
22695b482a8SLen Brown {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.translation),
22795b482a8SLen Brown AML_OFFSET(address.specific_flags),
22895b482a8SLen Brown 5}
22995b482a8SLen Brown };
23095b482a8SLen Brown
23195b482a8SLen Brown /*******************************************************************************
23295b482a8SLen Brown *
23395b482a8SLen Brown * acpi_rs_convert_io_flags - Flags common to I/O address descriptors
23495b482a8SLen Brown *
23595b482a8SLen Brown ******************************************************************************/
23695b482a8SLen Brown
23795b482a8SLen Brown static struct acpi_rsconvert_info acpi_rs_convert_io_flags[4] = {
23895b482a8SLen Brown {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags),
23995b482a8SLen Brown ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io_flags)},
24095b482a8SLen Brown
24195b482a8SLen Brown /* I/O-specific flags */
24295b482a8SLen Brown
24395b482a8SLen Brown {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.io.range_type),
24495b482a8SLen Brown AML_OFFSET(address.specific_flags),
24595b482a8SLen Brown 0},
24695b482a8SLen Brown
24795b482a8SLen Brown {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.io.translation),
24895b482a8SLen Brown AML_OFFSET(address.specific_flags),
24995b482a8SLen Brown 4},
25095b482a8SLen Brown
25195b482a8SLen Brown {ACPI_RSC_1BITFLAG,
25295b482a8SLen Brown ACPI_RS_OFFSET(data.address.info.io.translation_type),
25395b482a8SLen Brown AML_OFFSET(address.specific_flags),
25495b482a8SLen Brown 5}
25595b482a8SLen Brown };
25695b482a8SLen Brown
25795b482a8SLen Brown /*******************************************************************************
25895b482a8SLen Brown *
25995b482a8SLen Brown * FUNCTION: acpi_rs_get_address_common
26095b482a8SLen Brown *
261ba494beeSBob Moore * PARAMETERS: resource - Pointer to the internal resource struct
262ba494beeSBob Moore * aml - Pointer to the AML resource descriptor
26395b482a8SLen Brown *
26495b482a8SLen Brown * RETURN: TRUE if the resource_type field is OK, FALSE otherwise
26595b482a8SLen Brown *
26695b482a8SLen Brown * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor
26795b482a8SLen Brown * to an internal resource descriptor
26895b482a8SLen Brown *
26995b482a8SLen Brown ******************************************************************************/
27095b482a8SLen Brown
27195b482a8SLen Brown u8
acpi_rs_get_address_common(struct acpi_resource * resource,union aml_resource * aml)27295b482a8SLen Brown acpi_rs_get_address_common(struct acpi_resource *resource,
27395b482a8SLen Brown union aml_resource *aml)
27495b482a8SLen Brown {
27524d9609bSTamir Duberstein struct aml_resource_address address;
27624d9609bSTamir Duberstein
27795b482a8SLen Brown ACPI_FUNCTION_ENTRY();
27895b482a8SLen Brown
27924d9609bSTamir Duberstein /* Avoid undefined behavior: member access within misaligned address */
28024d9609bSTamir Duberstein
28124d9609bSTamir Duberstein memcpy(&address, aml, sizeof(address));
28224d9609bSTamir Duberstein
28395b482a8SLen Brown /* Validate the Resource Type */
28495b482a8SLen Brown
285*cff8a9f6SAdam Young if ((address.resource_type > 2) &&
286*cff8a9f6SAdam Young (address.resource_type < 0xC0) && (address.resource_type != 0x0A)) {
28795b482a8SLen Brown return (FALSE);
28895b482a8SLen Brown }
28995b482a8SLen Brown
29095b482a8SLen Brown /* Get the Resource Type and General Flags */
29195b482a8SLen Brown
29295b482a8SLen Brown (void)acpi_rs_convert_aml_to_resource(resource, aml,
29395b482a8SLen Brown acpi_rs_convert_general_flags);
29495b482a8SLen Brown
29595b482a8SLen Brown /* Get the Type-Specific Flags (Memory and I/O descriptors only) */
29695b482a8SLen Brown
29795b482a8SLen Brown if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) {
29895b482a8SLen Brown (void)acpi_rs_convert_aml_to_resource(resource, aml,
29995b482a8SLen Brown acpi_rs_convert_mem_flags);
30095b482a8SLen Brown } else if (resource->data.address.resource_type == ACPI_IO_RANGE) {
30195b482a8SLen Brown (void)acpi_rs_convert_aml_to_resource(resource, aml,
30295b482a8SLen Brown acpi_rs_convert_io_flags);
30395b482a8SLen Brown } else {
30495b482a8SLen Brown /* Generic resource type, just grab the type_specific byte */
30595b482a8SLen Brown
30695b482a8SLen Brown resource->data.address.info.type_specific =
30724d9609bSTamir Duberstein address.specific_flags;
30895b482a8SLen Brown }
30995b482a8SLen Brown
31095b482a8SLen Brown return (TRUE);
31195b482a8SLen Brown }
31295b482a8SLen Brown
31395b482a8SLen Brown /*******************************************************************************
31495b482a8SLen Brown *
31595b482a8SLen Brown * FUNCTION: acpi_rs_set_address_common
31695b482a8SLen Brown *
317ba494beeSBob Moore * PARAMETERS: aml - Pointer to the AML resource descriptor
318ba494beeSBob Moore * resource - Pointer to the internal resource struct
31995b482a8SLen Brown *
32095b482a8SLen Brown * RETURN: None
32195b482a8SLen Brown *
32295b482a8SLen Brown * DESCRIPTION: Convert common flag fields from a resource descriptor to an
32395b482a8SLen Brown * AML descriptor
32495b482a8SLen Brown *
32595b482a8SLen Brown ******************************************************************************/
32695b482a8SLen Brown
32795b482a8SLen Brown void
acpi_rs_set_address_common(union aml_resource * aml,struct acpi_resource * resource)32895b482a8SLen Brown acpi_rs_set_address_common(union aml_resource *aml,
32995b482a8SLen Brown struct acpi_resource *resource)
33095b482a8SLen Brown {
33195b482a8SLen Brown ACPI_FUNCTION_ENTRY();
33295b482a8SLen Brown
33395b482a8SLen Brown /* Set the Resource Type and General Flags */
33495b482a8SLen Brown
33595b482a8SLen Brown (void)acpi_rs_convert_resource_to_aml(resource, aml,
33695b482a8SLen Brown acpi_rs_convert_general_flags);
33795b482a8SLen Brown
33895b482a8SLen Brown /* Set the Type-Specific Flags (Memory and I/O descriptors only) */
33995b482a8SLen Brown
34095b482a8SLen Brown if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) {
34195b482a8SLen Brown (void)acpi_rs_convert_resource_to_aml(resource, aml,
34295b482a8SLen Brown acpi_rs_convert_mem_flags);
34395b482a8SLen Brown } else if (resource->data.address.resource_type == ACPI_IO_RANGE) {
34495b482a8SLen Brown (void)acpi_rs_convert_resource_to_aml(resource, aml,
34595b482a8SLen Brown acpi_rs_convert_io_flags);
34695b482a8SLen Brown } else {
34795b482a8SLen Brown /* Generic resource type, just copy the type_specific byte */
34895b482a8SLen Brown
34995b482a8SLen Brown aml->address.specific_flags =
35095b482a8SLen Brown resource->data.address.info.type_specific;
35195b482a8SLen Brown }
35295b482a8SLen Brown }
353