Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6595 serge 1
/******************************************************************************
2
 *
3
 * Module Name: psxface - Parser external interfaces
4
 *
5
 *****************************************************************************/
6
 
7
/*
8
 * Copyright (C) 2000 - 2015, 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 
45
#include "accommon.h"
46
#include "acparser.h"
47
#include "acdispat.h"
48
#include "acinterp.h"
49
#include "actables.h"
50
#include "acnamesp.h"
51
 
52
#define _COMPONENT          ACPI_PARSER
53
ACPI_MODULE_NAME("psxface")
54
 
55
/* Local Prototypes */
56
static void
57
acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action);
58
 
59
/*******************************************************************************
60
 *
61
 * FUNCTION:    acpi_debug_trace
62
 *
63
 * PARAMETERS:  method_name     - Valid ACPI name string
64
 *              debug_level     - Optional level mask. 0 to use default
65
 *              debug_layer     - Optional layer mask. 0 to use default
66
 *              flags           - bit 1: one shot(1) or persistent(0)
67
 *
68
 * RETURN:      Status
69
 *
70
 * DESCRIPTION: External interface to enable debug tracing during control
71
 *              method execution
72
 *
73
 ******************************************************************************/
74
 
75
acpi_status
76
acpi_debug_trace(const char *name, u32 debug_level, u32 debug_layer, u32 flags)
77
{
78
	acpi_status status;
79
 
80
	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
81
	if (ACPI_FAILURE(status)) {
82
		return (status);
83
	}
84
 
85
	acpi_gbl_trace_method_name = name;
86
	acpi_gbl_trace_flags = flags;
87
	acpi_gbl_trace_dbg_level = debug_level;
88
	acpi_gbl_trace_dbg_layer = debug_layer;
89
	status = AE_OK;
90
 
91
	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
92
	return (status);
93
}
94
 
95
/*******************************************************************************
96
 *
97
 * FUNCTION:    acpi_ps_execute_method
98
 *
99
 * PARAMETERS:  info            - Method info block, contains:
100
 *                  node            - Method Node to execute
101
 *                  obj_desc        - Method object
102
 *                  parameters      - List of parameters to pass to the method,
103
 *                                    terminated by NULL. Params itself may be
104
 *                                    NULL if no parameters are being passed.
105
 *                  return_object   - Where to put method's return value (if
106
 *                                    any). If NULL, no value is returned.
107
 *                  parameter_type  - Type of Parameter list
108
 *                  return_object   - Where to put method's return value (if
109
 *                                    any). If NULL, no value is returned.
110
 *                  pass_number     - Parse or execute pass
111
 *
112
 * RETURN:      Status
113
 *
114
 * DESCRIPTION: Execute a control method
115
 *
116
 ******************************************************************************/
117
 
118
acpi_status acpi_ps_execute_method(struct acpi_evaluate_info * info)
119
{
120
	acpi_status status;
121
	union acpi_parse_object *op;
122
	struct acpi_walk_state *walk_state;
123
 
124
	ACPI_FUNCTION_TRACE(ps_execute_method);
125
 
126
	/* Quick validation of DSDT header */
127
 
128
	acpi_tb_check_dsdt_header();
129
 
130
	/* Validate the Info and method Node */
131
 
132
	if (!info || !info->node) {
133
		return_ACPI_STATUS(AE_NULL_ENTRY);
134
	}
135
 
136
	/* Init for new method, wait on concurrency semaphore */
137
 
138
	status =
139
	    acpi_ds_begin_method_execution(info->node, info->obj_desc, NULL);
140
	if (ACPI_FAILURE(status)) {
141
		return_ACPI_STATUS(status);
142
	}
143
 
144
	/*
145
	 * The caller "owns" the parameters, so give each one an extra reference
146
	 */
147
	acpi_ps_update_parameter_list(info, REF_INCREMENT);
148
 
149
	/*
150
	 * Execute the method. Performs parse simultaneously
151
	 */
152
	ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
153
			  "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n",
154
			  info->node->name.ascii, info->node, info->obj_desc));
155
 
156
	/* Create and init a Root Node */
157
 
