1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /******************************************************************************* 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_RESOURCES 13 ACPI_MODULE_NAME("rsaddr") 14 15 /******************************************************************************* 16 * 17 * acpi_rs_convert_address16 - All WORD (16-bit) address resources 18 * 19 ******************************************************************************/ 20 struct 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 Granularity 36 * Address Range Minimum 37 * Address Range Maximum 38 * Address Translation Offset 39 * Address Length 40 */ 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 resources 55 * 56 ******************************************************************************/ 57 58 struct 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 Granularity 74 * Address Range Minimum 75 * Address Range Maximum 76 * Address Translation Offset 77 * Address Length 78 */ 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 resources 93 * 94 ******************************************************************************/ 95 96 struct 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 Granularity 112 * Address Range Minimum 113 * Address Range Maximum 114 * Address Translation Offset 115 * Address Length 116 */ 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 resources 131 * 132 ******************************************************************************/ 133 134 struct 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 Granularity 155 * Address Range Minimum 156 * Address Range Maximum 157 * Address Translation Offset 158 * Address Length 159 * Type-Specific Attribute 160 */ 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 descriptors 170 * 171 ******************************************************************************/ 172 173 static 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 descriptors 205 * 206 ******************************************************************************/ 207 208 static 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 descriptors 234 * 235 ******************************************************************************/ 236 237 static 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_common 260 * 261 * PARAMETERS: resource - Pointer to the internal resource struct 262 * aml - Pointer to the AML resource descriptor 263 * 264 * RETURN: TRUE if the resource_type field is OK, FALSE otherwise 265 * 266 * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor 267 * to an internal resource descriptor 268 * 269 ******************************************************************************/ 270 271 u8 272 acpi_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) && (address.resource_type < 0xC0)) { 286 return (FALSE); 287 } 288 289 /* Get the Resource Type and General Flags */ 290 291 (void)acpi_rs_convert_aml_to_resource(resource, aml, 292 acpi_rs_convert_general_flags); 293 294 /* Get the Type-Specific Flags (Memory and I/O descriptors only) */ 295 296 if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) { 297 (void)acpi_rs_convert_aml_to_resource(resource, aml, 298 acpi_rs_convert_mem_flags); 299 } else if (resource->data.address.resource_type == ACPI_IO_RANGE) { 300 (void)acpi_rs_convert_aml_to_resource(resource, aml, 301 acpi_rs_convert_io_flags); 302 } else { 303 /* Generic resource type, just grab the type_specific byte */ 304 305 resource->data.address.info.type_specific = 306 address.specific_flags; 307 } 308 309 return (TRUE); 310 } 311 312 /******************************************************************************* 313 * 314 * FUNCTION: acpi_rs_set_address_common 315 * 316 * PARAMETERS: aml - Pointer to the AML resource descriptor 317 * resource - Pointer to the internal resource struct 318 * 319 * RETURN: None 320 * 321 * DESCRIPTION: Convert common flag fields from a resource descriptor to an 322 * AML descriptor 323 * 324 ******************************************************************************/ 325 326 void 327 acpi_rs_set_address_common(union aml_resource *aml, 328 struct acpi_resource *resource) 329 { 330 ACPI_FUNCTION_ENTRY(); 331 332 /* Set the Resource Type and General Flags */ 333 334 (void)acpi_rs_convert_resource_to_aml(resource, aml, 335 acpi_rs_convert_general_flags); 336 337 /* Set the Type-Specific Flags (Memory and I/O descriptors only) */ 338 339 if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) { 340 (void)acpi_rs_convert_resource_to_aml(resource, aml, 341 acpi_rs_convert_mem_flags); 342 } else if (resource->data.address.resource_type == ACPI_IO_RANGE) { 343 (void)acpi_rs_convert_resource_to_aml(resource, aml, 344 acpi_rs_convert_io_flags); 345 } else { 346 /* Generic resource type, just copy the type_specific byte */ 347 348 aml->address.specific_flags = 349 resource->data.address.info.type_specific; 350 } 351 } 352