1 /******************************************************************************
3 * Module Name: amconfig - Namespace reconfiguration (Load/Unload opcodes)
6 *****************************************************************************/
9 * Copyright (C) 2000, 2001 R. Byron Moore
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 #define _COMPONENT ACPI_EXECUTER
38 MODULE_NAME ("amconfig")
41 /*****************************************************************************
43 * FUNCTION: Acpi_aml_exec_load_table
45 * PARAMETERS: Rgn_desc - Op region where the table will be obtained
46 * Ddb_handle - Where a handle to the table will be returned
50 * DESCRIPTION: Load an ACPI table
52 ****************************************************************************/
55 acpi_aml_exec_load_table (
56 ACPI_OPERAND_OBJECT *rgn_desc,
57 ACPI_HANDLE *ddb_handle)
60 ACPI_OPERAND_OBJECT *table_desc = NULL;
63 ACPI_TABLE_HEADER table_header;
64 ACPI_TABLE_DESC table_info;
68 /* TBD: [Unhandled] Object can be either a field or an opregion */
71 /* Get the table header */
73 table_header.length = 0;
74 for (i = 0; i < sizeof (ACPI_TABLE_HEADER); i++) {
75 status = acpi_ev_address_space_dispatch (rgn_desc, ADDRESS_SPACE_READ,
76 (ACPI_PHYSICAL_ADDRESS) i, 8,
77 (u32 *) ((u8 *) &table_header + i));
78 if (ACPI_FAILURE (status)) {
83 /* Allocate a buffer for the entire table */
85 table_ptr = acpi_cm_allocate (table_header.length);
87 return (AE_NO_MEMORY);
90 /* Copy the header to the buffer */
92 MEMCPY (table_ptr, &table_header, sizeof (ACPI_TABLE_HEADER));
93 table_data_ptr = table_ptr + sizeof (ACPI_TABLE_HEADER);
96 /* Get the table from the op region */
98 for (i = 0; i < table_header.length; i++) {
99 status = acpi_ev_address_space_dispatch (rgn_desc, ADDRESS_SPACE_READ,
100 (ACPI_PHYSICAL_ADDRESS)i, 8,
101 (u32 *) (table_data_ptr + i));
102 if (ACPI_FAILURE (status)) {
108 /* Table must be either an SSDT or a PSDT */
110 if ((!STRNCMP (table_header.signature,
111 acpi_gbl_acpi_table_data[ACPI_TABLE_PSDT].signature,
112 acpi_gbl_acpi_table_data[ACPI_TABLE_PSDT].sig_length)) &&
113 (!STRNCMP (table_header.signature,
114 acpi_gbl_acpi_table_data[ACPI_TABLE_SSDT].signature,
115 acpi_gbl_acpi_table_data[ACPI_TABLE_SSDT].sig_length))) {
116 status = AE_BAD_SIGNATURE;
120 /* Create an object to be the table handle */
122 table_desc = acpi_cm_create_internal_object (INTERNAL_TYPE_REFERENCE);
124 status = AE_NO_MEMORY;
129 /* Install the new table into the local data structures */
131 table_info.pointer = (ACPI_TABLE_HEADER *) table_ptr;
132 table_info.length = table_header.length;
133 table_info.allocation = ACPI_MEM_ALLOCATED;
134 table_info.base_pointer = table_ptr;
136 status = acpi_tb_install_table (NULL, &table_info);
137 if (ACPI_FAILURE (status)) {
141 /* Add the table to the namespace */
143 /* TBD: [Restructure] - change to whatever new interface is appropriate */
145 Status = Acpi_load_namespace ();
146 if (ACPI_FAILURE (Status))
149 /* TBD: [Errors] Unload the table on failure ? */
156 /* TBD: [Investigate] we need a pointer to the table desc */
158 /* Init the table handle */
160 table_desc->reference.opcode = AML_LOAD_OP;
161 table_desc->reference.object = table_info.installed_desc;
163 *ddb_handle = table_desc;
170 acpi_cm_free (table_desc);
171 acpi_cm_free (table_ptr);
177 /*****************************************************************************
179 * FUNCTION: Acpi_aml_exec_unload_table
181 * PARAMETERS: Ddb_handle - Handle to a previously loaded table
185 * DESCRIPTION: Unload an ACPI table
187 ****************************************************************************/
190 acpi_aml_exec_unload_table (
191 ACPI_HANDLE ddb_handle)
193 ACPI_STATUS status = AE_NOT_IMPLEMENTED;
194 ACPI_OPERAND_OBJECT *table_desc = (ACPI_OPERAND_OBJECT *) ddb_handle;
195 ACPI_TABLE_DESC *table_info;
198 /* Validate the handle */
199 /* Although the handle is partially validated in Acpi_aml_exec_reconfiguration(),
200 * when it calls Acpi_aml_resolve_operands(), the handle is more completely
205 (!VALID_DESCRIPTOR_TYPE (ddb_handle, ACPI_DESC_TYPE_INTERNAL)) ||
206 (((ACPI_OPERAND_OBJECT *)ddb_handle)->common.type !=
207 INTERNAL_TYPE_REFERENCE)) {
208 return (AE_BAD_PARAMETER);
212 /* Get the actual table descriptor from the Ddb_handle */
214 table_info = (ACPI_TABLE_DESC *) table_desc->reference.object;
217 * Delete the entire namespace under this table Node
218 * (Offset contains the Table_id)
221 status = acpi_ns_delete_namespace_by_owner (table_info->table_id);
222 if (ACPI_FAILURE (status)) {
226 /* Delete the table itself */
228 acpi_tb_uninstall_table (table_info->installed_desc);
230 /* Delete the table descriptor (Ddb_handle) */
232 acpi_cm_remove_reference (table_desc);
238 /*****************************************************************************
240 * FUNCTION: Acpi_aml_exec_reconfiguration
242 * PARAMETERS: Opcode - The opcode to be executed
243 * Walk_state - Current state of the parse tree walk
247 * DESCRIPTION: Reconfiguration opcodes such as LOAD and UNLOAD
249 ****************************************************************************/
252 acpi_aml_exec_reconfiguration (
254 ACPI_WALK_STATE *walk_state)
257 ACPI_OPERAND_OBJECT *region_desc = NULL;
258 ACPI_HANDLE *ddb_handle;
261 /* Resolve the operands */
263 status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
264 /* Get the table handle, common for both opcodes */
266 status |= acpi_ds_obj_stack_pop_object ((ACPI_OPERAND_OBJECT **) &ddb_handle,
273 /* Get the region or field descriptor */
275 status |= acpi_ds_obj_stack_pop_object (®ion_desc, walk_state);
276 if (ACPI_FAILURE (status)) {
277 acpi_cm_remove_reference (region_desc);
281 status = acpi_aml_exec_load_table (region_desc, ddb_handle);
287 if (ACPI_FAILURE (status)) {
291 status = acpi_aml_exec_unload_table (ddb_handle);
297 status = AE_AML_BAD_OPCODE;