diff options
Diffstat (limited to 'drivers/acpi/resources/rsaddr.c')
-rw-r--r-- | drivers/acpi/resources/rsaddr.c | 1132 |
1 files changed, 376 insertions, 756 deletions
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c index 798778261fb9..6f48ebf3304e 100644 --- a/drivers/acpi/resources/rsaddr.c +++ b/drivers/acpi/resources/rsaddr.c | |||
@@ -58,12 +58,20 @@ acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags); | |||
58 | 58 | ||
59 | static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource); | 59 | static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource); |
60 | 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 | |||
61 | /******************************************************************************* | 69 | /******************************************************************************* |
62 | * | 70 | * |
63 | * FUNCTION: acpi_rs_decode_general_flags | 71 | * FUNCTION: acpi_rs_decode_general_flags |
64 | * | 72 | * |
65 | * PARAMETERS: Resource - Address resource data struct | 73 | * PARAMETERS: Resource - Address resource data struct |
66 | * Flags - Actual flag byte | 74 | * Flags - Raw AML flag byte |
67 | * | 75 | * |
68 | * RETURN: Decoded flag bits in resource struct | 76 | * RETURN: Decoded flag bits in resource struct |
69 | * | 77 | * |
@@ -107,27 +115,19 @@ acpi_rs_decode_general_flags(union acpi_resource_data *resource, u8 flags) | |||
107 | 115 | ||
108 | static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource) | 116 | static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource) |
109 | { | 117 | { |
110 | u8 flags; | ||
111 | |||
112 | ACPI_FUNCTION_ENTRY(); | 118 | ACPI_FUNCTION_ENTRY(); |
113 | 119 | ||
114 | /* Producer / Consumer - flag bit[0] */ | 120 | return ((u8) |
115 | 121 | ||
116 | flags = (u8) (resource->address.producer_consumer & 0x01); | 122 | /* Producer / Consumer - flag bit[0] */ |
117 | 123 | ((resource->address.producer_consumer & 0x01) | | |
118 | /* Decode (_DEC) - flag bit[1] */ | 124 | /* Decode (_DEC) - flag bit[1] */ |
119 | 125 | ((resource->address.decode & 0x01) << 1) | | |
120 | flags |= (u8) ((resource->address.decode & 0x01) << 1); | 126 | /* Min Address Fixed (_MIF) - flag bit[2] */ |
121 | 127 | ((resource->address.min_address_fixed & 0x01) << 2) | | |
122 | /* Min Address Fixed (_MIF) - flag bit[2] */ | 128 | /* Max Address Fixed (_MAF) - flag bit[3] */ |
123 | 129 | ((resource->address.max_address_fixed & 0x01) << 3)) | |
124 | flags |= (u8) ((resource->address.min_address_fixed & 0x01) << 2); | 130 | ); |
125 | |||
126 | /* Max Address Fixed (_MAF) - flag bit[3] */ | ||
127 | |||
128 | flags |= (u8) ((resource->address.max_address_fixed & 0x01) << 3); | ||
129 | |||
130 | return (flags); | ||
131 | } | 131 | } |
132 | 132 | ||
133 | /******************************************************************************* | 133 | /******************************************************************************* |
@@ -135,7 +135,7 @@ static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource) | |||
135 | * FUNCTION: acpi_rs_decode_specific_flags | 135 | * FUNCTION: acpi_rs_decode_specific_flags |
136 | * | 136 | * |
137 | * PARAMETERS: Resource - Address resource data struct | 137 | * PARAMETERS: Resource - Address resource data struct |
138 | * Flags - Actual flag byte | 138 | * Flags - Raw AML flag byte |
139 | * | 139 | * |
140 | * RETURN: Decoded flag bits in attribute struct | 140 | * RETURN: Decoded flag bits in attribute struct |
141 | * | 141 | * |
@@ -189,921 +189,541 @@ acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags) | |||
189 | 189 | ||
190 | static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource) | 190 | static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource) |
191 | { | 191 | { |
192 | u8 flags = 0; | ||
193 | |||
194 | ACPI_FUNCTION_ENTRY(); | 192 | ACPI_FUNCTION_ENTRY(); |
195 | 193 | ||
196 | if (resource->address.resource_type == ACPI_MEMORY_RANGE) { | 194 | if (resource->address.resource_type == ACPI_MEMORY_RANGE) { |
197 | /* Write Status (_RW) - flag bit[0] */ | 195 | return ((u8) |
198 | 196 | ||
199 | flags = (u8) | 197 | /* Write Status (_RW) - flag bit[0] */ |
200 | (resource->address.attribute.memory. | 198 | ((resource->address.attribute.memory. |
201 | read_write_attribute & 0x01); | 199 | read_write_attribute & 0x01) | |
202 | 200 | /* Memory Attributes (_MEM) - flag bits[2:1] */ | |
203 | /* Memory Attributes (_MEM) - flag bits[2:1] */ | 201 | ((resource->address.attribute.memory. |
204 | 202 | cache_attribute & 0x03) << 1))); | |
205 | flags |= (u8) | ||
206 | ((resource->address.attribute.memory. | ||
207 | cache_attribute & 0x03) << 1); | ||
208 | } else if (resource->address.resource_type == ACPI_IO_RANGE) { | 203 | } else if (resource->address.resource_type == ACPI_IO_RANGE) { |
209 | /* Ranges (_RNG) - flag bits[1:0] */ | 204 | return ((u8) |
210 | 205 | ||
211 | flags = (u8) | 206 | /* Ranges (_RNG) - flag bits[1:0] */ |
212 | (resource->address.attribute.io.range_attribute & 0x03); | 207 | ((resource->address.attribute.io. |
213 | 208 | range_attribute & 0x03) | | |
214 | /* Translations (_TTP and _TRS) - flag bits[5:4] */ | 209 | /* Translations (_TTP and _TRS) - flag bits[5:4] */ |
215 | 210 | ((resource->address.attribute.io. | |
216 | flags |= (u8) | 211 | translation_attribute & 0x03) << 4))); |
217 | ((resource->address.attribute.io. | ||
218 | translation_attribute & 0x03) << 4); | ||
219 | } | 212 | } |
220 | 213 | ||
221 | return (flags); | 214 | return (0); |
222 | } | 215 | } |
223 | 216 | ||
224 | /******************************************************************************* | 217 | /******************************************************************************* |
225 | * | 218 | * |
226 | * FUNCTION: acpi_rs_address16_resource | 219 | * FUNCTION: acpi_rs_set_address_common |
227 | * | 220 | * |
228 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | 221 | * PARAMETERS: Aml - Pointer to the AML resource descriptor |
229 | * stream | 222 | * Resource - Pointer to the internal resource struct |
230 | * bytes_consumed - Pointer to where the number of bytes | ||
231 | * consumed the byte_stream_buffer is | ||
232 | * returned | ||
233 | * output_buffer - Pointer to the return data buffer | ||
234 | * structure_size - Pointer to where the number of bytes | ||
235 | * in the return data struct is returned | ||
236 | * | 223 | * |
237 | * RETURN: Status | 224 | * RETURN: None |
238 | * | 225 | * |
239 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | 226 | * DESCRIPTION: Convert common flag fields from a resource descriptor to an |
240 | * structure pointed to by the output_buffer. Return the | 227 | * AML descriptor |
241 | * number of bytes consumed from the byte stream. | ||
242 | * | 228 | * |
243 | ******************************************************************************/ | 229 | ******************************************************************************/ |
244 | 230 | ||
245 | acpi_status | 231 | static void |
246 | acpi_rs_address16_resource(u8 * byte_stream_buffer, | 232 | acpi_rs_set_address_common(union aml_resource *aml, |
247 | acpi_size * bytes_consumed, | 233 | struct acpi_resource *resource) |
248 | u8 ** output_buffer, acpi_size * structure_size) | ||
249 | { | 234 | { |
250 | u32 index; | 235 | ACPI_FUNCTION_ENTRY(); |
251 | u16 temp16; | ||
252 | u8 temp8; | ||
253 | u8 *temp_ptr; | ||
254 | u8 *buffer = byte_stream_buffer; | ||
255 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
256 | acpi_size struct_size = | ||
257 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16); | ||
258 | 236 | ||
259 | ACPI_FUNCTION_TRACE("rs_address16_resource"); | 237 | /* Set the Resource Type (Memory, Io, bus_number, etc.) */ |
260 | 238 | ||
261 | /* Get the Descriptor Length field */ | 239 | aml->address.resource_type = (u8) resource->data.address.resource_type; |
262 | 240 | ||
263 | buffer += 1; | 241 | /* Set the general flags */ |
264 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
265 | 242 | ||
266 | /* Validate minimum descriptor length */ | 243 | aml->address.flags = acpi_rs_encode_general_flags(&resource->data); |
267 | 244 | ||
268 | if (temp16 < 13) { | 245 | /* Set the type-specific flags */ |
269 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); | ||
270 | } | ||
271 | 246 | ||
272 | *bytes_consumed = temp16 + 3; | 247 | aml->address.specific_flags = |
273 | output_struct->type = ACPI_RSTYPE_ADDRESS16; | 248 | acpi_rs_encode_specific_flags(&resource->data); |
249 | } | ||
274 | 250 | ||
275 | /* Get the Resource Type (Byte3) */ | 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 | ******************************************************************************/ | ||
276 | 264 | ||
277 | buffer += 2; | 265 | static u8 |
278 | temp8 = *buffer; | 266 | acpi_rs_get_address_common(struct acpi_resource *resource, |
267 | union aml_resource *aml) | ||
268 | { | ||
269 | ACPI_FUNCTION_ENTRY(); | ||
279 | 270 | ||
280 | /* Values 0-2 and 0xC0-0xFF are valid */ | 271 | /* Validate resource type */ |
281 | 272 | ||
282 | if ((temp8 > 2) && (temp8 < 0xC0)) { | 273 | if ((aml->address.resource_type > 2) |
283 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | 274 | && (aml->address.resource_type < 0xC0)) { |
275 | return (FALSE); | ||
284 | } | 276 | } |
285 | 277 | ||
286 | output_struct->data.address16.resource_type = temp8; | 278 | /* Get the Resource Type (Memory, Io, bus_number, etc.) */ |
287 | |||
288 | /* Get the General Flags (Byte4) */ | ||
289 | |||
290 | buffer += 1; | ||
291 | acpi_rs_decode_general_flags(&output_struct->data, *buffer); | ||
292 | |||
293 | /* Get the Type Specific Flags (Byte5) */ | ||
294 | |||
295 | buffer += 1; | ||
296 | acpi_rs_decode_specific_flags(&output_struct->data, *buffer); | ||
297 | |||
298 | /* Get Granularity (Bytes 6-7) */ | ||
299 | |||
300 | buffer += 1; | ||
301 | ACPI_MOVE_16_TO_32(&output_struct->data.address16.granularity, buffer); | ||
302 | 279 | ||
303 | /* Get min_address_range (Bytes 8-9) */ | 280 | resource->data.address.resource_type = aml->address.resource_type; |
304 | 281 | ||
305 | buffer += 2; | 282 | /* Get the General Flags */ |
306 | ACPI_MOVE_16_TO_32(&output_struct->data.address16.min_address_range, | ||
307 | buffer); | ||
308 | 283 | ||
309 | /* Get max_address_range (Bytes 10-11) */ | 284 | acpi_rs_decode_general_flags(&resource->data, aml->address.flags); |
310 | 285 | ||
311 | buffer += 2; | 286 | /* Get the Type-Specific Flags */ |
312 | ACPI_MOVE_16_TO_32(&output_struct->data.address16.max_address_range, | ||
313 | buffer); | ||
314 | 287 | ||
315 | /* Get address_translation_offset (Bytes 12-13) */ | 288 | acpi_rs_decode_specific_flags(&resource->data, |
316 | 289 | aml->address.specific_flags); | |
317 | buffer += 2; | 290 | return (TRUE); |
318 | ACPI_MOVE_16_TO_32(&output_struct->data.address16. | 291 | } |
319 | address_translation_offset, buffer); | ||
320 | 292 | ||
321 | /* Get address_length (Bytes 14-15) */ | 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 | ******************************************************************************/ | ||
322 | 308 | ||
323 | buffer += 2; | 309 | acpi_status |
324 | ACPI_MOVE_16_TO_32(&output_struct->data.address16.address_length, | 310 | acpi_rs_get_address16(union aml_resource * aml, |
325 | buffer); | 311 | u16 aml_resource_length, struct acpi_resource * resource) |
312 | { | ||
313 | ACPI_FUNCTION_TRACE("rs_get_address16"); | ||
326 | 314 | ||
327 | /* Resource Source Index (if present) */ | 315 | /* Get the Resource Type, general flags, and type-specific flags */ |
328 | 316 | ||
329 | buffer += 2; | 317 | if (!acpi_rs_get_address_common(resource, aml)) { |
318 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | ||
319 | } | ||
330 | 320 | ||
331 | /* | 321 | /* |
332 | * This will leave us pointing to the Resource Source Index | 322 | * Get the following contiguous fields from the AML descriptor: |
333 | * If it is present, then save it off and calculate the | 323 | * Address Granularity |
334 | * pointer to where the null terminated string goes: | 324 | * Address Range Minimum |
335 | * Each Interrupt takes 32-bits + the 5 bytes of the | 325 | * Address Range Maximum |
336 | * stream that are default. | 326 | * Address Translation Offset |
337 | * | 327 | * Address Length |
338 | * Note: Some resource descriptors will have an additional null, so | ||
339 | * we add 1 to the length. | ||
340 | */ | 328 | */ |
341 | if (*bytes_consumed > (16 + 1)) { | 329 | acpi_rs_move_data(&resource->data.address16.granularity, |
342 | /* Dereference the Index */ | 330 | &aml->address16.granularity, 5, |
343 | 331 | ACPI_MOVE_TYPE_16_TO_32); | |
344 | output_struct->data.address16.resource_source.index = | ||
345 | (u32) * buffer; | ||
346 | |||
347 | /* Point to the String */ | ||
348 | 332 | ||
349 | buffer += 1; | 333 | /* Get the optional resource_source (index and string) */ |
350 | 334 | ||
351 | /* Point the String pointer to the end of this structure */ | 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); | ||
352 | 341 | ||
353 | output_struct->data.address16.resource_source.string_ptr = | 342 | /* Complete the resource header */ |
354 | (char *)((u8 *) output_struct + struct_size); | ||
355 | 343 | ||
356 | temp_ptr = (u8 *) | 344 | resource->type = ACPI_RESOURCE_TYPE_ADDRESS16; |
357 | output_struct->data.address16.resource_source.string_ptr; | ||
358 | |||
359 | /* Copy the resource_source string into the buffer */ | ||
360 | |||
361 | index = 0; | ||
362 | while (*buffer) { | ||
363 | *temp_ptr = *buffer; | ||
364 | |||
365 | temp_ptr++; | ||
366 | buffer++; | ||
367 | index++; | ||
368 | } | ||
369 | |||
370 | /* Add the terminating null and set the string length */ | ||
371 | |||
372 | *temp_ptr = 0; | ||
373 | output_struct->data.address16.resource_source.string_length = | ||
374 | index + 1; | ||
375 | |||
376 | /* | ||
377 | * In order for the struct_size to fall on a 32-bit boundary, | ||
378 | * calculate the length of the string and expand the | ||
379 | * struct_size to the next 32-bit boundary. | ||
380 | */ | ||
381 | temp8 = (u8) (index + 1); | ||
382 | struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); | ||
383 | } else { | ||
384 | output_struct->data.address16.resource_source.index = 0; | ||
385 | output_struct->data.address16.resource_source.string_length = 0; | ||
386 | output_struct->data.address16.resource_source.string_ptr = NULL; | ||
387 | } | ||
388 | |||
389 | /* Set the Length parameter */ | ||
390 | |||
391 | output_struct->length = (u32) struct_size; | ||
392 | |||
393 | /* Return the final size of the structure */ | ||
394 | |||
395 | *structure_size = struct_size; | ||
396 | return_ACPI_STATUS(AE_OK); | 345 | return_ACPI_STATUS(AE_OK); |
397 | } | 346 | } |
398 | 347 | ||
399 | /******************************************************************************* | 348 | /******************************************************************************* |
400 | * | 349 | * |
401 | * FUNCTION: acpi_rs_address16_stream | 350 | * FUNCTION: acpi_rs_set_address16 |
402 | * | 351 | * |
403 | * PARAMETERS: Resource - Pointer to the resource linked list | 352 | * PARAMETERS: Resource - Pointer to the resource descriptor |
404 | * output_buffer - Pointer to the user's return buffer | 353 | * Aml - Where the AML descriptor is returned |
405 | * bytes_consumed - Pointer to where the number of bytes | ||
406 | * used in the output_buffer is returned | ||
407 | * | 354 | * |
408 | * RETURN: Status | 355 | * RETURN: Status |
409 | * | 356 | * |
410 | * DESCRIPTION: Take the linked list resource structure and fills in the | 357 | * DESCRIPTION: Convert an internal resource descriptor to the corresponding |
411 | * the appropriate bytes in a byte stream | 358 | * external AML resource descriptor. |
412 | * | 359 | * |
413 | ******************************************************************************/ | 360 | ******************************************************************************/ |
414 | 361 | ||
415 | acpi_status | 362 | acpi_status |
416 | acpi_rs_address16_stream(struct acpi_resource *resource, | 363 | acpi_rs_set_address16(struct acpi_resource *resource, union aml_resource *aml) |
417 | u8 ** output_buffer, acpi_size * bytes_consumed) | ||
418 | { | 364 | { |
419 | u8 *buffer = *output_buffer; | 365 | acpi_size descriptor_length; |
420 | u8 *length_field; | ||
421 | acpi_size actual_bytes; | ||
422 | |||
423 | ACPI_FUNCTION_TRACE("rs_address16_stream"); | ||
424 | |||
425 | /* Set the Descriptor Type field */ | ||
426 | 366 | ||
427 | *buffer = ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE; | 367 | ACPI_FUNCTION_TRACE("rs_set_address16"); |
428 | buffer += 1; | ||
429 | 368 | ||
430 | /* Save a pointer to the Length field - to be filled in later */ | 369 | /* Set the Resource Type, General Flags, and Type-Specific Flags */ |
431 | 370 | ||
432 | length_field = buffer; | 371 | acpi_rs_set_address_common(aml, resource); |
433 | buffer += 2; | ||
434 | |||
435 | /* Set the Resource Type (Memory, Io, bus_number) */ | ||
436 | |||
437 | *buffer = (u8) (resource->data.address16.resource_type & 0x03); | ||
438 | buffer += 1; | ||
439 | |||
440 | /* Set the general flags */ | ||
441 | 372 | ||
442 | *buffer = acpi_rs_encode_general_flags(&resource->data); | 373 | /* |
443 | buffer += 1; | 374 | * Set the following contiguous fields in the AML descriptor: |
444 | 375 | * Address Granularity | |
445 | /* Set the type specific flags */ | 376 | * Address Range Minimum |
446 | 377 | * Address Range Maximum | |
447 | *buffer = acpi_rs_encode_specific_flags(&resource->data); | 378 | * Address Translation Offset |
448 | buffer += 1; | 379 | * Address Length |
449 | 380 | */ | |
450 | /* Set the address space granularity */ | 381 | acpi_rs_move_data(&aml->address16.granularity, |
451 | 382 | &resource->data.address16.granularity, 5, | |
452 | ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.granularity); | 383 | ACPI_MOVE_TYPE_32_TO_16); |
453 | buffer += 2; | ||
454 | |||
455 | /* Set the address range minimum */ | ||
456 | |||
457 | ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.min_address_range); | ||
458 | buffer += 2; | ||
459 | |||
460 | /* Set the address range maximum */ | ||
461 | |||
462 | ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.max_address_range); | ||
463 | buffer += 2; | ||
464 | |||
465 | /* Set the address translation offset */ | ||
466 | |||
467 | ACPI_MOVE_32_TO_16(buffer, | ||
468 | &resource->data.address16. | ||
469 | address_translation_offset); | ||
470 | buffer += 2; | ||
471 | |||
472 | /* Set the address length */ | ||
473 | |||
474 | ACPI_MOVE_32_TO_16(buffer, &resource->data.address16.address_length); | ||
475 | buffer += 2; | ||
476 | 384 | ||
477 | /* Resource Source Index and Resource Source are optional */ | 385 | /* Resource Source Index and Resource Source are optional */ |
478 | 386 | ||
479 | if (resource->data.address16.resource_source.string_length) { | 387 | descriptor_length = acpi_rs_set_resource_source(aml, |
480 | *buffer = (u8) resource->data.address16.resource_source.index; | 388 | sizeof(struct |
481 | buffer += 1; | 389 | aml_resource_address16), |
390 | &resource->data. | ||
391 | address16. | ||
392 | resource_source); | ||
482 | 393 | ||
483 | /* Copy the resource_source string */ | 394 | /* Complete the AML descriptor header */ |
484 | 395 | ||
485 | ACPI_STRCPY((char *)buffer, | 396 | acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS16, |
486 | resource->data.address16.resource_source. | 397 | descriptor_length, aml); |
487 | string_ptr); | ||
488 | |||
489 | /* | ||
490 | * Buffer needs to be set to the length of the string + one for the | ||
491 | * terminating null | ||
492 | */ | ||
493 | buffer += | ||
494 | (acpi_size) (ACPI_STRLEN | ||
495 | (resource->data.address16.resource_source. | ||
496 | string_ptr) + 1); | ||
497 | } | ||
498 | |||
499 | /* Return the number of bytes consumed in this operation */ | ||
500 | |||
501 | actual_bytes = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
502 | *bytes_consumed = actual_bytes; | ||
503 | |||
504 | /* | ||
505 | * Set the length field to the number of bytes consumed | ||
506 | * minus the header size (3 bytes) | ||
507 | */ | ||
508 | actual_bytes -= 3; | ||
509 | ACPI_MOVE_SIZE_TO_16(length_field, &actual_bytes); | ||
510 | return_ACPI_STATUS(AE_OK); | 398 | return_ACPI_STATUS(AE_OK); |
511 | } | 399 | } |
512 | 400 | ||
513 | /******************************************************************************* | 401 | /******************************************************************************* |
514 | * | 402 | * |
515 | * FUNCTION: acpi_rs_address32_resource | 403 | * FUNCTION: acpi_rs_get_address32 |
516 | * | 404 | * |
517 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | 405 | * PARAMETERS: Aml - Pointer to the AML resource descriptor |
518 | * stream | 406 | * aml_resource_length - Length of the resource from the AML header |
519 | * bytes_consumed - Pointer to where the number of bytes | 407 | * Resource - Where the internal resource is returned |
520 | * consumed the byte_stream_buffer is | ||
521 | * returned | ||
522 | * output_buffer - Pointer to the return data buffer | ||
523 | * structure_size - Pointer to where the number of bytes | ||
524 | * in the return data struct is returned | ||
525 | * | 408 | * |
526 | * RETURN: Status | 409 | * RETURN: Status |
527 | * | 410 | * |
528 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | 411 | * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding |
529 | * structure pointed to by the output_buffer. Return the | 412 | * internal resource descriptor, simplifying bitflags and handling |
530 | * number of bytes consumed from the byte stream. | 413 | * alignment and endian issues if necessary. |
531 | * | 414 | * |
532 | ******************************************************************************/ | 415 | ******************************************************************************/ |
533 | 416 | ||
534 | acpi_status | 417 | acpi_status |
535 | acpi_rs_address32_resource(u8 * byte_stream_buffer, | 418 | acpi_rs_get_address32(union aml_resource *aml, |
536 | acpi_size * bytes_consumed, | 419 | u16 aml_resource_length, struct acpi_resource *resource) |
537 | u8 ** output_buffer, acpi_size * structure_size) | ||
538 | { | 420 | { |
539 | u16 temp16; | ||
540 | u8 temp8; | ||
541 | u8 *temp_ptr; | ||
542 | u32 index; | ||
543 | u8 *buffer = byte_stream_buffer; | ||
544 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
545 | acpi_size struct_size = | ||
546 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32); | ||
547 | |||
548 | ACPI_FUNCTION_TRACE("rs_address32_resource"); | ||
549 | |||
550 | /* Get the Descriptor Length field */ | ||
551 | |||
552 | buffer += 1; | ||
553 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
554 | 421 | ||
555 | /* Validate minimum descriptor length */ | 422 | ACPI_FUNCTION_TRACE("rs_get_address32"); |
556 | 423 | ||
557 | if (temp16 < 23) { | 424 | /* Get the Resource Type, general flags, and type-specific flags */ |
558 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); | ||
559 | } | ||
560 | |||
561 | *bytes_consumed = temp16 + 3; | ||
562 | output_struct->type = ACPI_RSTYPE_ADDRESS32; | ||
563 | |||
564 | /* Get the Resource Type (Byte3) */ | ||
565 | |||
566 | buffer += 2; | ||
567 | temp8 = *buffer; | ||
568 | 425 | ||
569 | /* Values 0-2 and 0xC0-0xFF are valid */ | 426 | if (!acpi_rs_get_address_common(resource, (void *)aml)) { |
570 | |||
571 | if ((temp8 > 2) && (temp8 < 0xC0)) { | ||
572 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | 427 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); |
573 | } | 428 | } |
574 | 429 | ||
575 | output_struct->data.address32.resource_type = temp8; | ||
576 | |||
577 | /* Get the General Flags (Byte4) */ | ||
578 | |||
579 | buffer += 1; | ||
580 | acpi_rs_decode_general_flags(&output_struct->data, *buffer); | ||
581 | |||
582 | /* Get the Type Specific Flags (Byte5) */ | ||
583 | |||
584 | buffer += 1; | ||
585 | acpi_rs_decode_specific_flags(&output_struct->data, *buffer); | ||
586 | |||
587 | /* Get Granularity (Bytes 6-9) */ | ||
588 | |||
589 | buffer += 1; | ||
590 | ACPI_MOVE_32_TO_32(&output_struct->data.address32.granularity, buffer); | ||
591 | |||
592 | /* Get min_address_range (Bytes 10-13) */ | ||
593 | |||
594 | buffer += 4; | ||
595 | ACPI_MOVE_32_TO_32(&output_struct->data.address32.min_address_range, | ||
596 | buffer); | ||
597 | |||
598 | /* Get max_address_range (Bytes 14-17) */ | ||
599 | |||
600 | buffer += 4; | ||
601 | ACPI_MOVE_32_TO_32(&output_struct->data.address32.max_address_range, | ||
602 | buffer); | ||
603 | |||
604 | /* Get address_translation_offset (Bytes 18-21) */ | ||
605 | |||
606 | buffer += 4; | ||
607 | ACPI_MOVE_32_TO_32(&output_struct->data.address32. | ||
608 | address_translation_offset, buffer); | ||
609 | |||
610 | /* Get address_length (Bytes 22-25) */ | ||
611 | |||
612 | buffer += 4; | ||
613 | ACPI_MOVE_32_TO_32(&output_struct->data.address32.address_length, | ||
614 | buffer); | ||
615 | |||
616 | /* Resource Source Index (if present) */ | ||
617 | |||
618 | buffer += 4; | ||
619 | |||
620 | /* | 430 | /* |
621 | * This will leave us pointing to the Resource Source Index | 431 | * Get the following contiguous fields from the AML descriptor: |
622 | * If it is present, then save it off and calculate the | 432 | * Address Granularity |
623 | * pointer to where the null terminated string goes: | 433 | * Address Range Minimum |
624 | * | 434 | * Address Range Maximum |
625 | * Note: Some resource descriptors will have an additional null, so | 435 | * Address Translation Offset |
626 | * we add 1 to the length. | 436 | * Address Length |
627 | */ | 437 | */ |
628 | if (*bytes_consumed > (26 + 1)) { | 438 | acpi_rs_move_data(&resource->data.address32.granularity, |
629 | /* Dereference the Index */ | 439 | &aml->address32.granularity, 5, |
630 | 440 | ACPI_MOVE_TYPE_32_TO_32); | |
631 | output_struct->data.address32.resource_source.index = | ||
632 | (u32) * buffer; | ||
633 | |||
634 | /* Point to the String */ | ||
635 | 441 | ||
636 | buffer += 1; | 442 | /* Get the optional resource_source (index and string) */ |
637 | 443 | ||
638 | /* Point the String pointer to the end of this structure */ | 444 | resource->length = |
445 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32) + | ||
446 | acpi_rs_get_resource_source(aml_resource_length, | ||
447 | sizeof(struct aml_resource_address32), | ||
448 | &resource->data.address32. | ||
449 | resource_source, aml, NULL); | ||
639 | 450 | ||
640 | output_struct->data.address32.resource_source.string_ptr = | 451 | /* Complete the resource header */ |
641 | (char *)((u8 *) output_struct + struct_size); | ||
642 | 452 | ||
643 | temp_ptr = (u8 *) | 453 | resource->type = ACPI_RESOURCE_TYPE_ADDRESS32; |
644 | output_struct->data.address32.resource_source.string_ptr; | ||
645 | |||
646 | /* Copy the resource_source string into the buffer */ | ||
647 | |||
648 | index = 0; | ||
649 | while (*buffer) { | ||
650 | *temp_ptr = *buffer; | ||
651 | |||
652 | temp_ptr++; | ||
653 | buffer++; | ||
654 | index++; | ||
655 | } | ||
656 | |||
657 | /* Add the terminating null and set the string length */ | ||
658 | |||
659 | *temp_ptr = 0; | ||
660 | output_struct->data.address32.resource_source.string_length = | ||
661 | index + 1; | ||
662 | |||
663 | /* | ||
664 | * In order for the struct_size to fall on a 32-bit boundary, | ||
665 | * calculate the length of the string and expand the | ||
666 | * struct_size to the next 32-bit boundary. | ||
667 | */ | ||
668 | temp8 = (u8) (index + 1); | ||
669 | struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); | ||
670 | } else { | ||
671 | output_struct->data.address32.resource_source.index = 0; | ||
672 | output_struct->data.address32.resource_source.string_length = 0; | ||
673 | output_struct->data.address32.resource_source.string_ptr = NULL; | ||
674 | } | ||
675 | |||
676 | /* Set the Length parameter */ | ||
677 | |||
678 | output_struct->length = (u32) struct_size; | ||
679 | |||
680 | /* Return the final size of the structure */ | ||
681 | |||
682 | *structure_size = struct_size; | ||
683 | return_ACPI_STATUS(AE_OK); | 454 | return_ACPI_STATUS(AE_OK); |
684 | } | 455 | } |
685 | 456 | ||
686 | /******************************************************************************* | 457 | /******************************************************************************* |
687 | * | 458 | * |
688 | * FUNCTION: acpi_rs_address32_stream | 459 | * FUNCTION: acpi_rs_set_address32 |
689 | * | 460 | * |
690 | * PARAMETERS: Resource - Pointer to the resource linked list | 461 | * PARAMETERS: Resource - Pointer to the resource descriptor |
691 | * output_buffer - Pointer to the user's return buffer | 462 | * Aml - Where the AML descriptor is returned |
692 | * bytes_consumed - Pointer to where the number of bytes | ||
693 | * used in the output_buffer is returned | ||
694 | * | 463 | * |
695 | * RETURN: Status | 464 | * RETURN: Status |
696 | * | 465 | * |
697 | * DESCRIPTION: Take the linked list resource structure and fills in the | 466 | * DESCRIPTION: Convert an internal resource descriptor to the corresponding |
698 | * the appropriate bytes in a byte stream | 467 | * external AML resource descriptor. |
699 | * | 468 | * |
700 | ******************************************************************************/ | 469 | ******************************************************************************/ |
701 | 470 | ||
702 | acpi_status | 471 | acpi_status |
703 | acpi_rs_address32_stream(struct acpi_resource *resource, | 472 | acpi_rs_set_address32(struct acpi_resource *resource, union aml_resource *aml) |
704 | u8 ** output_buffer, acpi_size * bytes_consumed) | ||
705 | { | 473 | { |
706 | u8 *buffer; | 474 | acpi_size descriptor_length; |
707 | u16 *length_field; | ||
708 | |||
709 | ACPI_FUNCTION_TRACE("rs_address32_stream"); | ||
710 | |||
711 | buffer = *output_buffer; | ||
712 | 475 | ||
713 | /* Set the Descriptor Type field */ | 476 | ACPI_FUNCTION_TRACE("rs_set_address32"); |
714 | 477 | ||
715 | *buffer = ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE; | 478 | /* Set the Resource Type, General Flags, and Type-Specific Flags */ |
716 | buffer += 1; | ||
717 | 479 | ||
718 | /* Save a pointer to the Length field - to be filled in later */ | 480 | acpi_rs_set_address_common(aml, resource); |
719 | 481 | ||
720 | length_field = ACPI_CAST_PTR(u16, buffer); | 482 | /* |
721 | buffer += 2; | 483 | * Set the following contiguous fields in the AML descriptor: |
722 | 484 | * Address Granularity | |
723 | /* Set the Resource Type (Memory, Io, bus_number) */ | 485 | * Address Range Minimum |
724 | 486 | * Address Range Maximum | |
725 | *buffer = (u8) (resource->data.address32.resource_type & 0x03); | 487 | * Address Translation Offset |
726 | buffer += 1; | 488 | * Address Length |
727 | 489 | */ | |
728 | /* Set the general flags */ | 490 | acpi_rs_move_data(&aml->address32.granularity, |
729 | 491 | &resource->data.address32.granularity, 5, | |
730 | *buffer = acpi_rs_encode_general_flags(&resource->data); | 492 | ACPI_MOVE_TYPE_32_TO_32); |
731 | buffer += 1; | ||
732 | |||
733 | /* Set the type specific flags */ | ||
734 | |||
735 | *buffer = acpi_rs_encode_specific_flags(&resource->data); | ||
736 | buffer += 1; | ||
737 | |||
738 | /* Set the address space granularity */ | ||
739 | |||
740 | ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.granularity); | ||
741 | buffer += 4; | ||
742 | |||
743 | /* Set the address range minimum */ | ||
744 | |||
745 | ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.min_address_range); | ||
746 | buffer += 4; | ||
747 | |||
748 | /* Set the address range maximum */ | ||
749 | |||
750 | ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.max_address_range); | ||
751 | buffer += 4; | ||
752 | |||
753 | /* Set the address translation offset */ | ||
754 | |||
755 | ACPI_MOVE_32_TO_32(buffer, | ||
756 | &resource->data.address32. | ||
757 | address_translation_offset); | ||
758 | buffer += 4; | ||
759 | |||
760 | /* Set the address length */ | ||
761 | |||
762 | ACPI_MOVE_32_TO_32(buffer, &resource->data.address32.address_length); | ||
763 | buffer += 4; | ||
764 | 493 | ||
765 | /* Resource Source Index and Resource Source are optional */ | 494 | /* Resource Source Index and Resource Source are optional */ |
766 | 495 | ||
767 | if (resource->data.address32.resource_source.string_length) { | 496 | descriptor_length = acpi_rs_set_resource_source(aml, |
768 | *buffer = (u8) resource->data.address32.resource_source.index; | 497 | sizeof(struct |
769 | buffer += 1; | 498 | aml_resource_address32), |
770 | 499 | &resource->data. | |
771 | /* Copy the resource_source string */ | 500 | address32. |
501 | resource_source); | ||
772 | 502 | ||
773 | ACPI_STRCPY((char *)buffer, | 503 | /* Complete the AML descriptor header */ |
774 | resource->data.address32.resource_source. | ||
775 | string_ptr); | ||
776 | 504 | ||
777 | /* | 505 | acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS32, |
778 | * Buffer needs to be set to the length of the string + one for the | 506 | descriptor_length, aml); |
779 | * terminating null | ||
780 | */ | ||
781 | buffer += | ||
782 | (acpi_size) (ACPI_STRLEN | ||
783 | (resource->data.address32.resource_source. | ||
784 | string_ptr) + 1); | ||
785 | } | ||
786 | |||
787 | /* Return the number of bytes consumed in this operation */ | ||
788 | |||
789 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
790 | |||
791 | /* | ||
792 | * Set the length field to the number of bytes consumed | ||
793 | * minus the header size (3 bytes) | ||
794 | */ | ||
795 | *length_field = (u16) (*bytes_consumed - 3); | ||
796 | return_ACPI_STATUS(AE_OK); | 507 | return_ACPI_STATUS(AE_OK); |
797 | } | 508 | } |
798 | 509 | ||
799 | /******************************************************************************* | 510 | /******************************************************************************* |
800 | * | 511 | * |
801 | * FUNCTION: acpi_rs_address64_resource | 512 | * FUNCTION: acpi_rs_get_address64 |
802 | * | 513 | * |
803 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | 514 | * PARAMETERS: Aml - Pointer to the AML resource descriptor |
804 | * stream | 515 | * aml_resource_length - Length of the resource from the AML header |
805 | * bytes_consumed - Pointer to where the number of bytes | 516 | * Resource - Where the internal resource is returned |
806 | * consumed the byte_stream_buffer is | ||
807 | * returned | ||
808 | * output_buffer - Pointer to the return data buffer | ||
809 | * structure_size - Pointer to where the number of bytes | ||
810 | * in the return data struct is returned | ||
811 | * | 517 | * |
812 | * RETURN: Status | 518 | * RETURN: Status |
813 | * | 519 | * |
814 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | 520 | * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding |
815 | * structure pointed to by the output_buffer. Return the | 521 | * internal resource descriptor, simplifying bitflags and handling |
816 | * number of bytes consumed from the byte stream. | 522 | * alignment and endian issues if necessary. |
817 | * | 523 | * |
818 | ******************************************************************************/ | 524 | ******************************************************************************/ |
819 | 525 | ||
820 | acpi_status | 526 | acpi_status |
821 | acpi_rs_address64_resource(u8 * byte_stream_buffer, | 527 | acpi_rs_get_address64(union aml_resource *aml, |
822 | acpi_size * bytes_consumed, | 528 | u16 aml_resource_length, struct acpi_resource *resource) |
823 | u8 ** output_buffer, acpi_size * structure_size) | ||
824 | { | 529 | { |
825 | u16 temp16; | 530 | ACPI_FUNCTION_TRACE("rs_get_address64"); |
826 | u8 temp8; | ||
827 | u8 resource_type; | ||
828 | u8 *temp_ptr; | ||
829 | u32 index; | ||
830 | u8 *buffer = byte_stream_buffer; | ||
831 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
832 | acpi_size struct_size = | ||
833 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64); | ||
834 | |||
835 | ACPI_FUNCTION_TRACE("rs_address64_resource"); | ||
836 | |||
837 | /* Get the Descriptor Type */ | ||
838 | |||
839 | resource_type = *buffer; | ||
840 | |||
841 | /* Get the Descriptor Length field */ | ||
842 | |||
843 | buffer += 1; | ||
844 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
845 | |||
846 | /* Validate minimum descriptor length */ | ||
847 | |||
848 | if (temp16 < 43) { | ||
849 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); | ||
850 | } | ||
851 | |||
852 | *bytes_consumed = temp16 + 3; | ||
853 | output_struct->type = ACPI_RSTYPE_ADDRESS64; | ||
854 | |||
855 | /* Get the Resource Type (Byte3) */ | ||
856 | 531 | ||
857 | buffer += 2; | 532 | /* Get the Resource Type, general Flags, and type-specific Flags */ |
858 | temp8 = *buffer; | ||
859 | 533 | ||
860 | /* Values 0-2 and 0xC0-0xFF are valid */ | 534 | if (!acpi_rs_get_address_common(resource, aml)) { |
861 | |||
862 | if ((temp8 > 2) && (temp8 < 0xC0)) { | ||
863 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | 535 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); |
864 | } | 536 | } |
865 | 537 | ||
866 | output_struct->data.address64.resource_type = temp8; | 538 | /* |
867 | 539 | * Get the following contiguous fields from the AML descriptor: | |
868 | /* Get the General Flags (Byte4) */ | 540 | * Address Granularity |
869 | 541 | * Address Range Minimum | |
870 | buffer += 1; | 542 | * Address Range Maximum |
871 | acpi_rs_decode_general_flags(&output_struct->data, *buffer); | 543 | * Address Translation Offset |
872 | 544 | * Address Length | |
873 | /* Get the Type Specific Flags (Byte5) */ | 545 | */ |
874 | 546 | acpi_rs_move_data(&resource->data.address64.granularity, | |
875 | buffer += 1; | 547 | &aml->address64.granularity, 5, |
876 | acpi_rs_decode_specific_flags(&output_struct->data, *buffer); | 548 | ACPI_MOVE_TYPE_64_TO_64); |
877 | |||
878 | if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) { | ||
879 | /* Move past revision_id and Reserved byte */ | ||
880 | |||
881 | buffer += 2; | ||
882 | } | ||
883 | |||
884 | /* Get Granularity (Bytes 6-13) or (Bytes 8-15) */ | ||
885 | |||
886 | buffer += 1; | ||
887 | ACPI_MOVE_64_TO_64(&output_struct->data.address64.granularity, buffer); | ||
888 | |||
889 | /* Get min_address_range (Bytes 14-21) or (Bytes 16-23) */ | ||
890 | |||
891 | buffer += 8; | ||
892 | ACPI_MOVE_64_TO_64(&output_struct->data.address64.min_address_range, | ||
893 | buffer); | ||
894 | |||
895 | /* Get max_address_range (Bytes 22-29) or (Bytes 24-31) */ | ||
896 | |||
897 | buffer += 8; | ||
898 | ACPI_MOVE_64_TO_64(&output_struct->data.address64.max_address_range, | ||
899 | buffer); | ||
900 | |||
901 | /* Get address_translation_offset (Bytes 30-37) or (Bytes 32-39) */ | ||
902 | |||
903 | buffer += 8; | ||
904 | ACPI_MOVE_64_TO_64(&output_struct->data.address64. | ||
905 | address_translation_offset, buffer); | ||
906 | 549 | ||
907 | /* Get address_length (Bytes 38-45) or (Bytes 40-47) */ | 550 | /* Get the optional resource_source (index and string) */ |
908 | 551 | ||
909 | buffer += 8; | 552 | resource->length = |
910 | ACPI_MOVE_64_TO_64(&output_struct->data.address64.address_length, | 553 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64) + |
911 | buffer); | 554 | acpi_rs_get_resource_source(aml_resource_length, |
555 | sizeof(struct aml_resource_address64), | ||
556 | &resource->data.address64. | ||
557 | resource_source, aml, NULL); | ||
912 | 558 | ||
913 | output_struct->data.address64.resource_source.index = 0; | 559 | /* Complete the resource header */ |
914 | output_struct->data.address64.resource_source.string_length = 0; | ||
915 | output_struct->data.address64.resource_source.string_ptr = NULL; | ||
916 | 560 | ||
917 | if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) { | 561 | resource->type = ACPI_RESOURCE_TYPE_ADDRESS64; |
918 | /* Get type_specific_attribute (Bytes 48-55) */ | 562 | return_ACPI_STATUS(AE_OK); |
563 | } | ||
919 | 564 | ||
920 | buffer += 8; | 565 | /******************************************************************************* |
921 | ACPI_MOVE_64_TO_64(&output_struct->data.address64. | 566 | * |
922 | type_specific_attributes, buffer); | 567 | * FUNCTION: acpi_rs_set_address64 |
923 | } else { | 568 | * |
924 | output_struct->data.address64.type_specific_attributes = 0; | 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 | * | ||
577 | ******************************************************************************/ | ||
925 | 578 | ||
926 | /* Resource Source Index (if present) */ | 579 | acpi_status |
580 | acpi_rs_set_address64(struct acpi_resource *resource, union aml_resource *aml) | ||
581 | { | ||
582 | acpi_size descriptor_length; | ||
927 | 583 | ||
928 | buffer += 8; | 584 | ACPI_FUNCTION_TRACE("rs_set_address64"); |
929 | 585 | ||
930 | /* | 586 | /* Set the Resource Type, General Flags, and Type-Specific Flags */ |
931 | * This will leave us pointing to the Resource Source Index | ||
932 | * If it is present, then save it off and calculate the | ||
933 | * pointer to where the null terminated string goes: | ||
934 | * Each Interrupt takes 32-bits + the 5 bytes of the | ||
935 | * stream that are default. | ||
936 | * | ||
937 | * Note: Some resource descriptors will have an additional null, so | ||
938 | * we add 1 to the length. | ||
939 | */ | ||
940 | if (*bytes_consumed > (46 + 1)) { | ||
941 | /* Dereference the Index */ | ||
942 | 587 | ||
943 | output_struct->data.address64.resource_source.index = | 588 | acpi_rs_set_address_common(aml, resource); |
944 | (u32) * buffer; | ||
945 | 589 | ||
946 | /* Point to the String */ | 590 | /* |
591 | * Set the following contiguous fields in the AML descriptor: | ||
592 | * Address Granularity | ||
593 | * Address Range Minimum | ||
594 | * Address Range Maximum | ||
595 | * Address Translation Offset | ||
596 | * Address Length | ||
597 | */ | ||
598 | acpi_rs_move_data(&aml->address64.granularity, | ||
599 | &resource->data.address64.granularity, 5, | ||
600 | ACPI_MOVE_TYPE_64_TO_64); | ||
947 | 601 | ||
948 | buffer += 1; | 602 | /* Resource Source Index and Resource Source are optional */ |
949 | 603 | ||
950 | /* Point the String pointer to the end of this structure */ | 604 | descriptor_length = acpi_rs_set_resource_source(aml, |
605 | sizeof(struct | ||
606 | aml_resource_address64), | ||
607 | &resource->data. | ||
608 | address64. | ||
609 | resource_source); | ||
951 | 610 | ||
952 | output_struct->data.address64.resource_source. | 611 | /* Complete the AML descriptor header */ |
953 | string_ptr = | ||
954 | (char *)((u8 *) output_struct + struct_size); | ||
955 | 612 | ||
956 | temp_ptr = (u8 *) | 613 | acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_ADDRESS64, |
957 | output_struct->data.address64.resource_source. | 614 | descriptor_length, aml); |
958 | string_ptr; | 615 | return_ACPI_STATUS(AE_OK); |
616 | } | ||
959 | 617 | ||
960 | /* Copy the resource_source string into the buffer */ | 618 | /******************************************************************************* |
619 | * | ||
620 | * FUNCTION: acpi_rs_get_ext_address64 | ||
621 | * | ||
622 | * PARAMETERS: Aml - Pointer to the AML resource descriptor | ||
623 | * aml_resource_length - Length of the resource from the AML header | ||
624 | * Resource - Where the internal resource is returned | ||
625 | * | ||
626 | * RETURN: Status | ||
627 | * | ||
628 | * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding | ||
629 | * internal resource descriptor, simplifying bitflags and handling | ||
630 | * alignment and endian issues if necessary. | ||
631 | * | ||
632 | ******************************************************************************/ | ||
961 | 633 | ||
962 | index = 0; | 634 | acpi_status |
963 | while (*buffer) { | 635 | acpi_rs_get_ext_address64(union aml_resource *aml, |
964 | *temp_ptr = *buffer; | 636 | u16 aml_resource_length, |
637 | struct acpi_resource *resource) | ||
638 | { | ||
965 | 639 | ||
966 | temp_ptr++; | 640 | ACPI_FUNCTION_TRACE("rs_get_ext_address64"); |
967 | buffer++; | ||
968 | index++; | ||
969 | } | ||
970 | 641 | ||
971 | /* | 642 | /* Get the Resource Type, general flags, and type-specific flags */ |
972 | * Add the terminating null and set the string length | ||
973 | */ | ||
974 | *temp_ptr = 0; | ||
975 | output_struct->data.address64.resource_source. | ||
976 | string_length = index + 1; | ||
977 | 643 | ||
978 | /* | 644 | if (!acpi_rs_get_address_common(resource, aml)) { |
979 | * In order for the struct_size to fall on a 32-bit boundary, | 645 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); |
980 | * calculate the length of the string and expand the | ||
981 | * struct_size to the next 32-bit boundary. | ||
982 | */ | ||
983 | temp8 = (u8) (index + 1); | ||
984 | struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); | ||
985 | } | ||
986 | } | 646 | } |
987 | 647 | ||
988 | /* Set the Length parameter */ | 648 | /* |
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 | } | ||
989 | 658 | ||
990 | output_struct->length = (u32) struct_size; | 659 | /* |
660 | * Get the following contiguous fields from the AML descriptor: | ||
661 | * Address Granularity | ||
662 | * Address Range Minimum | ||
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); | ||
991 | 671 | ||
992 | /* Return the final size of the structure */ | 672 | /* Complete the resource header */ |
993 | 673 | ||
994 | *structure_size = struct_size; | 674 | resource->type = ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64; |
675 | resource->length = | ||
676 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_extended_address64); | ||
995 | return_ACPI_STATUS(AE_OK); | 677 | return_ACPI_STATUS(AE_OK); |
996 | } | 678 | } |
997 | 679 | ||
998 | /******************************************************************************* | 680 | /******************************************************************************* |
999 | * | 681 | * |
1000 | * FUNCTION: acpi_rs_address64_stream | 682 | * FUNCTION: acpi_rs_set_ext_address64 |
1001 | * | 683 | * |
1002 | * PARAMETERS: Resource - Pointer to the resource linked list | 684 | * PARAMETERS: Resource - Pointer to the resource descriptor |
1003 | * output_buffer - Pointer to the user's return buffer | 685 | * Aml - Where the AML descriptor is returned |
1004 | * bytes_consumed - Pointer to where the number of bytes | ||
1005 | * used in the output_buffer is returned | ||
1006 | * | 686 | * |
1007 | * RETURN: Status | 687 | * RETURN: Status |
1008 | * | 688 | * |
1009 | * DESCRIPTION: Take the linked list resource structure and fills in the | 689 | * DESCRIPTION: Convert an internal resource descriptor to the corresponding |
1010 | * the appropriate bytes in a byte stream | 690 | * external AML resource descriptor. |
1011 | * | 691 | * |
1012 | ******************************************************************************/ | 692 | ******************************************************************************/ |
1013 | 693 | ||
1014 | acpi_status | 694 | acpi_status |
1015 | acpi_rs_address64_stream(struct acpi_resource *resource, | 695 | acpi_rs_set_ext_address64(struct acpi_resource *resource, |
1016 | u8 ** output_buffer, acpi_size * bytes_consumed) | 696 | union aml_resource *aml) |
1017 | { | 697 | { |
1018 | u8 *buffer; | 698 | ACPI_FUNCTION_TRACE("rs_set_ext_address64"); |
1019 | u16 *length_field; | ||
1020 | |||
1021 | ACPI_FUNCTION_TRACE("rs_address64_stream"); | ||
1022 | |||
1023 | buffer = *output_buffer; | ||
1024 | |||
1025 | /* Set the Descriptor Type field */ | ||
1026 | |||
1027 | *buffer = ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE; | ||
1028 | buffer += 1; | ||
1029 | |||
1030 | /* Save a pointer to the Length field - to be filled in later */ | ||
1031 | |||
1032 | length_field = ACPI_CAST_PTR(u16, buffer); | ||
1033 | buffer += 2; | ||
1034 | |||
1035 | /* Set the Resource Type (Memory, Io, bus_number) */ | ||
1036 | |||
1037 | *buffer = (u8) (resource->data.address64.resource_type & 0x03); | ||
1038 | buffer += 1; | ||
1039 | |||
1040 | /* Set the general flags */ | ||
1041 | |||
1042 | *buffer = acpi_rs_encode_general_flags(&resource->data); | ||
1043 | buffer += 1; | ||
1044 | |||
1045 | /* Set the type specific flags */ | ||
1046 | |||
1047 | *buffer = acpi_rs_encode_specific_flags(&resource->data); | ||
1048 | buffer += 1; | ||
1049 | |||
1050 | /* Set the address space granularity */ | ||
1051 | 699 | ||
1052 | ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.granularity); | 700 | /* Set the Resource Type, General Flags, and Type-Specific Flags */ |
1053 | buffer += 8; | ||
1054 | 701 | ||
1055 | /* Set the address range minimum */ | 702 | acpi_rs_set_address_common(aml, resource); |
1056 | 703 | ||
1057 | ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.min_address_range); | 704 | /* Only one Revision ID is currently supported */ |
1058 | buffer += 8; | ||
1059 | 705 | ||
1060 | /* Set the address range maximum */ | 706 | aml->ext_address64.revision_iD = AML_RESOURCE_EXTENDED_ADDRESS_REVISION; |
1061 | 707 | aml->ext_address64.reserved = 0; | |
1062 | ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.max_address_range); | ||
1063 | buffer += 8; | ||
1064 | |||
1065 | /* Set the address translation offset */ | ||
1066 | |||
1067 | ACPI_MOVE_64_TO_64(buffer, | ||
1068 | &resource->data.address64. | ||
1069 | address_translation_offset); | ||
1070 | buffer += 8; | ||
1071 | |||
1072 | /* Set the address length */ | ||
1073 | |||
1074 | ACPI_MOVE_64_TO_64(buffer, &resource->data.address64.address_length); | ||
1075 | buffer += 8; | ||
1076 | |||
1077 | /* Resource Source Index and Resource Source are optional */ | ||
1078 | |||
1079 | if (resource->data.address64.resource_source.string_length) { | ||
1080 | *buffer = (u8) resource->data.address64.resource_source.index; | ||
1081 | buffer += 1; | ||
1082 | |||
1083 | /* Copy the resource_source string */ | ||
1084 | |||
1085 | ACPI_STRCPY((char *)buffer, | ||
1086 | resource->data.address64.resource_source. | ||
1087 | string_ptr); | ||
1088 | |||
1089 | /* | ||
1090 | * Buffer needs to be set to the length of the string + one for the | ||
1091 | * terminating null | ||
1092 | */ | ||
1093 | buffer += | ||
1094 | (acpi_size) (ACPI_STRLEN | ||
1095 | (resource->data.address64.resource_source. | ||
1096 | string_ptr) + 1); | ||
1097 | } | ||
1098 | |||
1099 | /* Return the number of bytes consumed in this operation */ | ||
1100 | |||
1101 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
1102 | 708 | ||
1103 | /* | 709 | /* |
1104 | * Set the length field to the number of bytes consumed | 710 | * Set the following contiguous fields in the AML descriptor: |
1105 | * minus the header size (3 bytes) | 711 | * Address Granularity |
712 | * Address Range Minimum | ||
713 | * Address Range Maximum | ||
714 | * Address Translation Offset | ||
715 | * Address Length | ||
716 | * Type-Specific Attribute | ||
1106 | */ | 717 | */ |
1107 | *length_field = (u16) (*bytes_consumed - 3); | 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); | ||
1108 | return_ACPI_STATUS(AE_OK); | 728 | return_ACPI_STATUS(AE_OK); |
1109 | } | 729 | } |