ACPICA: Interpreter: Fix MLC issues by switching to new term_list grammar for table...
[cascardo/linux.git] / drivers / acpi / acpica / nsparse.c
1 /******************************************************************************
2  *
3  * Module Name: nsparse - namespace interface to AML parser
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2016, 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 "acparser.h"
48 #include "acdispat.h"
49 #include "actables.h"
50
51 #define _COMPONENT          ACPI_NAMESPACE
52 ACPI_MODULE_NAME("nsparse")
53
54 /*******************************************************************************
55  *
56  * FUNCTION:    ns_execute_table
57  *
58  * PARAMETERS:  table_desc      - An ACPI table descriptor for table to parse
59  *              start_node      - Where to enter the table into the namespace
60  *
61  * RETURN:      Status
62  *
63  * DESCRIPTION: Load ACPI/AML table by executing the entire table as a
64  *              term_list.
65  *
66  ******************************************************************************/
67 acpi_status
68 acpi_ns_execute_table(u32 table_index, struct acpi_namespace_node *start_node)
69 {
70         acpi_status status;
71         struct acpi_table_header *table;
72         acpi_owner_id owner_id;
73         struct acpi_evaluate_info *info = NULL;
74         u32 aml_length;
75         u8 *aml_start;
76         union acpi_operand_object *method_obj = NULL;
77
78         ACPI_FUNCTION_TRACE(ns_execute_table);
79
80         status = acpi_get_table_by_index(table_index, &table);
81         if (ACPI_FAILURE(status)) {
82                 return_ACPI_STATUS(status);
83         }
84
85         /* Table must consist of at least a complete header */
86
87         if (table->length < sizeof(struct acpi_table_header)) {
88                 return_ACPI_STATUS(AE_BAD_HEADER);
89         }
90
91         aml_start = (u8 *)table + sizeof(struct acpi_table_header);
92         aml_length = table->length - sizeof(struct acpi_table_header);
93
94         status = acpi_tb_get_owner_id(table_index, &owner_id);
95         if (ACPI_FAILURE(status)) {
96                 return_ACPI_STATUS(status);
97         }
98
99         /* Create, initialize, and link a new temporary method object */
100
101         method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
102         if (!method_obj) {
103                 return_ACPI_STATUS(AE_NO_MEMORY);
104         }
105
106         /* Allocate the evaluation information block */
107
108         info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
109         if (!info) {
110                 status = AE_NO_MEMORY;
111                 goto cleanup;
112         }
113
114         ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
115                           "Create table code block: %p\n", method_obj));
116
117         method_obj->method.aml_start = aml_start;
118         method_obj->method.aml_length = aml_length;
119         method_obj->method.owner_id = owner_id;
120         method_obj->method.info_flags |= ACPI_METHOD_MODULE_LEVEL;
121
122         info->pass_number = ACPI_IMODE_EXECUTE;
123         info->node = start_node;
124         info->obj_desc = method_obj;
125         info->node_flags = info->node->flags;
126         info->full_pathname = acpi_ns_get_normalized_pathname(info->node, TRUE);
127         if (!info->full_pathname) {
128                 status = AE_NO_MEMORY;
129                 goto cleanup;
130         }
131
132         status = acpi_ps_execute_table(info);
133
134 cleanup:
135         if (info) {
136                 ACPI_FREE(info->full_pathname);
137                 info->full_pathname = NULL;
138         }
139         ACPI_FREE(info);
140         acpi_ut_remove_reference(method_obj);
141         return_ACPI_STATUS(status);
142 }
143
144 /*******************************************************************************
145  *
146  * FUNCTION:    ns_one_complete_parse
147  *
148  * PARAMETERS:  pass_number             - 1 or 2
149  *              table_desc              - The table to be parsed.
150  *
151  * RETURN:      Status
152  *
153  * DESCRIPTION: Perform one complete parse of an ACPI/AML table.
154  *
155  ******************************************************************************/
156
157 acpi_status
158 acpi_ns_one_complete_parse(u32 pass_number,
159                            u32 table_index,
160                            struct acpi_namespace_node *start_node)
161 {
162         union acpi_parse_object *parse_root;
163         acpi_status status;
164         u32 aml_length;
165         u8 *aml_start;
166         struct acpi_walk_state *walk_state;
167         struct acpi_table_header *table;
168         acpi_owner_id owner_id;
169
170         ACPI_FUNCTION_TRACE(ns_one_complete_parse);
171
172         status = acpi_get_table_by_index(table_index, &table);
173         if (ACPI_FAILURE(status)) {
174                 return_ACPI_STATUS(status);
175         }
176
177         /* Table must consist of at least a complete header */
178
179         if (table->length < sizeof(struct acpi_table_header)) {
180                 return_ACPI_STATUS(AE_BAD_HEADER);
181         }
182
183         aml_start = (u8 *)table + sizeof(struct acpi_table_header);
184         aml_length = table->length - sizeof(struct acpi_table_header);
185
186         status = acpi_tb_get_owner_id(table_index, &owner_id);
187         if (ACPI_FAILURE(status)) {
188                 return_ACPI_STATUS(status);
189         }
190
191         /* Create and init a Root Node */
192
193         parse_root = acpi_ps_create_scope_op(aml_start);
194         if (!parse_root) {
195                 return_ACPI_STATUS(AE_NO_MEMORY);
196         }
197
198         /* Create and initialize a new walk state */
199
200         walk_state = acpi_ds_create_walk_state(owner_id, NULL, NULL, NULL);
201         if (!walk_state) {
202                 acpi_ps_free_op(parse_root);
203                 return_ACPI_STATUS(AE_NO_MEMORY);
204         }
205
206         status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL,
207                                        aml_start, aml_length, NULL,
208                                        (u8)pass_number);
209         if (ACPI_FAILURE(status)) {
210                 acpi_ds_delete_walk_state(walk_state);
211                 goto cleanup;
212         }
213
214         /* Found OSDT table, enable the namespace override feature */
215
216         if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_OSDT) &&
217             pass_number == ACPI_IMODE_LOAD_PASS1) {
218                 walk_state->namespace_override = TRUE;
219         }
220
221         /* start_node is the default location to load the table */
222
223         if (start_node && start_node != acpi_gbl_root_node) {
224                 status =
225                     acpi_ds_scope_stack_push(start_node, ACPI_TYPE_METHOD,
226                                              walk_state);
227                 if (ACPI_FAILURE(status)) {
228                         acpi_ds_delete_walk_state(walk_state);
229                         goto cleanup;
230                 }
231         }
232
233         /* Parse the AML */
234
235         ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
236                           "*PARSE* pass %u parse\n", pass_number));
237         status = acpi_ps_parse_aml(walk_state);
238
239 cleanup:
240         acpi_ps_delete_parse_tree(parse_root);
241         return_ACPI_STATUS(status);
242 }
243
244 /*******************************************************************************
245  *
246  * FUNCTION:    acpi_ns_parse_table
247  *
248  * PARAMETERS:  table_desc      - An ACPI table descriptor for table to parse
249  *              start_node      - Where to enter the table into the namespace
250  *
251  * RETURN:      Status
252  *
253  * DESCRIPTION: Parse AML within an ACPI table and return a tree of ops
254  *
255  ******************************************************************************/
256
257 acpi_status
258 acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
259 {
260         acpi_status status;
261
262         ACPI_FUNCTION_TRACE(ns_parse_table);
263
264         if (acpi_gbl_parse_table_as_term_list) {
265                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start load pass\n"));
266
267                 status = acpi_ns_execute_table(table_index, start_node);
268                 if (ACPI_FAILURE(status)) {
269                         return_ACPI_STATUS(status);
270                 }
271         } else {
272                 /*
273                  * AML Parse, pass 1
274                  *
275                  * In this pass, we load most of the namespace. Control methods
276                  * are not parsed until later. A parse tree is not created.
277                  * Instead, each Parser Op subtree is deleted when it is finished.
278                  * This saves a great deal of memory, and allows a small cache of
279                  * parse objects to service the entire parse. The second pass of
280                  * the parse then performs another complete parse of the AML.
281                  */
282                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
283
284                 status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1,
285                                                     table_index, start_node);
286                 if (ACPI_FAILURE(status)) {
287                         return_ACPI_STATUS(status);
288                 }
289
290                 /*
291                  * AML Parse, pass 2
292                  *
293                  * In this pass, we resolve forward references and other things
294                  * that could not be completed during the first pass.
295                  * Another complete parse of the AML is performed, but the
296                  * overhead of this is compensated for by the fact that the
297                  * parse objects are all cached.
298                  */
299                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n"));
300                 status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2,
301                                                     table_index, start_node);
302                 if (ACPI_FAILURE(status)) {
303                         return_ACPI_STATUS(status);
304                 }
305         }
306
307         return_ACPI_STATUS(status);
308 }