diff options
author | Bob Moore <robert.moore@intel.com> | 2005-09-30 19:03:00 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2005-12-10 00:20:25 -0500 |
commit | 50eca3eb89d73d9f0aa070b126c7ee6a616016ab (patch) | |
tree | b2d06d21b34b9bd17eea4c53cff1f3866fa1b21d /drivers/acpi/resources/rsaddr.c | |
parent | 3d5271f9883cba7b54762bc4fe027d4172f06db7 (diff) |
[ACPI] ACPICA 20050930
Completed a major overhaul of the Resource Manager code -
specifically, optimizations in the area of the AML/internal
resource conversion code. The code has been optimized to
simplify and eliminate duplicated code, CPU stack use has
been decreased by optimizing function parameters and local
variables, and naming conventions across the manager have
been standardized for clarity and ease of maintenance (this
includes function, parameter, variable, and struct/typedef
names.)
All Resource Manager dispatch and information tables have
been moved to a single location for clarity and ease of
maintenance. One new file was created, named "rsinfo.c".
The ACPI return macros (return_ACPI_STATUS, etc.) have
been modified to guarantee that the argument is
not evaluated twice, making them less prone to macro
side-effects. However, since there exists the possibility
of additional stack use if a particular compiler cannot
optimize them (such as in the debug generation case),
the original macros are optionally available. Note that
some invocations of the return_VALUE macro may now cause
size mismatch warnings; the return_UINT8 and return_UINT32
macros are provided to eliminate these. (From Randy Dunlap)
Implemented a new mechanism to enable debug tracing for
individual control methods. A new external interface,
acpi_debug_trace(), is provided to enable this mechanism. The
intent is to allow the host OS to easily enable and disable
tracing for problematic control methods. This interface
can be easily exposed to a user or debugger interface if
desired. See the file psxface.c for details.
acpi_ut_callocate() will now return a valid pointer if a
length of zero is specified - a length of one is used
and a warning is issued. This matches the behavior of
acpi_ut_allocate().
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
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 | } |