diff options
Diffstat (limited to 'drivers/acpi/resources/rsaddr.c')
-rw-r--r-- | drivers/acpi/resources/rsaddr.c | 745 |
1 files changed, 198 insertions, 547 deletions
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c index 6f48ebf3304e..4ac942badbc0 100644 --- a/drivers/acpi/resources/rsaddr.c +++ b/drivers/acpi/resources/rsaddr.c | |||
@@ -47,683 +47,334 @@ | |||
47 | #define _COMPONENT ACPI_RESOURCES | 47 | #define _COMPONENT ACPI_RESOURCES |
48 | ACPI_MODULE_NAME("rsaddr") | 48 | ACPI_MODULE_NAME("rsaddr") |
49 | 49 | ||
50 | /* Local prototypes */ | ||
51 | static void | ||
52 | acpi_rs_decode_general_flags(union acpi_resource_data *resource, u8 flags); | ||
53 | |||
54 | static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource); | ||
55 | |||
56 | static void | ||
57 | acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags); | ||
58 | |||
59 | static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource); | ||
60 | |||
61 | static void | ||
62 | acpi_rs_set_address_common(union aml_resource *aml, | ||
63 | struct acpi_resource *resource); | ||
64 | |||
65 | static u8 | ||
66 | acpi_rs_get_address_common(struct acpi_resource *resource, | ||
67 | union aml_resource *aml); | ||
68 | |||
69 | /******************************************************************************* | ||
70 | * | ||
71 | * FUNCTION: acpi_rs_decode_general_flags | ||
72 | * | ||
73 | * PARAMETERS: Resource - Address resource data struct | ||
74 | * Flags - Raw AML flag byte | ||
75 | * | ||
76 | * RETURN: Decoded flag bits in resource struct | ||
77 | * | ||
78 | * DESCRIPTION: Decode a general flag byte to an address resource struct | ||
79 | * | ||
80 | ******************************************************************************/ | ||
81 | |||
82 | static void | ||
83 | acpi_rs_decode_general_flags(union acpi_resource_data *resource, u8 flags) | ||
84 | { | ||
85 | ACPI_FUNCTION_ENTRY(); | ||
86 | |||
87 | /* Producer / Consumer - flag bit[0] */ | ||
88 | |||
89 | resource->address.producer_consumer = (u32) (flags & 0x01); | ||
90 | |||
91 | /* Decode (_DEC) - flag bit[1] */ | ||
92 | |||
93 | resource->address.decode = (u32) ((flags >> 1) & 0x01); | ||
94 | |||
95 | /* Min Address Fixed (_MIF) - flag bit[2] */ | ||
96 | |||
97 | resource->address.min_address_fixed = (u32) ((flags >> 2) & 0x01); | ||
98 | |||
99 | /* Max Address Fixed (_MAF) - flag bit[3] */ | ||
100 | |||
101 | resource->address.max_address_fixed = (u32) ((flags >> 3) & 0x01); | ||
102 | } | ||
103 | |||
104 | /******************************************************************************* | ||
105 | * | ||
106 | * FUNCTION: acpi_rs_encode_general_flags | ||
107 | * | ||
108 | * PARAMETERS: Resource - Address resource data struct | ||
109 | * | ||
110 | * RETURN: Encoded general flag byte | ||
111 | * | ||
112 | * DESCRIPTION: Construct a general flag byte from an address resource struct | ||
113 | * | ||
114 | ******************************************************************************/ | ||
115 | |||
116 | static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource) | ||
117 | { | ||
118 | ACPI_FUNCTION_ENTRY(); | ||
119 | |||
120 | return ((u8) | ||
121 | |||
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)) | ||
130 | ); | ||
131 | } | ||
132 | |||
133 | /******************************************************************************* | 50 | /******************************************************************************* |
134 | * | 51 | * |
135 | * FUNCTION: acpi_rs_decode_specific_flags | 52 | * acpi_rs_convert_address16 - All WORD (16-bit) address resources |
136 | * | ||
137 | * PARAMETERS: Resource - Address resource data struct | ||
138 | * Flags - Raw AML flag byte | ||
139 | * | ||
140 | * RETURN: Decoded flag bits in attribute struct | ||
141 | * | ||
142 | * DESCRIPTION: Decode a type-specific flag byte to an attribute struct. | ||
143 | * Type-specific flags are only defined for the Memory and IO | ||
144 | * resource types. | ||
145 | * | 53 | * |
146 | ******************************************************************************/ | 54 | ******************************************************************************/ |
55 | struct acpi_rsconvert_info acpi_rs_convert_address16[5] = { | ||
56 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS16, | ||
57 | ACPI_RS_SIZE(struct acpi_resource_address16), | ||
58 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address16)}, | ||
147 | 59 | ||
148 | static void | 60 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS16, |
149 | acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags) | 61 | sizeof(struct aml_resource_address16), |
150 | { | 62 | 0}, |
151 | ACPI_FUNCTION_ENTRY(); | ||
152 | |||
153 | if (resource->address.resource_type == ACPI_MEMORY_RANGE) { | ||
154 | /* Write Status (_RW) - flag bit[0] */ | ||
155 | |||
156 | resource->address.attribute.memory.read_write_attribute = | ||
157 | (u16) (flags & 0x01); | ||
158 | 63 | ||
159 | /* Memory Attributes (_MEM) - flag bits[2:1] */ | 64 | /* Resource Type, General Flags, and Type-Specific Flags */ |
160 | 65 | ||
161 | resource->address.attribute.memory.cache_attribute = | 66 | {ACPI_RSC_ADDRESS, 0, 0, 0}, |
162 | (u16) ((flags >> 1) & 0x03); | ||
163 | } else if (resource->address.resource_type == ACPI_IO_RANGE) { | ||
164 | /* Ranges (_RNG) - flag bits[1:0] */ | ||
165 | |||
166 | resource->address.attribute.io.range_attribute = | ||
167 | (u16) (flags & 0x03); | ||
168 | |||
169 | /* Translations (_TTP and _TRS) - flag bits[5:4] */ | ||
170 | |||
171 | resource->address.attribute.io.translation_attribute = | ||
172 | (u16) ((flags >> 4) & 0x03); | ||
173 | } | ||
174 | } | ||
175 | |||
176 | /******************************************************************************* | ||
177 | * | ||
178 | * FUNCTION: acpi_rs_encode_specific_flags | ||
179 | * | ||
180 | * PARAMETERS: Resource - Address resource data struct | ||
181 | * | ||
182 | * RETURN: Encoded type-specific flag byte | ||
183 | * | ||
184 | * DESCRIPTION: Construct a type-specific flag byte from an attribute struct. | ||
185 | * Type-specific flags are only defined for the Memory and IO | ||
186 | * resource types. | ||
187 | * | ||
188 | ******************************************************************************/ | ||
189 | |||
190 | static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource) | ||
191 | { | ||
192 | ACPI_FUNCTION_ENTRY(); | ||
193 | |||
194 | if (resource->address.resource_type == ACPI_MEMORY_RANGE) { | ||
195 | return ((u8) | ||
196 | |||
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) { | ||
204 | return ((u8) | ||
205 | |||
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))); | ||
212 | } | ||
213 | |||
214 | return (0); | ||
215 | } | ||
216 | |||
217 | /******************************************************************************* | ||
218 | * | ||
219 | * FUNCTION: acpi_rs_set_address_common | ||
220 | * | ||
221 | * PARAMETERS: Aml - Pointer to the AML resource descriptor | ||
222 | * Resource - Pointer to the internal resource struct | ||
223 | * | ||
224 | * RETURN: None | ||
225 | * | ||
226 | * DESCRIPTION: Convert common flag fields from a resource descriptor to an | ||
227 | * AML descriptor | ||
228 | * | ||
229 | ******************************************************************************/ | ||
230 | |||
231 | static void | ||
232 | acpi_rs_set_address_common(union aml_resource *aml, | ||
233 | struct acpi_resource *resource) | ||
234 | { | ||
235 | ACPI_FUNCTION_ENTRY(); | ||
236 | |||
237 | /* Set the Resource Type (Memory, Io, bus_number, etc.) */ | ||
238 | |||
239 | aml->address.resource_type = (u8) resource->data.address.resource_type; | ||
240 | |||
241 | /* Set the general flags */ | ||
242 | |||
243 | aml->address.flags = acpi_rs_encode_general_flags(&resource->data); | ||
244 | |||
245 | /* Set the type-specific flags */ | ||
246 | |||
247 | aml->address.specific_flags = | ||
248 | acpi_rs_encode_specific_flags(&resource->data); | ||
249 | } | ||
250 | |||
251 | /******************************************************************************* | ||
252 | * | ||
253 | * FUNCTION: acpi_rs_get_address_common | ||
254 | * | ||
255 | * PARAMETERS: Resource - Pointer to the internal resource struct | ||
256 | * Aml - Pointer to the AML resource descriptor | ||
257 | * | ||
258 | * RETURN: TRUE if the resource_type field is OK, FALSE otherwise | ||
259 | * | ||
260 | * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor | ||
261 | * to an internal resource descriptor | ||
262 | * | ||
263 | ******************************************************************************/ | ||
264 | |||
265 | static u8 | ||
266 | acpi_rs_get_address_common(struct acpi_resource *resource, | ||
267 | union aml_resource *aml) | ||
268 | { | ||
269 | ACPI_FUNCTION_ENTRY(); | ||
270 | |||
271 | /* Validate resource type */ | ||
272 | |||
273 | if ((aml->address.resource_type > 2) | ||
274 | && (aml->address.resource_type < 0xC0)) { | ||
275 | return (FALSE); | ||
276 | } | ||
277 | |||
278 | /* Get the Resource Type (Memory, Io, bus_number, etc.) */ | ||
279 | |||
280 | resource->data.address.resource_type = aml->address.resource_type; | ||
281 | |||
282 | /* Get the General Flags */ | ||
283 | |||
284 | acpi_rs_decode_general_flags(&resource->data, aml->address.flags); | ||
285 | |||
286 | /* Get the Type-Specific Flags */ | ||
287 | |||
288 | acpi_rs_decode_specific_flags(&resource->data, | ||
289 | aml->address.specific_flags); | ||
290 | return (TRUE); | ||
291 | } | ||
292 | |||
293 | /******************************************************************************* | ||
294 | * | ||
295 | * FUNCTION: acpi_rs_get_address16 | ||
296 | * | ||
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 | ||
300 | * | ||
301 | * RETURN: Status | ||
302 | * | ||
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. | ||
306 | * | ||
307 | ******************************************************************************/ | ||
308 | |||
309 | acpi_status | ||
310 | acpi_rs_get_address16(union aml_resource * aml, | ||
311 | u16 aml_resource_length, struct acpi_resource * resource) | ||
312 | { | ||
313 | ACPI_FUNCTION_TRACE("rs_get_address16"); | ||
314 | |||
315 | /* Get the Resource Type, general flags, and type-specific flags */ | ||
316 | |||
317 | if (!acpi_rs_get_address_common(resource, aml)) { | ||
318 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | ||
319 | } | ||
320 | 67 | ||
321 | /* | 68 | /* |
322 | * Get the following contiguous fields from the AML descriptor: | 69 | * These fields are contiguous in both the source and destination: |
323 | * Address Granularity | 70 | * Address Granularity |
324 | * Address Range Minimum | 71 | * Address Range Minimum |
325 | * Address Range Maximum | 72 | * Address Range Maximum |
326 | * Address Translation Offset | 73 | * Address Translation Offset |
327 | * Address Length | 74 | * Address Length |
328 | */ | 75 | */ |
329 | acpi_rs_move_data(&resource->data.address16.granularity, | 76 | {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.address16.granularity), |
330 | &aml->address16.granularity, 5, | 77 | AML_OFFSET(address16.granularity), |
331 | ACPI_MOVE_TYPE_16_TO_32); | 78 | 5}, |
332 | |||
333 | /* Get the optional resource_source (index and string) */ | ||
334 | |||
335 | resource->length = | ||
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); | ||
341 | 79 | ||
342 | /* Complete the resource header */ | 80 | /* Optional resource_source (Index and String) */ |
343 | 81 | ||
344 | resource->type = ACPI_RESOURCE_TYPE_ADDRESS16; | 82 | {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address16.resource_source), |
345 | return_ACPI_STATUS(AE_OK); | 83 | 0, |
346 | } | 84 | sizeof(struct aml_resource_address16)} |
85 | }; | ||
347 | 86 | ||
348 | /******************************************************************************* | 87 | /******************************************************************************* |
349 | * | 88 | * |
350 | * FUNCTION: acpi_rs_set_address16 | 89 | * acpi_rs_convert_address32 - All DWORD (32-bit) address resources |
351 | * | ||
352 | * PARAMETERS: Resource - Pointer to the resource descriptor | ||
353 | * Aml - Where the AML descriptor is returned | ||
354 | * | ||
355 | * RETURN: Status | ||
356 | * | ||
357 | * DESCRIPTION: Convert an internal resource descriptor to the corresponding | ||
358 | * external AML resource descriptor. | ||
359 | * | 90 | * |
360 | ******************************************************************************/ | 91 | ******************************************************************************/ |
361 | 92 | ||
362 | acpi_status | 93 | struct acpi_rsconvert_info acpi_rs_convert_address32[5] = { |
363 | acpi_rs_set_address16(struct acpi_resource *resource, union aml_resource *aml) | 94 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS32, |
364 | { | 95 | ACPI_RS_SIZE(struct acpi_resource_address32), |
365 | acpi_size descriptor_length; | 96 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address32)}, |
366 | 97 | ||
367 | ACPI_FUNCTION_TRACE("rs_set_address16"); | 98 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS32, |
99 | sizeof(struct aml_resource_address32), | ||
100 | 0}, | ||
368 | 101 | ||
369 | /* Set the Resource Type, General Flags, and Type-Specific Flags */ | 102 | /* Resource Type, General Flags, and Type-Specific Flags */ |
370 | 103 | ||
371 | acpi_rs_set_address_common(aml, resource); | 104 | {ACPI_RSC_ADDRESS, 0, 0, 0}, |
372 | 105 | ||
373 | /* | 106 | /* |
374 | * Set the following contiguous fields in the AML descriptor: | 107 | * These fields are contiguous in both the source and destination: |
375 | * Address Granularity | 108 | * Address Granularity |
376 | * Address Range Minimum | 109 | * Address Range Minimum |
377 | * Address Range Maximum | 110 | * Address Range Maximum |
378 | * Address Translation Offset | 111 | * Address Translation Offset |
379 | * Address Length | 112 | * Address Length |
380 | */ | 113 | */ |
381 | acpi_rs_move_data(&aml->address16.granularity, | 114 | {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.address32.granularity), |
382 | &resource->data.address16.granularity, 5, | 115 | AML_OFFSET(address32.granularity), |
383 | ACPI_MOVE_TYPE_32_TO_16); | 116 | 5}, |
384 | |||
385 | /* Resource Source Index and Resource Source are optional */ | ||
386 | 117 | ||
387 | descriptor_length = acpi_rs_set_resource_source(aml, | 118 | /* Optional resource_source (Index and String) */ |
388 | sizeof(struct | ||
389 | aml_resource_address16), | ||
390 | &resource->data. | ||
391 | address16. | ||
392 | resource_source); | ||
393 | 119 | ||
394 | /* Complete the AML descriptor header */ | 120 | {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address32.resource_source), |
395 | 121 | 0, | |
396 | acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS16, | 122 | sizeof(struct aml_resource_address32)} |
397 | descriptor_length, aml); | 123 | }; |
398 | return_ACPI_STATUS(AE_OK); | ||
399 | } | ||
400 | 124 | ||
401 | /******************************************************************************* | 125 | /******************************************************************************* |
402 | * | 126 | * |
403 | * FUNCTION: acpi_rs_get_address32 | 127 | * acpi_rs_convert_address64 - All QWORD (64-bit) address resources |
404 | * | ||
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 | ||
408 | * | ||
409 | * RETURN: Status | ||
410 | * | ||
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. | ||
414 | * | 128 | * |
415 | ******************************************************************************/ | 129 | ******************************************************************************/ |
416 | 130 | ||
417 | acpi_status | 131 | struct acpi_rsconvert_info acpi_rs_convert_address64[5] = { |
418 | acpi_rs_get_address32(union aml_resource *aml, | 132 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS64, |
419 | u16 aml_resource_length, struct acpi_resource *resource) | 133 | ACPI_RS_SIZE(struct acpi_resource_address64), |
420 | { | 134 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address64)}, |
421 | 135 | ||
422 | ACPI_FUNCTION_TRACE("rs_get_address32"); | 136 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS64, |
137 | sizeof(struct aml_resource_address64), | ||
138 | 0}, | ||
423 | 139 | ||
424 | /* Get the Resource Type, general flags, and type-specific flags */ | 140 | /* Resource Type, General Flags, and Type-Specific Flags */ |
425 | 141 | ||
426 | if (!acpi_rs_get_address_common(resource, (void *)aml)) { | 142 | {ACPI_RSC_ADDRESS, 0, 0, 0}, |
427 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | ||
428 | } | ||
429 | 143 | ||
430 | /* | 144 | /* |
431 | * Get the following contiguous fields from the AML descriptor: | 145 | * These fields are contiguous in both the source and destination: |
432 | * Address Granularity | 146 | * Address Granularity |
433 | * Address Range Minimum | 147 | * Address Range Minimum |
434 | * Address Range Maximum | 148 | * Address Range Maximum |
435 | * Address Translation Offset | 149 | * Address Translation Offset |
436 | * Address Length | 150 | * Address Length |
437 | */ | 151 | */ |
438 | acpi_rs_move_data(&resource->data.address32.granularity, | 152 | {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.address64.granularity), |
439 | &aml->address32.granularity, 5, | 153 | AML_OFFSET(address64.granularity), |
440 | ACPI_MOVE_TYPE_32_TO_32); | 154 | 5}, |
441 | 155 | ||
442 | /* Get the optional resource_source (index and string) */ | 156 | /* Optional resource_source (Index and String) */ |
443 | 157 | ||
444 | resource->length = | 158 | {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address64.resource_source), |
445 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32) + | 159 | 0, |
446 | acpi_rs_get_resource_source(aml_resource_length, | 160 | sizeof(struct aml_resource_address64)} |
447 | sizeof(struct aml_resource_address32), | 161 | }; |
448 | &resource->data.address32. | ||
449 | resource_source, aml, NULL); | ||
450 | |||
451 | /* Complete the resource header */ | ||
452 | |||
453 | resource->type = ACPI_RESOURCE_TYPE_ADDRESS32; | ||
454 | return_ACPI_STATUS(AE_OK); | ||
455 | } | ||
456 | 162 | ||
457 | /******************************************************************************* | 163 | /******************************************************************************* |
458 | * | 164 | * |
459 | * FUNCTION: acpi_rs_set_address32 | 165 | * acpi_rs_convert_ext_address64 - All Extended (64-bit) address resources |
460 | * | ||
461 | * PARAMETERS: Resource - Pointer to the resource descriptor | ||
462 | * Aml - Where the AML descriptor is returned | ||
463 | * | ||
464 | * RETURN: Status | ||
465 | * | ||
466 | * DESCRIPTION: Convert an internal resource descriptor to the corresponding | ||
467 | * external AML resource descriptor. | ||
468 | * | 166 | * |
469 | ******************************************************************************/ | 167 | ******************************************************************************/ |
470 | 168 | ||
471 | acpi_status | 169 | struct acpi_rsconvert_info acpi_rs_convert_ext_address64[5] = { |
472 | acpi_rs_set_address32(struct acpi_resource *resource, union aml_resource *aml) | 170 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64, |
473 | { | 171 | ACPI_RS_SIZE(struct acpi_resource_extended_address64), |
474 | acpi_size descriptor_length; | 172 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_address64)}, |
173 | |||
174 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64, | ||
175 | sizeof(struct aml_resource_extended_address64), | ||
176 | 0}, | ||
475 | 177 | ||
476 | ACPI_FUNCTION_TRACE("rs_set_address32"); | 178 | /* Resource Type, General Flags, and Type-Specific Flags */ |
477 | 179 | ||
478 | /* Set the Resource Type, General Flags, and Type-Specific Flags */ | 180 | {ACPI_RSC_ADDRESS, 0, 0, 0}, |
479 | 181 | ||
480 | acpi_rs_set_address_common(aml, resource); | 182 | /* Revision ID */ |
481 | 183 | ||
184 | {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.ext_address64.revision_iD), | ||
185 | AML_OFFSET(ext_address64.revision_iD), | ||
186 | 1}, | ||
482 | /* | 187 | /* |
483 | * Set the following contiguous fields in the AML descriptor: | 188 | * These fields are contiguous in both the source and destination: |
484 | * Address Granularity | 189 | * Address Granularity |
485 | * Address Range Minimum | 190 | * Address Range Minimum |
486 | * Address Range Maximum | 191 | * Address Range Maximum |
487 | * Address Translation Offset | 192 | * Address Translation Offset |
488 | * Address Length | 193 | * Address Length |
194 | * Type-Specific Attribute | ||
489 | */ | 195 | */ |
490 | acpi_rs_move_data(&aml->address32.granularity, | 196 | {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.ext_address64.granularity), |
491 | &resource->data.address32.granularity, 5, | 197 | AML_OFFSET(ext_address64.granularity), |
492 | ACPI_MOVE_TYPE_32_TO_32); | 198 | 6} |
493 | 199 | }; | |
494 | /* Resource Source Index and Resource Source are optional */ | ||
495 | |||
496 | descriptor_length = acpi_rs_set_resource_source(aml, | ||
497 | sizeof(struct | ||
498 | aml_resource_address32), | ||
499 | &resource->data. | ||
500 | address32. | ||
501 | resource_source); | ||
502 | |||
503 | /* Complete the AML descriptor header */ | ||
504 | |||
505 | acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS32, | ||
506 | descriptor_length, aml); | ||
507 | return_ACPI_STATUS(AE_OK); | ||
508 | } | ||
509 | 200 | ||
510 | /******************************************************************************* | 201 | /******************************************************************************* |
511 | * | 202 | * |
512 | * FUNCTION: acpi_rs_get_address64 | 203 | * acpi_rs_convert_general_flags - Flags common to all address descriptors |
513 | * | ||
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 | ||
517 | * | ||
518 | * RETURN: Status | ||
519 | * | ||
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. | ||
523 | * | 204 | * |
524 | ******************************************************************************/ | 205 | ******************************************************************************/ |
525 | 206 | ||
526 | acpi_status | 207 | static struct acpi_rsconvert_info acpi_rs_convert_general_flags[6] = { |
527 | acpi_rs_get_address64(union aml_resource *aml, | 208 | {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.flags), |
528 | u16 aml_resource_length, struct acpi_resource *resource) | 209 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_general_flags)}, |
529 | { | ||
530 | ACPI_FUNCTION_TRACE("rs_get_address64"); | ||
531 | 210 | ||
532 | /* Get the Resource Type, general Flags, and type-specific Flags */ | 211 | /* Resource Type (Memory, Io, bus_number, etc.) */ |
533 | 212 | ||
534 | if (!acpi_rs_get_address_common(resource, aml)) { | 213 | {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.address.resource_type), |
535 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | 214 | AML_OFFSET(address.resource_type), |
536 | } | 215 | 1}, |
537 | 216 | ||
538 | /* | 217 | /* General Flags - Consume, Decode, min_fixed, max_fixed */ |
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 | ||
544 | * Address Length | ||
545 | */ | ||
546 | acpi_rs_move_data(&resource->data.address64.granularity, | ||
547 | &aml->address64.granularity, 5, | ||
548 | ACPI_MOVE_TYPE_64_TO_64); | ||
549 | 218 | ||
550 | /* Get the optional resource_source (index and string) */ | 219 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.producer_consumer), |
220 | AML_OFFSET(address.flags), | ||
221 | 0}, | ||
551 | 222 | ||
552 | resource->length = | 223 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.decode), |
553 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64) + | 224 | AML_OFFSET(address.flags), |
554 | acpi_rs_get_resource_source(aml_resource_length, | 225 | 1}, |
555 | sizeof(struct aml_resource_address64), | ||
556 | &resource->data.address64. | ||
557 | resource_source, aml, NULL); | ||
558 | 226 | ||
559 | /* Complete the resource header */ | 227 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.min_address_fixed), |
228 | AML_OFFSET(address.flags), | ||
229 | 2}, | ||
560 | 230 | ||
561 | resource->type = ACPI_RESOURCE_TYPE_ADDRESS64; | 231 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.max_address_fixed), |
562 | return_ACPI_STATUS(AE_OK); | 232 | AML_OFFSET(address.flags), |
563 | } | 233 | 3} |
234 | }; | ||
564 | 235 | ||
565 | /******************************************************************************* | 236 | /******************************************************************************* |
566 | * | 237 | * |
567 | * FUNCTION: acpi_rs_set_address64 | 238 | * acpi_rs_convert_mem_flags - Flags common to Memory address descriptors |
568 | * | ||
569 | * PARAMETERS: Resource - Pointer to the resource descriptor | ||
570 | * Aml - Where the AML descriptor is returned | ||
571 | * | ||
572 | * RETURN: Status | ||
573 | * | ||
574 | * DESCRIPTION: Convert an internal resource descriptor to the corresponding | ||
575 | * external AML resource descriptor. | ||
576 | * | 239 | * |
577 | ******************************************************************************/ | 240 | ******************************************************************************/ |
578 | 241 | ||
579 | acpi_status | 242 | static struct acpi_rsconvert_info acpi_rs_convert_mem_flags[5] = { |
580 | acpi_rs_set_address64(struct acpi_resource *resource, union aml_resource *aml) | 243 | {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags), |
581 | { | 244 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_mem_flags)}, |
582 | acpi_size descriptor_length; | ||
583 | 245 | ||
584 | ACPI_FUNCTION_TRACE("rs_set_address64"); | 246 | /* Memory-specific flags */ |
585 | 247 | ||
586 | /* Set the Resource Type, General Flags, and Type-Specific Flags */ | 248 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.write_protect), |
249 | AML_OFFSET(address.specific_flags), | ||
250 | 0}, | ||
587 | 251 | ||
588 | acpi_rs_set_address_common(aml, resource); | 252 | {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.caching), |
253 | AML_OFFSET(address.specific_flags), | ||
254 | 1}, | ||
589 | 255 | ||
590 | /* | 256 | {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.range_type), |
591 | * Set the following contiguous fields in the AML descriptor: | 257 | AML_OFFSET(address.specific_flags), |
592 | * Address Granularity | 258 | 3}, |
593 | * Address Range Minimum | 259 | |
594 | * Address Range Maximum | 260 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.translation), |
595 | * Address Translation Offset | 261 | AML_OFFSET(address.specific_flags), |
596 | * Address Length | 262 | 5} |
597 | */ | 263 | }; |
598 | acpi_rs_move_data(&aml->address64.granularity, | 264 | |
599 | &resource->data.address64.granularity, 5, | 265 | /******************************************************************************* |
600 | ACPI_MOVE_TYPE_64_TO_64); | 266 | * |
267 | * acpi_rs_convert_io_flags - Flags common to I/O address descriptors | ||
268 | * | ||
269 | ******************************************************************************/ | ||
601 | 270 | ||
602 | /* Resource Source Index and Resource Source are optional */ | 271 | static struct acpi_rsconvert_info acpi_rs_convert_io_flags[4] = { |
272 | {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags), | ||
273 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io_flags)}, | ||
603 | 274 | ||
604 | descriptor_length = acpi_rs_set_resource_source(aml, | 275 | /* I/O-specific flags */ |
605 | sizeof(struct | ||
606 | aml_resource_address64), | ||
607 | &resource->data. | ||
608 | address64. | ||
609 | resource_source); | ||
610 | 276 | ||
611 | /* Complete the AML descriptor header */ | 277 | {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.io.range_type), |
278 | AML_OFFSET(address.specific_flags), | ||
279 | 0}, | ||
612 | 280 | ||
613 | acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS64, | 281 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.io.translation), |
614 | descriptor_length, aml); | 282 | AML_OFFSET(address.specific_flags), |
615 | return_ACPI_STATUS(AE_OK); | 283 | 4}, |
616 | } | 284 | |
285 | {ACPI_RSC_1BITFLAG, | ||
286 | ACPI_RS_OFFSET(data.address.info.io.translation_type), | ||
287 | AML_OFFSET(address.specific_flags), | ||
288 | 5} | ||
289 | }; | ||
617 | 290 | ||
618 | /******************************************************************************* | 291 | /******************************************************************************* |
619 | * | 292 | * |
620 | * FUNCTION: acpi_rs_get_ext_address64 | 293 | * FUNCTION: acpi_rs_get_address_common |
621 | * | 294 | * |
622 | * PARAMETERS: Aml - Pointer to the AML resource descriptor | 295 | * PARAMETERS: Resource - Pointer to the internal resource struct |
623 | * aml_resource_length - Length of the resource from the AML header | 296 | * Aml - Pointer to the AML resource descriptor |
624 | * Resource - Where the internal resource is returned | ||
625 | * | 297 | * |
626 | * RETURN: Status | 298 | * RETURN: TRUE if the resource_type field is OK, FALSE otherwise |
627 | * | 299 | * |
628 | * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding | 300 | * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor |
629 | * internal resource descriptor, simplifying bitflags and handling | 301 | * to an internal resource descriptor |
630 | * alignment and endian issues if necessary. | ||
631 | * | 302 | * |
632 | ******************************************************************************/ | 303 | ******************************************************************************/ |
633 | 304 | ||
634 | acpi_status | 305 | u8 |
635 | acpi_rs_get_ext_address64(union aml_resource *aml, | 306 | acpi_rs_get_address_common(struct acpi_resource *resource, |
636 | u16 aml_resource_length, | 307 | union aml_resource *aml) |
637 | struct acpi_resource *resource) | ||
638 | { | 308 | { |
309 | ACPI_FUNCTION_ENTRY(); | ||
639 | 310 | ||
640 | ACPI_FUNCTION_TRACE("rs_get_ext_address64"); | 311 | /* Validate the Resource Type */ |
641 | |||
642 | /* Get the Resource Type, general flags, and type-specific flags */ | ||
643 | 312 | ||
644 | if (!acpi_rs_get_address_common(resource, aml)) { | 313 | if ((aml->address.resource_type > 2) |
645 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | 314 | && (aml->address.resource_type < 0xC0)) { |
315 | return (FALSE); | ||
646 | } | 316 | } |
647 | 317 | ||
648 | /* | 318 | /* Get the Resource Type and General Flags */ |
649 | * Get and validate the Revision ID | ||
650 | * Note: Only one revision ID is currently supported | ||
651 | */ | ||
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); | ||
657 | } | ||
658 | 319 | ||
659 | /* | 320 | (void)acpi_rs_convert_aml_to_resource(resource, aml, |
660 | * Get the following contiguous fields from the AML descriptor: | 321 | acpi_rs_convert_general_flags); |
661 | * Address Granularity | 322 | |
662 | * Address Range Minimum | 323 | /* Get the Type-Specific Flags (Memory and I/O descriptors only) */ |
663 | * Address Range Maximum | ||
664 | * Address Translation Offset | ||
665 | * Address Length | ||
666 | * Type-Specific Attribute | ||
667 | */ | ||
668 | acpi_rs_move_data(&resource->data.ext_address64.granularity, | ||
669 | &aml->ext_address64.granularity, 6, | ||
670 | ACPI_MOVE_TYPE_64_TO_64); | ||
671 | 324 | ||
672 | /* Complete the resource header */ | 325 | if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) { |
326 | (void)acpi_rs_convert_aml_to_resource(resource, aml, | ||
327 | acpi_rs_convert_mem_flags); | ||
328 | } else if (resource->data.address.resource_type == ACPI_IO_RANGE) { | ||
329 | (void)acpi_rs_convert_aml_to_resource(resource, aml, | ||
330 | acpi_rs_convert_io_flags); | ||
331 | } else { | ||
332 | /* Generic resource type, just grab the type_specific byte */ | ||
673 | 333 | ||
674 | resource->type = ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64; | 334 | resource->data.address.info.type_specific = |
675 | resource->length = | 335 | aml->address.specific_flags; |
676 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_extended_address64); | 336 | } |
677 | return_ACPI_STATUS(AE_OK); | 337 | |
338 | return (TRUE); | ||
678 | } | 339 | } |
679 | 340 | ||
680 | /******************************************************************************* | 341 | /******************************************************************************* |
681 | * | 342 | * |
682 | * FUNCTION: acpi_rs_set_ext_address64 | 343 | * FUNCTION: acpi_rs_set_address_common |
683 | * | 344 | * |
684 | * PARAMETERS: Resource - Pointer to the resource descriptor | 345 | * PARAMETERS: Aml - Pointer to the AML resource descriptor |
685 | * Aml - Where the AML descriptor is returned | 346 | * Resource - Pointer to the internal resource struct |
686 | * | 347 | * |
687 | * RETURN: Status | 348 | * RETURN: None |
688 | * | 349 | * |
689 | * DESCRIPTION: Convert an internal resource descriptor to the corresponding | 350 | * DESCRIPTION: Convert common flag fields from a resource descriptor to an |
690 | * external AML resource descriptor. | 351 | * AML descriptor |
691 | * | 352 | * |
692 | ******************************************************************************/ | 353 | ******************************************************************************/ |
693 | 354 | ||
694 | acpi_status | 355 | void |
695 | acpi_rs_set_ext_address64(struct acpi_resource *resource, | 356 | acpi_rs_set_address_common(union aml_resource *aml, |
696 | union aml_resource *aml) | 357 | struct acpi_resource *resource) |
697 | { | 358 | { |
698 | ACPI_FUNCTION_TRACE("rs_set_ext_address64"); | 359 | ACPI_FUNCTION_ENTRY(); |
699 | 360 | ||
700 | /* Set the Resource Type, General Flags, and Type-Specific Flags */ | 361 | /* Set the Resource Type and General Flags */ |
701 | 362 | ||
702 | acpi_rs_set_address_common(aml, resource); | 363 | (void)acpi_rs_convert_resource_to_aml(resource, aml, |
364 | acpi_rs_convert_general_flags); | ||
703 | 365 | ||
704 | /* Only one Revision ID is currently supported */ | 366 | /* Set the Type-Specific Flags (Memory and I/O descriptors only) */ |
705 | 367 | ||
706 | aml->ext_address64.revision_iD = AML_RESOURCE_EXTENDED_ADDRESS_REVISION; | 368 | if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) { |
707 | aml->ext_address64.reserved = 0; | 369 | (void)acpi_rs_convert_resource_to_aml(resource, aml, |
370 | acpi_rs_convert_mem_flags); | ||
371 | } else if (resource->data.address.resource_type == ACPI_IO_RANGE) { | ||
372 | (void)acpi_rs_convert_resource_to_aml(resource, aml, | ||
373 | acpi_rs_convert_io_flags); | ||
374 | } else { | ||
375 | /* Generic resource type, just copy the type_specific byte */ | ||
708 | 376 | ||
709 | /* | 377 | aml->address.specific_flags = |
710 | * Set the following contiguous fields in the AML descriptor: | 378 | resource->data.address.info.type_specific; |
711 | * Address Granularity | 379 | } |
712 | * Address Range Minimum | ||
713 | * Address Range Maximum | ||
714 | * Address Translation Offset | ||
715 | * Address Length | ||
716 | * Type-Specific Attribute | ||
717 | */ | ||
718 | acpi_rs_move_data(&aml->ext_address64.granularity, | ||
719 | &resource->data.address64.granularity, 6, | ||
720 | ACPI_MOVE_TYPE_64_TO_64); | ||
721 | |||
722 | /* Complete the AML descriptor header */ | ||
723 | |||
724 | acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64, | ||
725 | sizeof(struct | ||
726 | aml_resource_extended_address64), | ||
727 | aml); | ||
728 | return_ACPI_STATUS(AE_OK); | ||
729 | } | 380 | } |