162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 262306a36Sopenharmony_ci/******************************************************************************* 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Module Name: rsaddr - Address resource descriptors (16/32/64) 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci ******************************************************************************/ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <acpi/acpi.h> 962306a36Sopenharmony_ci#include "accommon.h" 1062306a36Sopenharmony_ci#include "acresrc.h" 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#define _COMPONENT ACPI_RESOURCES 1362306a36Sopenharmony_ciACPI_MODULE_NAME("rsaddr") 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/******************************************************************************* 1662306a36Sopenharmony_ci * 1762306a36Sopenharmony_ci * acpi_rs_convert_address16 - All WORD (16-bit) address resources 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci ******************************************************************************/ 2062306a36Sopenharmony_cistruct acpi_rsconvert_info acpi_rs_convert_address16[5] = { 2162306a36Sopenharmony_ci {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS16, 2262306a36Sopenharmony_ci ACPI_RS_SIZE(struct acpi_resource_address16), 2362306a36Sopenharmony_ci ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address16)}, 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS16, 2662306a36Sopenharmony_ci sizeof(struct aml_resource_address16), 2762306a36Sopenharmony_ci 0}, 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci /* Resource Type, General Flags, and Type-Specific Flags */ 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci {ACPI_RSC_ADDRESS, 0, 0, 0}, 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci /* 3462306a36Sopenharmony_ci * These fields are contiguous in both the source and destination: 3562306a36Sopenharmony_ci * Address Granularity 3662306a36Sopenharmony_ci * Address Range Minimum 3762306a36Sopenharmony_ci * Address Range Maximum 3862306a36Sopenharmony_ci * Address Translation Offset 3962306a36Sopenharmony_ci * Address Length 4062306a36Sopenharmony_ci */ 4162306a36Sopenharmony_ci {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.address16.address.granularity), 4262306a36Sopenharmony_ci AML_OFFSET(address16.granularity), 4362306a36Sopenharmony_ci 5}, 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci /* Optional resource_source (Index and String) */ 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address16.resource_source), 4862306a36Sopenharmony_ci 0, 4962306a36Sopenharmony_ci sizeof(struct aml_resource_address16)} 5062306a36Sopenharmony_ci}; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci/******************************************************************************* 5362306a36Sopenharmony_ci * 5462306a36Sopenharmony_ci * acpi_rs_convert_address32 - All DWORD (32-bit) address resources 5562306a36Sopenharmony_ci * 5662306a36Sopenharmony_ci ******************************************************************************/ 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cistruct acpi_rsconvert_info acpi_rs_convert_address32[5] = { 5962306a36Sopenharmony_ci {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS32, 6062306a36Sopenharmony_ci ACPI_RS_SIZE(struct acpi_resource_address32), 6162306a36Sopenharmony_ci ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address32)}, 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS32, 6462306a36Sopenharmony_ci sizeof(struct aml_resource_address32), 6562306a36Sopenharmony_ci 0}, 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci /* Resource Type, General Flags, and Type-Specific Flags */ 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci {ACPI_RSC_ADDRESS, 0, 0, 0}, 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci /* 7262306a36Sopenharmony_ci * These fields are contiguous in both the source and destination: 7362306a36Sopenharmony_ci * Address Granularity 7462306a36Sopenharmony_ci * Address Range Minimum 7562306a36Sopenharmony_ci * Address Range Maximum 7662306a36Sopenharmony_ci * Address Translation Offset 7762306a36Sopenharmony_ci * Address Length 7862306a36Sopenharmony_ci */ 7962306a36Sopenharmony_ci {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.address32.address.granularity), 8062306a36Sopenharmony_ci AML_OFFSET(address32.granularity), 8162306a36Sopenharmony_ci 5}, 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci /* Optional resource_source (Index and String) */ 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address32.resource_source), 8662306a36Sopenharmony_ci 0, 8762306a36Sopenharmony_ci sizeof(struct aml_resource_address32)} 8862306a36Sopenharmony_ci}; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci/******************************************************************************* 9162306a36Sopenharmony_ci * 9262306a36Sopenharmony_ci * acpi_rs_convert_address64 - All QWORD (64-bit) address resources 9362306a36Sopenharmony_ci * 9462306a36Sopenharmony_ci ******************************************************************************/ 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistruct acpi_rsconvert_info acpi_rs_convert_address64[5] = { 9762306a36Sopenharmony_ci {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS64, 9862306a36Sopenharmony_ci ACPI_RS_SIZE(struct acpi_resource_address64), 9962306a36Sopenharmony_ci ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address64)}, 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS64, 10262306a36Sopenharmony_ci sizeof(struct aml_resource_address64), 10362306a36Sopenharmony_ci 0}, 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci /* Resource Type, General Flags, and Type-Specific Flags */ 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci {ACPI_RSC_ADDRESS, 0, 0, 0}, 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci /* 11062306a36Sopenharmony_ci * These fields are contiguous in both the source and destination: 11162306a36Sopenharmony_ci * Address Granularity 11262306a36Sopenharmony_ci * Address Range Minimum 11362306a36Sopenharmony_ci * Address Range Maximum 11462306a36Sopenharmony_ci * Address Translation Offset 11562306a36Sopenharmony_ci * Address Length 11662306a36Sopenharmony_ci */ 11762306a36Sopenharmony_ci {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.address64.address.granularity), 11862306a36Sopenharmony_ci AML_OFFSET(address64.granularity), 11962306a36Sopenharmony_ci 5}, 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci /* Optional resource_source (Index and String) */ 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address64.resource_source), 12462306a36Sopenharmony_ci 0, 12562306a36Sopenharmony_ci sizeof(struct aml_resource_address64)} 12662306a36Sopenharmony_ci}; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci/******************************************************************************* 12962306a36Sopenharmony_ci * 13062306a36Sopenharmony_ci * acpi_rs_convert_ext_address64 - All Extended (64-bit) address resources 13162306a36Sopenharmony_ci * 13262306a36Sopenharmony_ci ******************************************************************************/ 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_cistruct acpi_rsconvert_info acpi_rs_convert_ext_address64[5] = { 13562306a36Sopenharmony_ci {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64, 13662306a36Sopenharmony_ci ACPI_RS_SIZE(struct acpi_resource_extended_address64), 13762306a36Sopenharmony_ci ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_address64)}, 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64, 14062306a36Sopenharmony_ci sizeof(struct aml_resource_extended_address64), 14162306a36Sopenharmony_ci 0}, 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci /* Resource Type, General Flags, and Type-Specific Flags */ 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci {ACPI_RSC_ADDRESS, 0, 0, 0}, 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci /* Revision ID */ 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.ext_address64.revision_ID), 15062306a36Sopenharmony_ci AML_OFFSET(ext_address64.revision_ID), 15162306a36Sopenharmony_ci 1}, 15262306a36Sopenharmony_ci /* 15362306a36Sopenharmony_ci * These fields are contiguous in both the source and destination: 15462306a36Sopenharmony_ci * Address Granularity 15562306a36Sopenharmony_ci * Address Range Minimum 15662306a36Sopenharmony_ci * Address Range Maximum 15762306a36Sopenharmony_ci * Address Translation Offset 15862306a36Sopenharmony_ci * Address Length 15962306a36Sopenharmony_ci * Type-Specific Attribute 16062306a36Sopenharmony_ci */ 16162306a36Sopenharmony_ci {ACPI_RSC_MOVE64, 16262306a36Sopenharmony_ci ACPI_RS_OFFSET(data.ext_address64.address.granularity), 16362306a36Sopenharmony_ci AML_OFFSET(ext_address64.granularity), 16462306a36Sopenharmony_ci 6} 16562306a36Sopenharmony_ci}; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci/******************************************************************************* 16862306a36Sopenharmony_ci * 16962306a36Sopenharmony_ci * acpi_rs_convert_general_flags - Flags common to all address descriptors 17062306a36Sopenharmony_ci * 17162306a36Sopenharmony_ci ******************************************************************************/ 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_cistatic struct acpi_rsconvert_info acpi_rs_convert_general_flags[6] = { 17462306a36Sopenharmony_ci {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.flags), 17562306a36Sopenharmony_ci ACPI_RSC_TABLE_SIZE(acpi_rs_convert_general_flags)}, 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci /* Resource Type (Memory, Io, bus_number, etc.) */ 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.address.resource_type), 18062306a36Sopenharmony_ci AML_OFFSET(address.resource_type), 18162306a36Sopenharmony_ci 1}, 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci /* General flags - Consume, Decode, min_fixed, max_fixed */ 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.producer_consumer), 18662306a36Sopenharmony_ci AML_OFFSET(address.flags), 18762306a36Sopenharmony_ci 0}, 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.decode), 19062306a36Sopenharmony_ci AML_OFFSET(address.flags), 19162306a36Sopenharmony_ci 1}, 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.min_address_fixed), 19462306a36Sopenharmony_ci AML_OFFSET(address.flags), 19562306a36Sopenharmony_ci 2}, 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.max_address_fixed), 19862306a36Sopenharmony_ci AML_OFFSET(address.flags), 19962306a36Sopenharmony_ci 3} 20062306a36Sopenharmony_ci}; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci/******************************************************************************* 20362306a36Sopenharmony_ci * 20462306a36Sopenharmony_ci * acpi_rs_convert_mem_flags - Flags common to Memory address descriptors 20562306a36Sopenharmony_ci * 20662306a36Sopenharmony_ci ******************************************************************************/ 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_cistatic struct acpi_rsconvert_info acpi_rs_convert_mem_flags[5] = { 20962306a36Sopenharmony_ci {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags), 21062306a36Sopenharmony_ci ACPI_RSC_TABLE_SIZE(acpi_rs_convert_mem_flags)}, 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci /* Memory-specific flags */ 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.write_protect), 21562306a36Sopenharmony_ci AML_OFFSET(address.specific_flags), 21662306a36Sopenharmony_ci 0}, 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.caching), 21962306a36Sopenharmony_ci AML_OFFSET(address.specific_flags), 22062306a36Sopenharmony_ci 1}, 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.range_type), 22362306a36Sopenharmony_ci AML_OFFSET(address.specific_flags), 22462306a36Sopenharmony_ci 3}, 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.translation), 22762306a36Sopenharmony_ci AML_OFFSET(address.specific_flags), 22862306a36Sopenharmony_ci 5} 22962306a36Sopenharmony_ci}; 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci/******************************************************************************* 23262306a36Sopenharmony_ci * 23362306a36Sopenharmony_ci * acpi_rs_convert_io_flags - Flags common to I/O address descriptors 23462306a36Sopenharmony_ci * 23562306a36Sopenharmony_ci ******************************************************************************/ 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_cistatic struct acpi_rsconvert_info acpi_rs_convert_io_flags[4] = { 23862306a36Sopenharmony_ci {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags), 23962306a36Sopenharmony_ci ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io_flags)}, 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci /* I/O-specific flags */ 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.io.range_type), 24462306a36Sopenharmony_ci AML_OFFSET(address.specific_flags), 24562306a36Sopenharmony_ci 0}, 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.io.translation), 24862306a36Sopenharmony_ci AML_OFFSET(address.specific_flags), 24962306a36Sopenharmony_ci 4}, 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci {ACPI_RSC_1BITFLAG, 25262306a36Sopenharmony_ci ACPI_RS_OFFSET(data.address.info.io.translation_type), 25362306a36Sopenharmony_ci AML_OFFSET(address.specific_flags), 25462306a36Sopenharmony_ci 5} 25562306a36Sopenharmony_ci}; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci/******************************************************************************* 25862306a36Sopenharmony_ci * 25962306a36Sopenharmony_ci * FUNCTION: acpi_rs_get_address_common 26062306a36Sopenharmony_ci * 26162306a36Sopenharmony_ci * PARAMETERS: resource - Pointer to the internal resource struct 26262306a36Sopenharmony_ci * aml - Pointer to the AML resource descriptor 26362306a36Sopenharmony_ci * 26462306a36Sopenharmony_ci * RETURN: TRUE if the resource_type field is OK, FALSE otherwise 26562306a36Sopenharmony_ci * 26662306a36Sopenharmony_ci * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor 26762306a36Sopenharmony_ci * to an internal resource descriptor 26862306a36Sopenharmony_ci * 26962306a36Sopenharmony_ci ******************************************************************************/ 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ciu8 27262306a36Sopenharmony_ciacpi_rs_get_address_common(struct acpi_resource *resource, 27362306a36Sopenharmony_ci union aml_resource *aml) 27462306a36Sopenharmony_ci{ 27562306a36Sopenharmony_ci struct aml_resource_address address; 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci ACPI_FUNCTION_ENTRY(); 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci /* Avoid undefined behavior: member access within misaligned address */ 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci memcpy(&address, aml, sizeof(address)); 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci /* Validate the Resource Type */ 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci if ((address.resource_type > 2) && (address.resource_type < 0xC0)) { 28662306a36Sopenharmony_ci return (FALSE); 28762306a36Sopenharmony_ci } 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci /* Get the Resource Type and General Flags */ 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci (void)acpi_rs_convert_aml_to_resource(resource, aml, 29262306a36Sopenharmony_ci acpi_rs_convert_general_flags); 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci /* Get the Type-Specific Flags (Memory and I/O descriptors only) */ 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) { 29762306a36Sopenharmony_ci (void)acpi_rs_convert_aml_to_resource(resource, aml, 29862306a36Sopenharmony_ci acpi_rs_convert_mem_flags); 29962306a36Sopenharmony_ci } else if (resource->data.address.resource_type == ACPI_IO_RANGE) { 30062306a36Sopenharmony_ci (void)acpi_rs_convert_aml_to_resource(resource, aml, 30162306a36Sopenharmony_ci acpi_rs_convert_io_flags); 30262306a36Sopenharmony_ci } else { 30362306a36Sopenharmony_ci /* Generic resource type, just grab the type_specific byte */ 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci resource->data.address.info.type_specific = 30662306a36Sopenharmony_ci address.specific_flags; 30762306a36Sopenharmony_ci } 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci return (TRUE); 31062306a36Sopenharmony_ci} 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci/******************************************************************************* 31362306a36Sopenharmony_ci * 31462306a36Sopenharmony_ci * FUNCTION: acpi_rs_set_address_common 31562306a36Sopenharmony_ci * 31662306a36Sopenharmony_ci * PARAMETERS: aml - Pointer to the AML resource descriptor 31762306a36Sopenharmony_ci * resource - Pointer to the internal resource struct 31862306a36Sopenharmony_ci * 31962306a36Sopenharmony_ci * RETURN: None 32062306a36Sopenharmony_ci * 32162306a36Sopenharmony_ci * DESCRIPTION: Convert common flag fields from a resource descriptor to an 32262306a36Sopenharmony_ci * AML descriptor 32362306a36Sopenharmony_ci * 32462306a36Sopenharmony_ci ******************************************************************************/ 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_civoid 32762306a36Sopenharmony_ciacpi_rs_set_address_common(union aml_resource *aml, 32862306a36Sopenharmony_ci struct acpi_resource *resource) 32962306a36Sopenharmony_ci{ 33062306a36Sopenharmony_ci ACPI_FUNCTION_ENTRY(); 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci /* Set the Resource Type and General Flags */ 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci (void)acpi_rs_convert_resource_to_aml(resource, aml, 33562306a36Sopenharmony_ci acpi_rs_convert_general_flags); 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci /* Set the Type-Specific Flags (Memory and I/O descriptors only) */ 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) { 34062306a36Sopenharmony_ci (void)acpi_rs_convert_resource_to_aml(resource, aml, 34162306a36Sopenharmony_ci acpi_rs_convert_mem_flags); 34262306a36Sopenharmony_ci } else if (resource->data.address.resource_type == ACPI_IO_RANGE) { 34362306a36Sopenharmony_ci (void)acpi_rs_convert_resource_to_aml(resource, aml, 34462306a36Sopenharmony_ci acpi_rs_convert_io_flags); 34562306a36Sopenharmony_ci } else { 34662306a36Sopenharmony_ci /* Generic resource type, just copy the type_specific byte */ 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci aml->address.specific_flags = 34962306a36Sopenharmony_ci resource->data.address.info.type_specific; 35062306a36Sopenharmony_ci } 35162306a36Sopenharmony_ci} 352