xref: /openbmc/linux/drivers/acpi/acpica/nsrepair.c (revision a09d2831)
1 /******************************************************************************
2  *
3  * Module Name: nsrepair - Repair for objects returned by predefined methods
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2009, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include <acpi/acpi.h>
45 #include "accommon.h"
46 #include "acnamesp.h"
47 #include "acinterp.h"
48 
49 #define _COMPONENT          ACPI_NAMESPACE
50 ACPI_MODULE_NAME("nsrepair")
51 
52 /*******************************************************************************
53  *
54  * This module attempts to repair or convert objects returned by the
55  * predefined methods to an object type that is expected, as per the ACPI
56  * specification. The need for this code is dictated by the many machines that
57  * return incorrect types for the standard predefined methods. Performing these
58  * conversions here, in one place, eliminates the need for individual ACPI
59  * device drivers to do the same. Note: Most of these conversions are different
60  * than the internal object conversion routines used for implicit object
61  * conversion.
62  *
63  * The following conversions can be performed as necessary:
64  *
65  * Integer -> String
66  * Integer -> Buffer
67  * String  -> Integer
68  * String  -> Buffer
69  * Buffer  -> Integer
70  * Buffer  -> String
71  * Buffer  -> Package of Integers
72  * Package -> Package of one Package
73  *
74  ******************************************************************************/
75 /* Local prototypes */
76 static acpi_status
77 acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
78 			   union acpi_operand_object **return_object);
79 
80 static acpi_status
81 acpi_ns_convert_to_string(union acpi_operand_object *original_object,
82 			  union acpi_operand_object **return_object);
83 
84 static acpi_status
85 acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
86 			  union acpi_operand_object **return_object);
87 
88 static acpi_status
89 acpi_ns_convert_to_package(union acpi_operand_object *original_object,
90 			   union acpi_operand_object **return_object);
91 
92 /*******************************************************************************
93  *
94  * FUNCTION:    acpi_ns_repair_object
95  *
96  * PARAMETERS:  Data                - Pointer to validation data structure
97  *              expected_btypes     - Object types expected
98  *              package_index       - Index of object within parent package (if
99  *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
100  *                                    otherwise)
101  *              return_object_ptr   - Pointer to the object returned from the
102  *                                    evaluation of a method or object
103  *
104  * RETURN:      Status. AE_OK if repair was successful.
105  *
106  * DESCRIPTION: Attempt to repair/convert a return object of a type that was
107  *              not expected.
108  *
109  ******************************************************************************/
110 
111 acpi_status
112 acpi_ns_repair_object(struct acpi_predefined_data *data,
113 		      u32 expected_btypes,
114 		      u32 package_index,
115 		      union acpi_operand_object **return_object_ptr)
116 {
117 	union acpi_operand_object *return_object = *return_object_ptr;
118 	union acpi_operand_object *new_object;
119 	acpi_status status;
120 
121 	ACPI_FUNCTION_NAME(ns_repair_object);
122 
123 	/*
124 	 * At this point, we know that the type of the returned object was not
125 	 * one of the expected types for this predefined name. Attempt to
126 	 * repair the object by converting it to one of the expected object
127 	 * types for this predefined name.
128 	 */
129 	if (expected_btypes & ACPI_RTYPE_INTEGER) {
130 		status = acpi_ns_convert_to_integer(return_object, &new_object);
131 		if (ACPI_SUCCESS(status)) {
132 			goto object_repaired;
133 		}
134 	}
135 	if (expected_btypes & ACPI_RTYPE_STRING) {
136 		status = acpi_ns_convert_to_string(return_object, &new_object);
137 		if (ACPI_SUCCESS(status)) {
138 			goto object_repaired;
139 		}
140 	}
141 	if (expected_btypes & ACPI_RTYPE_BUFFER) {
142 		status = acpi_ns_convert_to_buffer(return_object, &new_object);
143 		if (ACPI_SUCCESS(status)) {
144 			goto object_repaired;
145 		}
146 	}
147 	if (expected_btypes & ACPI_RTYPE_PACKAGE) {
148 		status = acpi_ns_convert_to_package(return_object, &new_object);
149 		if (ACPI_SUCCESS(status)) {
150 			goto object_repaired;
151 		}
152 	}
153 
154 	/* We cannot repair this object */
155 
156 	return (AE_AML_OPERAND_TYPE);
157 
158       object_repaired:
159 
160 	/* Object was successfully repaired */
161 
162 	/*
163 	 * If the original object is a package element, we need to:
164 	 * 1. Set the reference count of the new object to match the
165 	 *    reference count of the old object.
166 	 * 2. Decrement the reference count of the original object.
167 	 */
168 	if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
169 		new_object->common.reference_count =
170 		    return_object->common.reference_count;
171 
172 		if (return_object->common.reference_count > 1) {
173 			return_object->common.reference_count--;
174 		}
175 
176 		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
177 				  "%s: Converted %s to expected %s at index %u\n",
178 				  data->pathname,
179 				  acpi_ut_get_object_type_name(return_object),
180 				  acpi_ut_get_object_type_name(new_object),
181 				  package_index));
182 	} else {
183 		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
184 				  "%s: Converted %s to expected %s\n",
185 				  data->pathname,
186 				  acpi_ut_get_object_type_name(return_object),
187 				  acpi_ut_get_object_type_name(new_object)));
188 	}
189 
190 	/* Delete old object, install the new return object */
191 
192 	acpi_ut_remove_reference(return_object);
193 	*return_object_ptr = new_object;
194 	data->flags |= ACPI_OBJECT_REPAIRED;
195 	return (AE_OK);
196 }
197 
198 /*******************************************************************************
199  *
200  * FUNCTION:    acpi_ns_convert_to_integer
201  *
202  * PARAMETERS:  original_object     - Object to be converted
203  *              return_object       - Where the new converted object is returned
204  *
205  * RETURN:      Status. AE_OK if conversion was successful.
206  *
207  * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer.
208  *
209  ******************************************************************************/
210 
211 static acpi_status
212 acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
213 			   union acpi_operand_object **return_object)
214 {
215 	union acpi_operand_object *new_object;
216 	acpi_status status;
217 	u64 value = 0;
218 	u32 i;
219 
220 	switch (original_object->common.type) {
221 	case ACPI_TYPE_STRING:
222 
223 		/* String-to-Integer conversion */
224 
225 		status = acpi_ut_strtoul64(original_object->string.pointer,
226 					   ACPI_ANY_BASE, &value);
227 		if (ACPI_FAILURE(status)) {
228 			return (status);
229 		}
230 		break;
231 
232 	case ACPI_TYPE_BUFFER:
233 
234 		/* Buffer-to-Integer conversion. Max buffer size is 64 bits. */
235 
236 		if (original_object->buffer.length > 8) {
237 			return (AE_AML_OPERAND_TYPE);
238 		}
239 
240 		/* Extract each buffer byte to create the integer */
241 
242 		for (i = 0; i < original_object->buffer.length; i++) {
243 			value |=
244 			    ((u64) original_object->buffer.
245 			     pointer[i] << (i * 8));
246 		}
247 		break;
248 
249 	default:
250 		return (AE_AML_OPERAND_TYPE);
251 	}
252 
253 	new_object = acpi_ut_create_integer_object(value);
254 	if (!new_object) {
255 		return (AE_NO_MEMORY);
256 	}
257 
258 	*return_object = new_object;
259 	return (AE_OK);
260 }
261 
262 /*******************************************************************************
263  *
264  * FUNCTION:    acpi_ns_convert_to_string
265  *
266  * PARAMETERS:  original_object     - Object to be converted
267  *              return_object       - Where the new converted object is returned
268  *
269  * RETURN:      Status. AE_OK if conversion was successful.
270  *
271  * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String.
272  *
273  ******************************************************************************/
274 
275 static acpi_status
276 acpi_ns_convert_to_string(union acpi_operand_object *original_object,
277 			  union acpi_operand_object **return_object)
278 {
279 	union acpi_operand_object *new_object;
280 	acpi_size length;
281 	acpi_status status;
282 
283 	switch (original_object->common.type) {
284 	case ACPI_TYPE_INTEGER:
285 		/*
286 		 * Integer-to-String conversion. Commonly, convert
287 		 * an integer of value 0 to a NULL string. The last element of
288 		 * _BIF and _BIX packages occasionally need this fix.
289 		 */
290 		if (original_object->integer.value == 0) {
291 
292 			/* Allocate a new NULL string object */
293 
294 			new_object = acpi_ut_create_string_object(0);
295 			if (!new_object) {
296 				return (AE_NO_MEMORY);
297 			}
298 		} else {
299 			status =
300 			    acpi_ex_convert_to_string(original_object,
301 						      &new_object,
302 						      ACPI_IMPLICIT_CONVERT_HEX);
303 			if (ACPI_FAILURE(status)) {
304 				return (status);
305 			}
306 		}
307 		break;
308 
309 	case ACPI_TYPE_BUFFER:
310 		/*
311 		 * Buffer-to-String conversion. Use a to_string
312 		 * conversion, no transform performed on the buffer data. The best
313 		 * example of this is the _BIF method, where the string data from
314 		 * the battery is often (incorrectly) returned as buffer object(s).
315 		 */
316 		length = 0;
317 		while ((length < original_object->buffer.length) &&
318 		       (original_object->buffer.pointer[length])) {
319 			length++;
320 		}
321 
322 		/* Allocate a new string object */
323 
324 		new_object = acpi_ut_create_string_object(length);
325 		if (!new_object) {
326 			return (AE_NO_MEMORY);
327 		}
328 
329 		/*
330 		 * Copy the raw buffer data with no transform. String is already NULL
331 		 * terminated at Length+1.
332 		 */
333 		ACPI_MEMCPY(new_object->string.pointer,
334 			    original_object->buffer.pointer, length);
335 		break;
336 
337 	default:
338 		return (AE_AML_OPERAND_TYPE);
339 	}
340 
341 	*return_object = new_object;
342 	return (AE_OK);
343 }
344 
345 /*******************************************************************************
346  *
347  * FUNCTION:    acpi_ns_convert_to_buffer
348  *
349  * PARAMETERS:  original_object     - Object to be converted
350  *              return_object       - Where the new converted object is returned
351  *
352  * RETURN:      Status. AE_OK if conversion was successful.
353  *
354  * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer.
355  *
356  ******************************************************************************/
357 
358 static acpi_status
359 acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
360 			  union acpi_operand_object **return_object)
361 {
362 	union acpi_operand_object *new_object;
363 	acpi_status status;
364 	union acpi_operand_object **elements;
365 	u32 *dword_buffer;
366 	u32 count;
367 	u32 i;
368 
369 	switch (original_object->common.type) {
370 	case ACPI_TYPE_INTEGER:
371 		/*
372 		 * Integer-to-Buffer conversion.
373 		 * Convert the Integer to a packed-byte buffer. _MAT and other
374 		 * objects need this sometimes, if a read has been performed on a
375 		 * Field object that is less than or equal to the global integer
376 		 * size (32 or 64 bits).
377 		 */
378 		status =
379 		    acpi_ex_convert_to_buffer(original_object, &new_object);
380 		if (ACPI_FAILURE(status)) {
381 			return (status);
382 		}
383 		break;
384 
385 	case ACPI_TYPE_STRING:
386 
387 		/* String-to-Buffer conversion. Simple data copy */
388 
389 		new_object =
390 		    acpi_ut_create_buffer_object(original_object->string.
391 						 length);
392 		if (!new_object) {
393 			return (AE_NO_MEMORY);
394 		}
395 
396 		ACPI_MEMCPY(new_object->buffer.pointer,
397 			    original_object->string.pointer,
398 			    original_object->string.length);
399 		break;
400 
401 	case ACPI_TYPE_PACKAGE:
402 		/*
403 		 * This case is often seen for predefined names that must return a
404 		 * Buffer object with multiple DWORD integers within. For example,
405 		 * _FDE and _GTM. The Package can be converted to a Buffer.
406 		 */
407 
408 		/* All elements of the Package must be integers */
409 
410 		elements = original_object->package.elements;
411 		count = original_object->package.count;
412 
413 		for (i = 0; i < count; i++) {
414 			if ((!*elements) ||
415 			    ((*elements)->common.type != ACPI_TYPE_INTEGER)) {
416 				return (AE_AML_OPERAND_TYPE);
417 			}
418 			elements++;
419 		}
420 
421 		/* Create the new buffer object to replace the Package */
422 
423 		new_object = acpi_ut_create_buffer_object(ACPI_MUL_4(count));
424 		if (!new_object) {
425 			return (AE_NO_MEMORY);
426 		}
427 
428 		/* Copy the package elements (integers) to the buffer as DWORDs */
429 
430 		elements = original_object->package.elements;
431 		dword_buffer = ACPI_CAST_PTR(u32, new_object->buffer.pointer);
432 
433 		for (i = 0; i < count; i++) {
434 			*dword_buffer = (u32) (*elements)->integer.value;
435 			dword_buffer++;
436 			elements++;
437 		}
438 		break;
439 
440 	default:
441 		return (AE_AML_OPERAND_TYPE);
442 	}
443 
444 	*return_object = new_object;
445 	return (AE_OK);
446 }
447 
448 /*******************************************************************************
449  *
450  * FUNCTION:    acpi_ns_convert_to_package
451  *
452  * PARAMETERS:  original_object     - Object to be converted
453  *              return_object       - Where the new converted object is returned
454  *
455  * RETURN:      Status. AE_OK if conversion was successful.
456  *
457  * DESCRIPTION: Attempt to convert a Buffer object to a Package. Each byte of
458  *              the buffer is converted to a single integer package element.
459  *
460  ******************************************************************************/
461 
462 static acpi_status
463 acpi_ns_convert_to_package(union acpi_operand_object *original_object,
464 			   union acpi_operand_object **return_object)
465 {
466 	union acpi_operand_object *new_object;
467 	union acpi_operand_object **elements;
468 	u32 length;
469 	u8 *buffer;
470 
471 	switch (original_object->common.type) {
472 	case ACPI_TYPE_BUFFER:
473 
474 		/* Buffer-to-Package conversion */
475 
476 		length = original_object->buffer.length;
477 		new_object = acpi_ut_create_package_object(length);
478 		if (!new_object) {
479 			return (AE_NO_MEMORY);
480 		}
481 
482 		/* Convert each buffer byte to an integer package element */
483 
484 		elements = new_object->package.elements;
485 		buffer = original_object->buffer.pointer;
486 
487 		while (length--) {
488 			*elements =
489 			    acpi_ut_create_integer_object((u64) *buffer);
490 			if (!*elements) {
491 				acpi_ut_remove_reference(new_object);
492 				return (AE_NO_MEMORY);
493 			}
494 			elements++;
495 			buffer++;
496 		}
497 		break;
498 
499 	default:
500 		return (AE_AML_OPERAND_TYPE);
501 	}
502 
503 	*return_object = new_object;
504 	return (AE_OK);
505 }
506 
507 /*******************************************************************************
508  *
509  * FUNCTION:    acpi_ns_repair_package_list
510  *
511  * PARAMETERS:  Data                - Pointer to validation data structure
512  *              obj_desc_ptr        - Pointer to the object to repair. The new
513  *                                    package object is returned here,
514  *                                    overwriting the old object.
515  *
516  * RETURN:      Status, new object in *obj_desc_ptr
517  *
518  * DESCRIPTION: Repair a common problem with objects that are defined to return
519  *              a variable-length Package of Packages. If the variable-length
520  *              is one, some BIOS code mistakenly simply declares a single
521  *              Package instead of a Package with one sub-Package. This
522  *              function attempts to repair this error by wrapping a Package
523  *              object around the original Package, creating the correct
524  *              Package with one sub-Package.
525  *
526  *              Names that can be repaired in this manner include:
527  *              _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS
528  *
529  ******************************************************************************/
530 
531 acpi_status
532 acpi_ns_repair_package_list(struct acpi_predefined_data *data,
533 			    union acpi_operand_object **obj_desc_ptr)
534 {
535 	union acpi_operand_object *pkg_obj_desc;
536 
537 	ACPI_FUNCTION_NAME(ns_repair_package_list);
538 
539 	/*
540 	 * Create the new outer package and populate it. The new package will
541 	 * have a single element, the lone subpackage.
542 	 */
543 	pkg_obj_desc = acpi_ut_create_package_object(1);
544 	if (!pkg_obj_desc) {
545 		return (AE_NO_MEMORY);
546 	}
547 
548 	pkg_obj_desc->package.elements[0] = *obj_desc_ptr;
549 
550 	/* Return the new object in the object pointer */
551 
552 	*obj_desc_ptr = pkg_obj_desc;
553 	data->flags |= ACPI_OBJECT_REPAIRED;
554 
555 	ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
556 			  "%s: Repaired incorrectly formed Package\n",
557 			  data->pathname));
558 
559 	return (AE_OK);
560 }
561