diff options
author | Bob Moore <robert.moore@intel.com> | 2005-10-21 00:00:00 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2005-12-10 00:22:54 -0500 |
commit | 0897831bb54eb36fd9e2a22da7f0f64be1b20d09 (patch) | |
tree | 8d77687ce8ebcfb62d6012d2d3c44f6a904b3c15 /drivers/acpi/resources/rsutils.c | |
parent | 50eca3eb89d73d9f0aa070b126c7ee6a616016ab (diff) |
[ACPI] ACPICA 20051021
Implemented support for the EM64T and other x86_64
processors. This essentially entails recognizing
that these processors support non-aligned memory
transfers. Previously, all 64-bit processors were assumed
to lack hardware support for non-aligned transfers.
Completed conversion of the Resource Manager to nearly
full table-driven operation. Specifically, the resource
conversion code (convert AML to internal format and the
reverse) and the debug code to dump internal resource
descriptors are fully table-driven, reducing code and data
size and improving maintainability.
The OSL interfaces for Acquire and Release Lock now use a
64-bit flag word on 64-bit processors instead of a fixed
32-bit word. (Alexey Starikovskiy)
Implemented support within the resource conversion code
for the Type-Specific byte within the various ACPI 3.0
*WordSpace macros.
Fixed some issues within the resource conversion code for
the type-specific flags for both Memory and I/O address
resource descriptors. For Memory, implemented support
for the MTP and TTP flags. For I/O, split the TRS and TTP
flags into two separate fields.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/resources/rsutils.c')
-rw-r--r-- | drivers/acpi/resources/rsutils.c | 269 |
1 files changed, 133 insertions, 136 deletions
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index 9d503de1a349..7613033f5dcf 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c | |||
@@ -50,6 +50,64 @@ ACPI_MODULE_NAME("rsutils") | |||
50 | 50 | ||
51 | /******************************************************************************* | 51 | /******************************************************************************* |
52 | * | 52 | * |
53 | * FUNCTION: acpi_rs_decode_bitmask | ||
54 | * | ||
55 | * PARAMETERS: Mask - Bitmask to decode | ||
56 | * List - Where the converted list is returned | ||
57 | * | ||
58 | * RETURN: Count of bits set (length of list) | ||
59 | * | ||
60 | * DESCRIPTION: Convert a bit mask into a list of values | ||
61 | * | ||
62 | ******************************************************************************/ | ||
63 | u8 acpi_rs_decode_bitmask(u16 mask, u8 * list) | ||
64 | { | ||
65 | acpi_native_uint i; | ||
66 | u8 bit_count; | ||
67 | |||
68 | /* Decode the mask bits */ | ||
69 | |||
70 | for (i = 0, bit_count = 0; mask; i++) { | ||
71 | if (mask & 0x0001) { | ||
72 | list[bit_count] = (u8) i; | ||
73 | bit_count++; | ||
74 | } | ||
75 | |||
76 | mask >>= 1; | ||
77 | } | ||
78 | |||
79 | return (bit_count); | ||
80 | } | ||
81 | |||
82 | /******************************************************************************* | ||
83 | * | ||
84 | * FUNCTION: acpi_rs_encode_bitmask | ||
85 | * | ||
86 | * PARAMETERS: List - List of values to encode | ||
87 | * Count - Length of list | ||
88 | * | ||
89 | * RETURN: Encoded bitmask | ||
90 | * | ||
91 | * DESCRIPTION: Convert a list of values to an encoded bitmask | ||
92 | * | ||
93 | ******************************************************************************/ | ||
94 | |||
95 | u16 acpi_rs_encode_bitmask(u8 * list, u8 count) | ||
96 | { | ||
97 | acpi_native_uint i; | ||
98 | u16 mask; | ||
99 | |||
100 | /* Encode the list into a single bitmask */ | ||
101 | |||
102 | for (i = 0, mask = 0; i < count; i++) { | ||
103 | mask |= (0x0001 << list[i]); | ||
104 | } | ||
105 | |||
106 | return (mask); | ||
107 | } | ||
108 | |||
109 | /******************************************************************************* | ||
110 | * | ||
53 | * FUNCTION: acpi_rs_move_data | 111 | * FUNCTION: acpi_rs_move_data |
54 | * | 112 | * |
55 | * PARAMETERS: Destination - Pointer to the destination descriptor | 113 | * PARAMETERS: Destination - Pointer to the destination descriptor |
@@ -64,6 +122,7 @@ ACPI_MODULE_NAME("rsutils") | |||
64 | * via the ACPI_MOVE_* macros. (This is why a memcpy is not used) | 122 | * via the ACPI_MOVE_* macros. (This is why a memcpy is not used) |
65 | * | 123 | * |
66 | ******************************************************************************/ | 124 | ******************************************************************************/ |
125 | |||
67 | void | 126 | void |
68 | acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) | 127 | acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) |
69 | { | 128 | { |
@@ -73,22 +132,30 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) | |||
73 | 132 | ||
74 | for (i = 0; i < item_count; i++) { | 133 | for (i = 0; i < item_count; i++) { |
75 | switch (move_type) { | 134 | switch (move_type) { |
76 | case ACPI_MOVE_TYPE_16_TO_32: | 135 | /* |
77 | ACPI_MOVE_16_TO_32(&((u32 *) destination)[i], | 136 | * For the 8-bit case, we can perform the move all at once |
78 | &((u16 *) source)[i]); | 137 | * since there are no alignment or endian issues |
79 | break; | 138 | */ |
139 | case ACPI_RSC_MOVE8: | ||
140 | ACPI_MEMCPY(destination, source, item_count); | ||
141 | return; | ||
80 | 142 | ||
81 | case ACPI_MOVE_TYPE_32_TO_16: | 143 | /* |
82 | ACPI_MOVE_32_TO_16(&((u16 *) destination)[i], | 144 | * 16-, 32-, and 64-bit cases must use the move macros that perform |
83 | &((u32 *) source)[i]); | 145 | * endian conversion and/or accomodate hardware that cannot perform |
146 | * misaligned memory transfers | ||
147 | */ | ||
148 | case ACPI_RSC_MOVE16: | ||
149 | ACPI_MOVE_16_TO_16(&((u16 *) destination)[i], | ||
150 | &((u16 *) source)[i]); | ||
84 | break; | 151 | break; |
85 | 152 | ||
86 | case ACPI_MOVE_TYPE_32_TO_32: | 153 | case ACPI_RSC_MOVE32: |
87 | ACPI_MOVE_32_TO_32(&((u32 *) destination)[i], | 154 | ACPI_MOVE_32_TO_32(&((u32 *) destination)[i], |
88 | &((u32 *) source)[i]); | 155 | &((u32 *) source)[i]); |
89 | break; | 156 | break; |
90 | 157 | ||
91 | case ACPI_MOVE_TYPE_64_TO_64: | 158 | case ACPI_RSC_MOVE64: |
92 | ACPI_MOVE_64_TO_64(&((u64 *) destination)[i], | 159 | ACPI_MOVE_64_TO_64(&((u64 *) destination)[i], |
93 | &((u64 *) source)[i]); | 160 | &((u64 *) source)[i]); |
94 | break; | 161 | break; |
@@ -148,80 +215,57 @@ struct acpi_resource_info *acpi_rs_get_resource_info(u8 resource_type) | |||
148 | 215 | ||
149 | /******************************************************************************* | 216 | /******************************************************************************* |
150 | * | 217 | * |
151 | * FUNCTION: acpi_rs_get_resource_length | 218 | * FUNCTION: acpi_rs_set_resource_length |
152 | * | 219 | * |
153 | * PARAMETERS: Aml - Pointer to the raw AML resource descriptor | 220 | * PARAMETERS: total_length - Length of the AML descriptor, including |
221 | * the header and length fields. | ||
222 | * Aml - Pointer to the raw AML descriptor | ||
154 | * | 223 | * |
155 | * RETURN: Byte Length | 224 | * RETURN: None |
156 | * | 225 | * |
157 | * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By | 226 | * DESCRIPTION: Set the resource_length field of an AML |
158 | * definition, this does not include the size of the descriptor | 227 | * resource descriptor, both Large and Small descriptors are |
159 | * header or the length field itself. | 228 | * supported automatically. Note: Descriptor Type field must |
229 | * be valid. | ||
160 | * | 230 | * |
161 | ******************************************************************************/ | 231 | ******************************************************************************/ |
162 | 232 | ||
163 | u16 acpi_rs_get_resource_length(union aml_resource * aml) | 233 | void |
234 | acpi_rs_set_resource_length(acpi_rsdesc_size total_length, | ||
235 | union aml_resource *aml) | ||
164 | { | 236 | { |
165 | u16 resource_length; | 237 | acpi_rs_length resource_length; |
166 | 238 | ||
167 | ACPI_FUNCTION_ENTRY(); | 239 | ACPI_FUNCTION_ENTRY(); |
168 | 240 | ||
169 | /* Determine if this is a small or large resource */ | 241 | /* Determine if this is a small or large resource */ |
170 | 242 | ||
171 | if (aml->large_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { | 243 | if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { |
172 | /* Large Resource type -- bytes 1-2 contain the 16-bit length */ | 244 | /* Large Resource type -- bytes 1-2 contain the 16-bit length */ |
173 | 245 | ||
174 | ACPI_MOVE_16_TO_16(&resource_length, | 246 | resource_length = (acpi_rs_length) |
175 | &aml->large_header.resource_length); | 247 | (total_length - sizeof(struct aml_resource_large_header)); |
248 | |||
249 | /* Insert length into the Large descriptor length field */ | ||
176 | 250 | ||
251 | ACPI_MOVE_16_TO_16(&aml->large_header.resource_length, | ||
252 | &resource_length); | ||
177 | } else { | 253 | } else { |
178 | /* Small Resource type -- bits 2:0 of byte 0 contain the length */ | 254 | /* Small Resource type -- bits 2:0 of byte 0 contain the length */ |
179 | 255 | ||
180 | resource_length = (u16) (aml->small_header.descriptor_type & | 256 | resource_length = (acpi_rs_length) |
181 | ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); | 257 | (total_length - sizeof(struct aml_resource_small_header)); |
182 | } | ||
183 | |||
184 | return (resource_length); | ||
185 | } | ||
186 | 258 | ||
187 | /******************************************************************************* | 259 | /* Insert length into the descriptor type byte */ |
188 | * | ||
189 | * FUNCTION: acpi_rs_get_descriptor_length | ||
190 | * | ||
191 | * PARAMETERS: Aml - Pointer to the raw AML resource descriptor | ||
192 | * | ||
193 | * RETURN: Byte length | ||
194 | * | ||
195 | * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the | ||
196 | * length of the descriptor header and the length field itself. | ||
197 | * Used to walk descriptor lists. | ||
198 | * | ||
199 | ******************************************************************************/ | ||
200 | |||
201 | u32 acpi_rs_get_descriptor_length(union aml_resource * aml) | ||
202 | { | ||
203 | u32 descriptor_length; | ||
204 | |||
205 | ACPI_FUNCTION_ENTRY(); | ||
206 | |||
207 | /* Determine if this is a small or large resource */ | ||
208 | |||
209 | if (aml->large_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { | ||
210 | /* Large Resource type -- bytes 1-2 contain the 16-bit length */ | ||
211 | 260 | ||
212 | ACPI_MOVE_16_TO_32(&descriptor_length, | 261 | aml->small_header.descriptor_type = (u8) |
213 | &aml->large_header.resource_length); | ||
214 | descriptor_length += sizeof(struct aml_resource_large_header); | ||
215 | 262 | ||
216 | } else { | 263 | /* Clear any existing length, preserving descriptor type bits */ |
217 | /* Small Resource type -- bits 2:0 of byte 0 contain the length */ | 264 | ((aml->small_header. |
265 | descriptor_type & ~ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK) | ||
218 | 266 | ||
219 | descriptor_length = (u32) (aml->small_header.descriptor_type & | 267 | | resource_length); |
220 | ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); | ||
221 | descriptor_length += sizeof(struct aml_resource_small_header); | ||
222 | } | 268 | } |
223 | |||
224 | return (descriptor_length); | ||
225 | } | 269 | } |
226 | 270 | ||
227 | /******************************************************************************* | 271 | /******************************************************************************* |
@@ -243,71 +287,18 @@ u32 acpi_rs_get_descriptor_length(union aml_resource * aml) | |||
243 | 287 | ||
244 | void | 288 | void |
245 | acpi_rs_set_resource_header(u8 descriptor_type, | 289 | acpi_rs_set_resource_header(u8 descriptor_type, |
246 | acpi_size total_length, union aml_resource *aml) | 290 | acpi_rsdesc_size total_length, |
291 | union aml_resource *aml) | ||
247 | { | 292 | { |
248 | u16 resource_length; | ||
249 | |||
250 | ACPI_FUNCTION_ENTRY(); | 293 | ACPI_FUNCTION_ENTRY(); |
251 | 294 | ||
252 | /* Set the descriptor type */ | 295 | /* Set the Descriptor Type */ |
253 | 296 | ||
254 | aml->small_header.descriptor_type = descriptor_type; | 297 | aml->small_header.descriptor_type = descriptor_type; |
255 | 298 | ||
256 | /* Determine if this is a small or large resource */ | 299 | /* Set the Resource Length */ |
257 | |||
258 | if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { | ||
259 | /* Large Resource type -- bytes 1-2 contain the 16-bit length */ | ||
260 | |||
261 | resource_length = | ||
262 | (u16) (total_length - | ||
263 | sizeof(struct aml_resource_large_header)); | ||
264 | |||
265 | /* Insert length into the Large descriptor length field */ | ||
266 | |||
267 | ACPI_MOVE_16_TO_16(&aml->large_header.resource_length, | ||
268 | &resource_length); | ||
269 | } else { | ||
270 | /* Small Resource type -- bits 2:0 of byte 0 contain the length */ | ||
271 | |||
272 | resource_length = | ||
273 | (u16) (total_length - | ||
274 | sizeof(struct aml_resource_small_header)); | ||
275 | |||
276 | /* Insert length into the descriptor type byte */ | ||
277 | |||
278 | aml->small_header.descriptor_type |= (u8) resource_length; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | /******************************************************************************* | ||
283 | * | ||
284 | * FUNCTION: acpi_rs_get_resource_type | ||
285 | * | ||
286 | * PARAMETERS: resource_type - Byte 0 of a resource descriptor | ||
287 | * | ||
288 | * RETURN: The Resource Type with no extraneous bits (except the | ||
289 | * Large/Small descriptor bit -- this is left alone) | ||
290 | * | ||
291 | * DESCRIPTION: Extract the Resource Type/Name from the first byte of | ||
292 | * a resource descriptor. | ||
293 | * | ||
294 | ******************************************************************************/ | ||
295 | |||
296 | u8 acpi_rs_get_resource_type(u8 resource_type) | ||
297 | { | ||
298 | ACPI_FUNCTION_ENTRY(); | ||
299 | 300 | ||
300 | /* Determine if this is a small or large resource */ | 301 | acpi_rs_set_resource_length(total_length, aml); |
301 | |||
302 | if (resource_type & ACPI_RESOURCE_NAME_LARGE) { | ||
303 | /* Large Resource Type -- bits 6:0 contain the name */ | ||
304 | |||
305 | return (resource_type); | ||
306 | } else { | ||
307 | /* Small Resource Type -- bits 6:3 contain the name */ | ||
308 | |||
309 | return ((u8) (resource_type & ACPI_RESOURCE_NAME_SMALL_MASK)); | ||
310 | } | ||
311 | } | 302 | } |
312 | 303 | ||
313 | /******************************************************************************* | 304 | /******************************************************************************* |
@@ -360,13 +351,13 @@ static u16 acpi_rs_strcpy(char *destination, char *source) | |||
360 | * | 351 | * |
361 | ******************************************************************************/ | 352 | ******************************************************************************/ |
362 | 353 | ||
363 | u16 | 354 | acpi_rs_length |
364 | acpi_rs_get_resource_source(u16 resource_length, | 355 | acpi_rs_get_resource_source(acpi_rs_length resource_length, |
365 | acpi_size minimum_length, | 356 | acpi_rs_length minimum_length, |
366 | struct acpi_resource_source * resource_source, | 357 | struct acpi_resource_source * resource_source, |
367 | union aml_resource * aml, char *string_ptr) | 358 | union aml_resource * aml, char *string_ptr) |
368 | { | 359 | { |
369 | acpi_size total_length; | 360 | acpi_rsdesc_size total_length; |
370 | u8 *aml_resource_source; | 361 | u8 *aml_resource_source; |
371 | 362 | ||
372 | ACPI_FUNCTION_ENTRY(); | 363 | ACPI_FUNCTION_ENTRY(); |
@@ -382,7 +373,7 @@ acpi_rs_get_resource_source(u16 resource_length, | |||
382 | * Note: Some resource descriptors will have an additional null, so | 373 | * Note: Some resource descriptors will have an additional null, so |
383 | * we add 1 to the minimum length. | 374 | * we add 1 to the minimum length. |
384 | */ | 375 | */ |
385 | if (total_length > (minimum_length + 1)) { | 376 | if (total_length > (acpi_rsdesc_size) (minimum_length + 1)) { |
386 | /* Get the resource_source_index */ | 377 | /* Get the resource_source_index */ |
387 | 378 | ||
388 | resource_source->index = aml_resource_source[0]; | 379 | resource_source->index = aml_resource_source[0]; |
@@ -398,20 +389,26 @@ acpi_rs_get_resource_source(u16 resource_length, | |||
398 | sizeof(struct acpi_resource_source); | 389 | sizeof(struct acpi_resource_source); |
399 | } | 390 | } |
400 | 391 | ||
392 | /* | ||
393 | * In order for the struct_size to fall on a 32-bit boundary, calculate | ||
394 | * the length of the string (+1 for the NULL terminator) and expand the | ||
395 | * struct_size to the next 32-bit boundary. | ||
396 | * | ||
397 | * Zero the entire area of the buffer. | ||
398 | */ | ||
399 | total_length = | ||
400 | ACPI_ROUND_UP_to_32_bITS(ACPI_STRLEN | ||
401 | ((char *)&aml_resource_source[1]) + | ||
402 | 1); | ||
403 | ACPI_MEMSET(resource_source->string_ptr, 0, total_length); | ||
404 | |||
401 | /* Copy the resource_source string to the destination */ | 405 | /* Copy the resource_source string to the destination */ |
402 | 406 | ||
403 | resource_source->string_length = | 407 | resource_source->string_length = |
404 | acpi_rs_strcpy(resource_source->string_ptr, | 408 | acpi_rs_strcpy(resource_source->string_ptr, |
405 | (char *)&aml_resource_source[1]); | 409 | (char *)&aml_resource_source[1]); |
406 | 410 | ||
407 | /* | 411 | return ((acpi_rs_length) total_length); |
408 | * In order for the struct_size to fall on a 32-bit boundary, | ||
409 | * calculate the length of the string and expand the | ||
410 | * struct_size to the next 32-bit boundary. | ||
411 | */ | ||
412 | return ((u16) | ||
413 | ACPI_ROUND_UP_to_32_bITS(resource_source-> | ||
414 | string_length)); | ||
415 | } else { | 412 | } else { |
416 | /* resource_source is not present */ | 413 | /* resource_source is not present */ |
417 | 414 | ||
@@ -434,18 +431,18 @@ acpi_rs_get_resource_source(u16 resource_length, | |||
434 | * | 431 | * |
435 | * RETURN: Total length of the AML descriptor | 432 | * RETURN: Total length of the AML descriptor |
436 | * | 433 | * |
437 | * DESCRIPTION: Convert an optoinal resource_source from internal format to a | 434 | * DESCRIPTION: Convert an optional resource_source from internal format to a |
438 | * raw AML resource descriptor | 435 | * raw AML resource descriptor |
439 | * | 436 | * |
440 | ******************************************************************************/ | 437 | ******************************************************************************/ |
441 | 438 | ||
442 | acpi_size | 439 | acpi_rsdesc_size |
443 | acpi_rs_set_resource_source(union aml_resource * aml, | 440 | acpi_rs_set_resource_source(union aml_resource * aml, |
444 | acpi_size minimum_length, | 441 | acpi_rs_length minimum_length, |
445 | struct acpi_resource_source * resource_source) | 442 | struct acpi_resource_source * resource_source) |
446 | { | 443 | { |
447 | u8 *aml_resource_source; | 444 | u8 *aml_resource_source; |
448 | acpi_size descriptor_length; | 445 | acpi_rsdesc_size descriptor_length; |
449 | 446 | ||
450 | ACPI_FUNCTION_ENTRY(); | 447 | ACPI_FUNCTION_ENTRY(); |
451 | 448 | ||
@@ -472,7 +469,7 @@ acpi_rs_set_resource_source(union aml_resource * aml, | |||
472 | * final descriptor length | 469 | * final descriptor length |
473 | */ | 470 | */ |
474 | descriptor_length += | 471 | descriptor_length += |
475 | ((acpi_size) resource_source->string_length + 1); | 472 | ((acpi_rsdesc_size) resource_source->string_length + 1); |
476 | } | 473 | } |
477 | 474 | ||
478 | /* Return the new total length of the AML descriptor */ | 475 | /* Return the new total length of the AML descriptor */ |