158
	op = acpi_ps_create_scope_op(info->obj_desc->method.aml_start);
159
	if (!op) {
160
		status = AE_NO_MEMORY;
161
		goto cleanup;
162
	}
163
 
164
	/* Create and initialize a new walk state */
165
 
166
	info->pass_number = ACPI_IMODE_EXECUTE;
167
	walk_state =
168
	    acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
169
				      NULL, NULL);
170
	if (!walk_state) {
171
		status = AE_NO_MEMORY;
172
		goto cleanup;
173
	}
174
 
175
	status = acpi_ds_init_aml_walk(walk_state, op, info->node,
176
				       info->obj_desc->method.aml_start,
177
				       info->obj_desc->method.aml_length, info,
178
				       info->pass_number);
179
	if (ACPI_FAILURE(status)) {
180
		acpi_ds_delete_walk_state(walk_state);
181
		goto cleanup;
182
	}
183
 
184
	if (info->obj_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) {
185
		walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL;
186
	}
187
 
188
	/* Invoke an internal method if necessary */
189
 
190
	if (info->obj_desc->method.info_flags & ACPI_METHOD_INTERNAL_ONLY) {
191
		status =
192
		    info->obj_desc->method.dispatch.implementation(walk_state);
193
		info->return_object = walk_state->return_desc;
194
 
195
		/* Cleanup states */
196
 
197
		acpi_ds_scope_stack_clear(walk_state);
198
		acpi_ps_cleanup_scope(&walk_state->parser_state);
199
		acpi_ds_terminate_control_method(walk_state->method_desc,
200
						 walk_state);
201
		acpi_ds_delete_walk_state(walk_state);
202
		goto cleanup;
203
	}
204
 
205
	/*
206
	 * Start method evaluation with an implicit return of zero.
207
	 * This is done for Windows compatibility.
208
	 */
209
	if (acpi_gbl_enable_interpreter_slack) {
210
		walk_state->implicit_return_obj =
211
		    acpi_ut_create_integer_object((u64) 0);
212
		if (!walk_state->implicit_return_obj) {
213
			status = AE_NO_MEMORY;
214
			acpi_ds_delete_walk_state(walk_state);
215
			goto cleanup;
216
		}
217
	}
218
 
219
	/* Parse the AML */
220
 
221
	status = acpi_ps_parse_aml(walk_state);
222
 
223
	/* walk_state was deleted by parse_aml */
224
 
225
cleanup:
226
	acpi_ps_delete_parse_tree(op);
227
 
228
	/* Take away the extra reference that we gave the parameters above */
229
 
230
	acpi_ps_update_parameter_list(info, REF_DECREMENT);
231
 
232
	/* Exit now if error above */
233
 
234
	if (ACPI_FAILURE(status)) {
235
		return_ACPI_STATUS(status);
236
	}
237
 
238
	/*
239
	 * If the method has returned an object, signal this to the caller with
240
	 * a control exception code
241
	 */
242
	if (info->return_object) {
243
		ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n",
244
				  info->return_object));
245
		ACPI_DUMP_STACK_ENTRY(info->return_object);
246
 
247
		status = AE_CTRL_RETURN_VALUE;
248
	}
249
 
250
	return_ACPI_STATUS(status);
251
}
252
 
253
/*******************************************************************************
254
 *
255
 * FUNCTION:    acpi_ps_update_parameter_list
256
 *
257
 * PARAMETERS:  info            - See struct acpi_evaluate_info
258
 *                                (Used: parameter_type and Parameters)
259
 *              action          - Add or Remove reference
260
 *
261
 * RETURN:      Status
262
 *
263
 * DESCRIPTION: Update reference count on all method parameter objects
264
 *
265
 ******************************************************************************/
266
 
267
static void
268
acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action)
269
{
270
	u32 i;
271
 
272
	if (info->parameters) {
273
 
274
		/* Update reference count for each parameter */
275
 
276
		for (i = 0; info->parameters[i]; i++) {
277
 
278
			/* Ignore errors, just do them all */
279
 
280
			(void)acpi_ut_update_object_reference(info->
281
							      parameters[i],
282
							      action);
283
		}
284
	}
285
}