aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/resources/rsutils.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2005-10-21 00:00:00 -0400
committerLen Brown <len.brown@intel.com>2005-12-10 00:22:54 -0500
commit0897831bb54eb36fd9e2a22da7f0f64be1b20d09 (patch)
tree8d77687ce8ebcfb62d6012d2d3c44f6a904b3c15 /drivers/acpi/resources/rsutils.c
parent50eca3eb89d73d9f0aa070b126c7ee6a616016ab (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.c269
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 ******************************************************************************/
63u8 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
95u16 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
67void 126void
68acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) 127acpi_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
163u16 acpi_rs_get_resource_length(union aml_resource * aml) 233void
234acpi_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
201u32 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
244void 288void
245acpi_rs_set_resource_header(u8 descriptor_type, 289acpi_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
296u8 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
363u16 354acpi_rs_length
364acpi_rs_get_resource_source(u16 resource_length, 355acpi_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
442acpi_size 439acpi_rsdesc_size
443acpi_rs_set_resource_source(union aml_resource * aml, 440acpi_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 */