353 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/*******************************************************************************3 *4 * Module Name: rsaddr - Address resource descriptors (16/32/64)5 *6 ******************************************************************************/7 8#include <acpi/acpi.h>9#include "accommon.h"10#include "acresrc.h"11 12#define _COMPONENT ACPI_RESOURCES13ACPI_MODULE_NAME("rsaddr")14 15/*******************************************************************************16 *17 * acpi_rs_convert_address16 - All WORD (16-bit) address resources18 *19 ******************************************************************************/20struct acpi_rsconvert_info acpi_rs_convert_address16[5] = {21 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS16,22 ACPI_RS_SIZE(struct acpi_resource_address16),23 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address16)},24 25 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS16,26 sizeof(struct aml_resource_address16),27 0},28 29 /* Resource Type, General Flags, and Type-Specific Flags */30 31 {ACPI_RSC_ADDRESS, 0, 0, 0},32 33 /*34 * These fields are contiguous in both the source and destination:35 * Address Granularity36 * Address Range Minimum37 * Address Range Maximum38 * Address Translation Offset39 * Address Length40 */41 {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.address16.address.granularity),42 AML_OFFSET(address16.granularity),43 5},44 45 /* Optional resource_source (Index and String) */46 47 {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address16.resource_source),48 0,49 sizeof(struct aml_resource_address16)}50};51 52/*******************************************************************************53 *54 * acpi_rs_convert_address32 - All DWORD (32-bit) address resources55 *56 ******************************************************************************/57 58struct acpi_rsconvert_info acpi_rs_convert_address32[5] = {59 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS32,60 ACPI_RS_SIZE(struct acpi_resource_address32),61 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address32)},62 63 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS32,64 sizeof(struct aml_resource_address32),65 0},66 67 /* Resource Type, General Flags, and Type-Specific Flags */68 69 {ACPI_RSC_ADDRESS, 0, 0, 0},70 71 /*72 * These fields are contiguous in both the source and destination:73 * Address Granularity74 * Address Range Minimum75 * Address Range Maximum76 * Address Translation Offset77 * Address Length78 */79 {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.address32.address.granularity),80 AML_OFFSET(address32.granularity),81 5},82 83 /* Optional resource_source (Index and String) */84 85 {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address32.resource_source),86 0,87 sizeof(struct aml_resource_address32)}88};89 90/*******************************************************************************91 *92 * acpi_rs_convert_address64 - All QWORD (64-bit) address resources93 *94 ******************************************************************************/95 96struct acpi_rsconvert_info acpi_rs_convert_address64[5] = {97 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS64,98 ACPI_RS_SIZE(struct acpi_resource_address64),99 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address64)},100 101 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS64,102 sizeof(struct aml_resource_address64),103 0},104 105 /* Resource Type, General Flags, and Type-Specific Flags */106 107 {ACPI_RSC_ADDRESS, 0, 0, 0},108 109 /*110 * These fields are contiguous in both the source and destination:111 * Address Granularity112 * Address Range Minimum113 * Address Range Maximum114 * Address Translation Offset115 * Address Length116 */117 {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.address64.address.granularity),118 AML_OFFSET(address64.granularity),119 5},120 121 /* Optional resource_source (Index and String) */122 123 {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address64.resource_source),124 0,125 sizeof(struct aml_resource_address64)}126};127 128/*******************************************************************************129 *130 * acpi_rs_convert_ext_address64 - All Extended (64-bit) address resources131 *132 ******************************************************************************/133 134struct acpi_rsconvert_info acpi_rs_convert_ext_address64[5] = {135 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64,136 ACPI_RS_SIZE(struct acpi_resource_extended_address64),137 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_address64)},138 139 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64,140 sizeof(struct aml_resource_extended_address64),141 0},142 143 /* Resource Type, General Flags, and Type-Specific Flags */144 145 {ACPI_RSC_ADDRESS, 0, 0, 0},146 147 /* Revision ID */148 149 {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.ext_address64.revision_ID),150 AML_OFFSET(ext_address64.revision_ID),151 1},152 /*153 * These fields are contiguous in both the source and destination:154 * Address Granularity155 * Address Range Minimum156 * Address Range Maximum157 * Address Translation Offset158 * Address Length159 * Type-Specific Attribute160 */161 {ACPI_RSC_MOVE64,162 ACPI_RS_OFFSET(data.ext_address64.address.granularity),163 AML_OFFSET(ext_address64.granularity),164 6}165};166 167/*******************************************************************************168 *169 * acpi_rs_convert_general_flags - Flags common to all address descriptors170 *171 ******************************************************************************/172 173static struct acpi_rsconvert_info acpi_rs_convert_general_flags[6] = {174 {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.flags),175 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_general_flags)},176 177 /* Resource Type (Memory, Io, bus_number, etc.) */178 179 {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.address.resource_type),180 AML_OFFSET(address.resource_type),181 1},182 183 /* General flags - Consume, Decode, min_fixed, max_fixed */184 185 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.producer_consumer),186 AML_OFFSET(address.flags),187 0},188 189 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.decode),190 AML_OFFSET(address.flags),191 1},192 193 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.min_address_fixed),194 AML_OFFSET(address.flags),195 2},196 197 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.max_address_fixed),198 AML_OFFSET(address.flags),199 3}200};201 202/*******************************************************************************203 *204 * acpi_rs_convert_mem_flags - Flags common to Memory address descriptors205 *206 ******************************************************************************/207 208static struct acpi_rsconvert_info acpi_rs_convert_mem_flags[5] = {209 {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags),210 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_mem_flags)},211 212 /* Memory-specific flags */213 214 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.write_protect),215 AML_OFFSET(address.specific_flags),216 0},217 218 {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.caching),219 AML_OFFSET(address.specific_flags),220 1},221 222 {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.range_type),223 AML_OFFSET(address.specific_flags),224 3},225 226 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.translation),227 AML_OFFSET(address.specific_flags),228 5}229};230 231/*******************************************************************************232 *233 * acpi_rs_convert_io_flags - Flags common to I/O address descriptors234 *235 ******************************************************************************/236 237static struct acpi_rsconvert_info acpi_rs_convert_io_flags[4] = {238 {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags),239 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io_flags)},240 241 /* I/O-specific flags */242 243 {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.io.range_type),244 AML_OFFSET(address.specific_flags),245 0},246 247 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.io.translation),248 AML_OFFSET(address.specific_flags),249 4},250 251 {ACPI_RSC_1BITFLAG,252 ACPI_RS_OFFSET(data.address.info.io.translation_type),253 AML_OFFSET(address.specific_flags),254 5}255};256 257/*******************************************************************************258 *259 * FUNCTION: acpi_rs_get_address_common260 *261 * PARAMETERS: resource - Pointer to the internal resource struct262 * aml - Pointer to the AML resource descriptor263 *264 * RETURN: TRUE if the resource_type field is OK, FALSE otherwise265 *266 * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor267 * to an internal resource descriptor268 *269 ******************************************************************************/270 271u8272acpi_rs_get_address_common(struct acpi_resource *resource,273 union aml_resource *aml)274{275 struct aml_resource_address address;276 277 ACPI_FUNCTION_ENTRY();278 279 /* Avoid undefined behavior: member access within misaligned address */280 281 memcpy(&address, aml, sizeof(address));282 283 /* Validate the Resource Type */284 285 if ((address.resource_type > 2) &&286 (address.resource_type < 0xC0) && (address.resource_type != 0x0A)) {287 return (FALSE);288 }289 290 /* Get the Resource Type and General Flags */291 292 (void)acpi_rs_convert_aml_to_resource(resource, aml,293 acpi_rs_convert_general_flags);294 295 /* Get the Type-Specific Flags (Memory and I/O descriptors only) */296 297 if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) {298 (void)acpi_rs_convert_aml_to_resource(resource, aml,299 acpi_rs_convert_mem_flags);300 } else if (resource->data.address.resource_type == ACPI_IO_RANGE) {301 (void)acpi_rs_convert_aml_to_resource(resource, aml,302 acpi_rs_convert_io_flags);303 } else {304 /* Generic resource type, just grab the type_specific byte */305 306 resource->data.address.info.type_specific =307 address.specific_flags;308 }309 310 return (TRUE);311}312 313/*******************************************************************************314 *315 * FUNCTION: acpi_rs_set_address_common316 *317 * PARAMETERS: aml - Pointer to the AML resource descriptor318 * resource - Pointer to the internal resource struct319 *320 * RETURN: None321 *322 * DESCRIPTION: Convert common flag fields from a resource descriptor to an323 * AML descriptor324 *325 ******************************************************************************/326 327void328acpi_rs_set_address_common(union aml_resource *aml,329 struct acpi_resource *resource)330{331 ACPI_FUNCTION_ENTRY();332 333 /* Set the Resource Type and General Flags */334 335 (void)acpi_rs_convert_resource_to_aml(resource, aml,336 acpi_rs_convert_general_flags);337 338 /* Set the Type-Specific Flags (Memory and I/O descriptors only) */339 340 if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) {341 (void)acpi_rs_convert_resource_to_aml(resource, aml,342 acpi_rs_convert_mem_flags);343 } else if (resource->data.address.resource_type == ACPI_IO_RANGE) {344 (void)acpi_rs_convert_resource_to_aml(resource, aml,345 acpi_rs_convert_io_flags);346 } else {347 /* Generic resource type, just copy the type_specific byte */348 349 aml->address.specific_flags =350 resource->data.address.info.type_specific;351 }352}353