xref: /openbmc/linux/drivers/acpi/acpica/exconfig.c (revision b04b4f78)
1 /******************************************************************************
2  *
3  * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes)
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2008, 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 "acinterp.h"
47 #include "acnamesp.h"
48 #include "actables.h"
49 #include "acdispat.h"
50 
51 #define _COMPONENT          ACPI_EXECUTER
52 ACPI_MODULE_NAME("exconfig")
53 
54 /* Local prototypes */
55 static acpi_status
56 acpi_ex_add_table(u32 table_index,
57 		  struct acpi_namespace_node *parent_node,
58 		  union acpi_operand_object **ddb_handle);
59 
60 /*******************************************************************************
61  *
62  * FUNCTION:    acpi_ex_add_table
63  *
64  * PARAMETERS:  Table               - Pointer to raw table
65  *              parent_node         - Where to load the table (scope)
66  *              ddb_handle          - Where to return the table handle.
67  *
68  * RETURN:      Status
69  *
70  * DESCRIPTION: Common function to Install and Load an ACPI table with a
71  *              returned table handle.
72  *
73  ******************************************************************************/
74 
75 static acpi_status
76 acpi_ex_add_table(u32 table_index,
77 		  struct acpi_namespace_node *parent_node,
78 		  union acpi_operand_object **ddb_handle)
79 {
80 	acpi_status status;
81 	union acpi_operand_object *obj_desc;
82 
83 	ACPI_FUNCTION_TRACE(ex_add_table);
84 
85 	/* Create an object to be the table handle */
86 
87 	obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE);
88 	if (!obj_desc) {
89 		return_ACPI_STATUS(AE_NO_MEMORY);
90 	}
91 
92 	/* Init the table handle */
93 
94 	obj_desc->reference.class = ACPI_REFCLASS_TABLE;
95 	*ddb_handle = obj_desc;
96 
97 	/* Install the new table into the local data structures */
98 
99 	obj_desc->reference.value = table_index;
100 
101 	/* Add the table to the namespace */
102 
103 	status = acpi_ns_load_table(table_index, parent_node);
104 	if (ACPI_FAILURE(status)) {
105 		acpi_ut_remove_reference(obj_desc);
106 		*ddb_handle = NULL;
107 	}
108 
109 	return_ACPI_STATUS(status);
110 }
111 
112 /*******************************************************************************
113  *
114  * FUNCTION:    acpi_ex_load_table_op
115  *
116  * PARAMETERS:  walk_state          - Current state with operands
117  *              return_desc         - Where to store the return object
118  *
119  * RETURN:      Status
120  *
121  * DESCRIPTION: Load an ACPI table from the RSDT/XSDT
122  *
123  ******************************************************************************/
124 
125 acpi_status
126 acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
127 		      union acpi_operand_object **return_desc)
128 {
129 	acpi_status status;
130 	union acpi_operand_object **operand = &walk_state->operands[0];
131 	struct acpi_namespace_node *parent_node;
132 	struct acpi_namespace_node *start_node;
133 	struct acpi_namespace_node *parameter_node = NULL;
134 	union acpi_operand_object *ddb_handle;
135 	struct acpi_table_header *table;
136 	u32 table_index;
137 
138 	ACPI_FUNCTION_TRACE(ex_load_table_op);
139 
140 	/* Validate lengths for the signature_string, OEMIDString, OEMtable_iD */
141 
142 	if ((operand[0]->string.length > ACPI_NAME_SIZE) ||
143 	    (operand[1]->string.length > ACPI_OEM_ID_SIZE) ||
144 	    (operand[2]->string.length > ACPI_OEM_TABLE_ID_SIZE)) {
145 		return_ACPI_STATUS(AE_BAD_PARAMETER);
146 	}
147 
148 	/* Find the ACPI table in the RSDT/XSDT */
149 
150 	status = acpi_tb_find_table(operand[0]->string.pointer,
151 				    operand[1]->string.pointer,
152 				    operand[2]->string.pointer, &table_index);
153 	if (ACPI_FAILURE(status)) {
154 		if (status != AE_NOT_FOUND) {
155 			return_ACPI_STATUS(status);
156 		}
157 
158 		/* Table not found, return an Integer=0 and AE_OK */
159 
160 		ddb_handle = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
161 		if (!ddb_handle) {
162 			return_ACPI_STATUS(AE_NO_MEMORY);
163 		}
164 
165 		ddb_handle->integer.value = 0;
166 		*return_desc = ddb_handle;
167 
168 		return_ACPI_STATUS(AE_OK);
169 	}
170 
171 	/* Default nodes */
172 
173 	start_node = walk_state->scope_info->scope.node;
174 	parent_node = acpi_gbl_root_node;
175 
176 	/* root_path (optional parameter) */
177 
178 	if (operand[3]->string.length > 0) {
179 		/*
180 		 * Find the node referenced by the root_path_string. This is the
181 		 * location within the namespace where the table will be loaded.
182 		 */
183 		status =
184 		    acpi_ns_get_node(start_node, operand[3]->string.pointer,
185 				     ACPI_NS_SEARCH_PARENT, &parent_node);
186 		if (ACPI_FAILURE(status)) {
187 			return_ACPI_STATUS(status);
188 		}
189 	}
190 
191 	/* parameter_path (optional parameter) */
192 
193 	if (operand[4]->string.length > 0) {
194 		if ((operand[4]->string.pointer[0] != '\\') &&
195 		    (operand[4]->string.pointer[0] != '^')) {
196 			/*
197 			 * Path is not absolute, so it will be relative to the node
198 			 * referenced by the root_path_string (or the NS root if omitted)
199 			 */
200 			start_node = parent_node;
201 		}
202 
203 		/* Find the node referenced by the parameter_path_string */
204 
205 		status =
206 		    acpi_ns_get_node(start_node, operand[4]->string.pointer,
207 				     ACPI_NS_SEARCH_PARENT, &parameter_node);
208 		if (ACPI_FAILURE(status)) {
209 			return_ACPI_STATUS(status);
210 		}
211 	}
212 
213 	/* Load the table into the namespace */
214 
215 	status = acpi_ex_add_table(table_index, parent_node, &ddb_handle);
216 	if (ACPI_FAILURE(status)) {
217 		return_ACPI_STATUS(status);
218 	}
219 
220 	/* Parameter Data (optional) */
221 
222 	if (parameter_node) {
223 
224 		/* Store the parameter data into the optional parameter object */
225 
226 		status = acpi_ex_store(operand[5],
227 				       ACPI_CAST_PTR(union acpi_operand_object,
228 						     parameter_node),
229 				       walk_state);
230 		if (ACPI_FAILURE(status)) {
231 			(void)acpi_ex_unload_table(ddb_handle);
232 			return_ACPI_STATUS(status);
233 		}
234 	}
235 
236 	status = acpi_get_table_by_index(table_index, &table);
237 	if (ACPI_SUCCESS(status)) {
238 		ACPI_INFO((AE_INFO,
239 			   "Dynamic OEM Table Load - [%.4s] OemId [%.6s] OemTableId [%.8s]",
240 			   table->signature, table->oem_id,
241 			   table->oem_table_id));
242 	}
243 
244 	/* Invoke table handler if present */
245 
246 	if (acpi_gbl_table_handler) {
247 		(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
248 					     acpi_gbl_table_handler_context);
249 	}
250 
251 	*return_desc = ddb_handle;
252 	return_ACPI_STATUS(status);
253 }
254 
255 /*******************************************************************************
256  *
257  * FUNCTION:    acpi_ex_load_op
258  *
259  * PARAMETERS:  obj_desc        - Region or Buffer/Field where the table will be
260  *                                obtained
261  *              Target          - Where a handle to the table will be stored
262  *              walk_state      - Current state
263  *
264  * RETURN:      Status
265  *
266  * DESCRIPTION: Load an ACPI table from a field or operation region
267  *
268  * NOTE: Region Fields (Field, bank_field, index_fields) are resolved to buffer
269  *       objects before this code is reached.
270  *
271  *       If source is an operation region, it must refer to system_memory, as
272  *       per the ACPI specification.
273  *
274  ******************************************************************************/
275 
276 acpi_status
277 acpi_ex_load_op(union acpi_operand_object *obj_desc,
278 		union acpi_operand_object *target,
279 		struct acpi_walk_state *walk_state)
280 {
281 	union acpi_operand_object *ddb_handle;
282 	struct acpi_table_header *table;
283 	struct acpi_table_desc table_desc;
284 	u32 table_index;
285 	acpi_status status;
286 	u32 length;
287 
288 	ACPI_FUNCTION_TRACE(ex_load_op);
289 
290 	ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc));
291 
292 	/* Source Object can be either an op_region or a Buffer/Field */
293 
294 	switch (obj_desc->common.type) {
295 	case ACPI_TYPE_REGION:
296 
297 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
298 				  "Load table from Region %p\n", obj_desc));
299 
300 		/* Region must be system_memory (from ACPI spec) */
301 
302 		if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
303 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
304 		}
305 
306 		/*
307 		 * If the Region Address and Length have not been previously evaluated,
308 		 * evaluate them now and save the results.
309 		 */
310 		if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
311 			status = acpi_ds_get_region_arguments(obj_desc);
312 			if (ACPI_FAILURE(status)) {
313 				return_ACPI_STATUS(status);
314 			}
315 		}
316 
317 		/*
318 		 * Map the table header and get the actual table length. The region
319 		 * length is not guaranteed to be the same as the table length.
320 		 */
321 		table = acpi_os_map_memory(obj_desc->region.address,
322 					   sizeof(struct acpi_table_header));
323 		if (!table) {
324 			return_ACPI_STATUS(AE_NO_MEMORY);
325 		}
326 
327 		length = table->length;
328 		acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
329 
330 		/* Must have at least an ACPI table header */
331 
332 		if (length < sizeof(struct acpi_table_header)) {
333 			return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
334 		}
335 
336 		/*
337 		 * The memory region is not guaranteed to remain stable and we must
338 		 * copy the table to a local buffer. For example, the memory region
339 		 * is corrupted after suspend on some machines. Dynamically loaded
340 		 * tables are usually small, so this overhead is minimal.
341 		 */
342 
343 		/* Allocate a buffer for the table */
344 
345 		table_desc.pointer = ACPI_ALLOCATE(length);
346 		if (!table_desc.pointer) {
347 			return_ACPI_STATUS(AE_NO_MEMORY);
348 		}
349 
350 		/* Map the entire table and copy it */
351 
352 		table = acpi_os_map_memory(obj_desc->region.address, length);
353 		if (!table) {
354 			ACPI_FREE(table_desc.pointer);
355 			return_ACPI_STATUS(AE_NO_MEMORY);
356 		}
357 
358 		ACPI_MEMCPY(table_desc.pointer, table, length);
359 		acpi_os_unmap_memory(table, length);
360 
361 		table_desc.address = obj_desc->region.address;
362 		break;
363 
364 	case ACPI_TYPE_BUFFER:	/* Buffer or resolved region_field */
365 
366 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
367 				  "Load table from Buffer or Field %p\n",
368 				  obj_desc));
369 
370 		/* Must have at least an ACPI table header */
371 
372 		if (obj_desc->buffer.length < sizeof(struct acpi_table_header)) {
373 			return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
374 		}
375 
376 		/* Get the actual table length from the table header */
377 
378 		table =
379 		    ACPI_CAST_PTR(struct acpi_table_header,
380 				  obj_desc->buffer.pointer);
381 		length = table->length;
382 
383 		/* Table cannot extend beyond the buffer */
384 
385 		if (length > obj_desc->buffer.length) {
386 			return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
387 		}
388 		if (length < sizeof(struct acpi_table_header)) {
389 			return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
390 		}
391 
392 		/*
393 		 * Copy the table from the buffer because the buffer could be modified
394 		 * or even deleted in the future
395 		 */
396 		table_desc.pointer = ACPI_ALLOCATE(length);
397 		if (!table_desc.pointer) {
398 			return_ACPI_STATUS(AE_NO_MEMORY);
399 		}
400 
401 		ACPI_MEMCPY(table_desc.pointer, table, length);
402 		table_desc.address = ACPI_TO_INTEGER(table_desc.pointer);
403 		break;
404 
405 	default:
406 		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
407 	}
408 
409 	/* Validate table checksum (will not get validated in tb_add_table) */
410 
411 	status = acpi_tb_verify_checksum(table_desc.pointer, length);
412 	if (ACPI_FAILURE(status)) {
413 		ACPI_FREE(table_desc.pointer);
414 		return_ACPI_STATUS(status);
415 	}
416 
417 	/* Complete the table descriptor */
418 
419 	table_desc.length = length;
420 	table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
421 
422 	/* Install the new table into the local data structures */
423 
424 	status = acpi_tb_add_table(&table_desc, &table_index);
425 	if (ACPI_FAILURE(status)) {
426 		goto cleanup;
427 	}
428 
429 	/*
430 	 * Add the table to the namespace.
431 	 *
432 	 * Note: Load the table objects relative to the root of the namespace.
433 	 * This appears to go against the ACPI specification, but we do it for
434 	 * compatibility with other ACPI implementations.
435 	 */
436 	status =
437 	    acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle);
438 	if (ACPI_FAILURE(status)) {
439 
440 		/* On error, table_ptr was deallocated above */
441 
442 		return_ACPI_STATUS(status);
443 	}
444 
445 	/* Store the ddb_handle into the Target operand */
446 
447 	status = acpi_ex_store(ddb_handle, target, walk_state);
448 	if (ACPI_FAILURE(status)) {
449 		(void)acpi_ex_unload_table(ddb_handle);
450 
451 		/* table_ptr was deallocated above */
452 
453 		acpi_ut_remove_reference(ddb_handle);
454 		return_ACPI_STATUS(status);
455 	}
456 
457 	/* Invoke table handler if present */
458 
459 	if (acpi_gbl_table_handler) {
460 		(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD,
461 					     table_desc.pointer,
462 					     acpi_gbl_table_handler_context);
463 	}
464 
465       cleanup:
466 	if (ACPI_FAILURE(status)) {
467 
468 		/* Delete allocated table buffer */
469 
470 		acpi_tb_delete_table(&table_desc);
471 	}
472 	return_ACPI_STATUS(status);
473 }
474 
475 /*******************************************************************************
476  *
477  * FUNCTION:    acpi_ex_unload_table
478  *
479  * PARAMETERS:  ddb_handle          - Handle to a previously loaded table
480  *
481  * RETURN:      Status
482  *
483  * DESCRIPTION: Unload an ACPI table
484  *
485  ******************************************************************************/
486 
487 acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
488 {
489 	acpi_status status = AE_OK;
490 	union acpi_operand_object *table_desc = ddb_handle;
491 	u32 table_index;
492 	struct acpi_table_header *table;
493 
494 	ACPI_FUNCTION_TRACE(ex_unload_table);
495 
496 	/*
497 	 * Validate the handle
498 	 * Although the handle is partially validated in acpi_ex_reconfiguration(),
499 	 * when it calls acpi_ex_resolve_operands(), the handle is more completely
500 	 * validated here.
501 	 */
502 	if ((!ddb_handle) ||
503 	    (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
504 	    (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE)) {
505 		return_ACPI_STATUS(AE_BAD_PARAMETER);
506 	}
507 
508 	/* Get the table index from the ddb_handle */
509 
510 	table_index = table_desc->reference.value;
511 
512 	/* Invoke table handler if present */
513 
514 	if (acpi_gbl_table_handler) {
515 		status = acpi_get_table_by_index(table_index, &table);
516 		if (ACPI_SUCCESS(status)) {
517 			(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD,
518 						     table,
519 						     acpi_gbl_table_handler_context);
520 		}
521 	}
522 
523 	/* Delete the portion of the namespace owned by this table */
524 
525 	status = acpi_tb_delete_namespace_by_owner(table_index);
526 	if (ACPI_FAILURE(status)) {
527 		return_ACPI_STATUS(status);
528 	}
529 
530 	(void)acpi_tb_release_owner_id(table_index);
531 	acpi_tb_set_table_loaded_flag(table_index, FALSE);
532 
533 	/* Table unloaded, remove a reference to the ddb_handle object */
534 
535 	acpi_ut_remove_reference(ddb_handle);
536 	return_ACPI_STATUS(AE_OK);
537 }
538