Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/acpi/acpica/dsargs.c
15109 views
1
/******************************************************************************
2
*
3
* Module Name: dsargs - Support for execution of dynamic arguments for static
4
* objects (regions, fields, buffer fields, etc.)
5
*
6
*****************************************************************************/
7
8
/*
9
* Copyright (C) 2000 - 2011, Intel Corp.
10
* All rights reserved.
11
*
12
* Redistribution and use in source and binary forms, with or without
13
* modification, are permitted provided that the following conditions
14
* are met:
15
* 1. Redistributions of source code must retain the above copyright
16
* notice, this list of conditions, and the following disclaimer,
17
* without modification.
18
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
19
* substantially similar to the "NO WARRANTY" disclaimer below
20
* ("Disclaimer") and any redistribution must be conditioned upon
21
* including a substantially similar Disclaimer requirement for further
22
* binary redistribution.
23
* 3. Neither the names of the above-listed copyright holders nor the names
24
* of any contributors may be used to endorse or promote products derived
25
* from this software without specific prior written permission.
26
*
27
* Alternatively, this software may be distributed under the terms of the
28
* GNU General Public License ("GPL") version 2 as published by the Free
29
* Software Foundation.
30
*
31
* NO WARRANTY
32
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42
* POSSIBILITY OF SUCH DAMAGES.
43
*/
44
45
#include <acpi/acpi.h>
46
#include "accommon.h"
47
#include "acparser.h"
48
#include "amlcode.h"
49
#include "acdispat.h"
50
#include "acnamesp.h"
51
52
#define _COMPONENT ACPI_DISPATCHER
53
ACPI_MODULE_NAME("dsargs")
54
55
/* Local prototypes */
56
static acpi_status
57
acpi_ds_execute_arguments(struct acpi_namespace_node *node,
58
struct acpi_namespace_node *scope_node,
59
u32 aml_length, u8 *aml_start);
60
61
/*******************************************************************************
62
*
63
* FUNCTION: acpi_ds_execute_arguments
64
*
65
* PARAMETERS: Node - Object NS node
66
* scope_node - Parent NS node
67
* aml_length - Length of executable AML
68
* aml_start - Pointer to the AML
69
*
70
* RETURN: Status.
71
*
72
* DESCRIPTION: Late (deferred) execution of region or field arguments
73
*
74
******************************************************************************/
75
76
static acpi_status
77
acpi_ds_execute_arguments(struct acpi_namespace_node *node,
78
struct acpi_namespace_node *scope_node,
79
u32 aml_length, u8 *aml_start)
80
{
81
acpi_status status;
82
union acpi_parse_object *op;
83
struct acpi_walk_state *walk_state;
84
85
ACPI_FUNCTION_TRACE(ds_execute_arguments);
86
87
/* Allocate a new parser op to be the root of the parsed tree */
88
89
op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP);
90
if (!op) {
91
return_ACPI_STATUS(AE_NO_MEMORY);
92
}
93
94
/* Save the Node for use in acpi_ps_parse_aml */
95
96
op->common.node = scope_node;
97
98
/* Create and initialize a new parser state */
99
100
walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
101
if (!walk_state) {
102
status = AE_NO_MEMORY;
103
goto cleanup;
104
}
105
106
status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
107
aml_length, NULL, ACPI_IMODE_LOAD_PASS1);
108
if (ACPI_FAILURE(status)) {
109
acpi_ds_delete_walk_state(walk_state);
110
goto cleanup;
111
}
112
113
/* Mark this parse as a deferred opcode */
114
115
walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP;
116
walk_state->deferred_node = node;
117
118
/* Pass1: Parse the entire declaration */
119
120
status = acpi_ps_parse_aml(walk_state);
121
if (ACPI_FAILURE(status)) {
122
goto cleanup;
123
}
124
125
/* Get and init the Op created above */
126
127
op->common.node = node;
128
acpi_ps_delete_parse_tree(op);
129
130
/* Evaluate the deferred arguments */
131
132
op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP);
133
if (!op) {
134
return_ACPI_STATUS(AE_NO_MEMORY);
135
}
136
137
op->common.node = scope_node;
138
139
/* Create and initialize a new parser state */
140
141
walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
142
if (!walk_state) {
143
status = AE_NO_MEMORY;
144
goto cleanup;
145
}
146
147
/* Execute the opcode and arguments */
148
149
status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
150
aml_length, NULL, ACPI_IMODE_EXECUTE);
151
if (ACPI_FAILURE(status)) {
152
acpi_ds_delete_walk_state(walk_state);
153
goto cleanup;
154
}
155
156
/* Mark this execution as a deferred opcode */
157
158
walk_state->deferred_node = node;
159
status = acpi_ps_parse_aml(walk_state);
160
161
cleanup:
162
acpi_ps_delete_parse_tree(op);
163
return_ACPI_STATUS(status);
164
}
165
166
/*******************************************************************************
167
*
168
* FUNCTION: acpi_ds_get_buffer_field_arguments
169
*
170
* PARAMETERS: obj_desc - A valid buffer_field object
171
*
172
* RETURN: Status.
173
*
174
* DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
175
* evaluation of these field attributes.
176
*
177
******************************************************************************/
178
179
acpi_status
180
acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)
181
{
182
union acpi_operand_object *extra_desc;
183
struct acpi_namespace_node *node;
184
acpi_status status;
185
186
ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc);
187
188
if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
189
return_ACPI_STATUS(AE_OK);
190
}
191
192
/* Get the AML pointer (method object) and buffer_field node */
193
194
extra_desc = acpi_ns_get_secondary_object(obj_desc);
195
node = obj_desc->buffer_field.node;
196
197
ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_BUFFER_FIELD,
198
node, NULL));
199
200
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
201
acpi_ut_get_node_name(node)));
202
203
/* Execute the AML code for the term_arg arguments */
204
205
status = acpi_ds_execute_arguments(node, node->parent,
206
extra_desc->extra.aml_length,
207
extra_desc->extra.aml_start);
208
return_ACPI_STATUS(status);
209
}
210
211
/*******************************************************************************
212
*
213
* FUNCTION: acpi_ds_get_bank_field_arguments
214
*
215
* PARAMETERS: obj_desc - A valid bank_field object
216
*
217
* RETURN: Status.
218
*
219
* DESCRIPTION: Get bank_field bank_value. This implements the late
220
* evaluation of these field attributes.
221
*
222
******************************************************************************/
223
224
acpi_status
225
acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)
226
{
227
union acpi_operand_object *extra_desc;
228
struct acpi_namespace_node *node;
229
acpi_status status;
230
231
ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc);
232
233
if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
234
return_ACPI_STATUS(AE_OK);
235
}
236
237
/* Get the AML pointer (method object) and bank_field node */
238
239
extra_desc = acpi_ns_get_secondary_object(obj_desc);
240
node = obj_desc->bank_field.node;
241
242
ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
243
(ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL));
244
245
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
246
acpi_ut_get_node_name(node)));
247
248
/* Execute the AML code for the term_arg arguments */
249
250
status = acpi_ds_execute_arguments(node, node->parent,
251
extra_desc->extra.aml_length,
252
extra_desc->extra.aml_start);
253
return_ACPI_STATUS(status);
254
}
255
256
/*******************************************************************************
257
*
258
* FUNCTION: acpi_ds_get_buffer_arguments
259
*
260
* PARAMETERS: obj_desc - A valid Buffer object
261
*
262
* RETURN: Status.
263
*
264
* DESCRIPTION: Get Buffer length and initializer byte list. This implements
265
* the late evaluation of these attributes.
266
*
267
******************************************************************************/
268
269
acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc)
270
{
271
struct acpi_namespace_node *node;
272
acpi_status status;
273
274
ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc);
275
276
if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
277
return_ACPI_STATUS(AE_OK);
278
}
279
280
/* Get the Buffer node */
281
282
node = obj_desc->buffer.node;
283
if (!node) {
284
ACPI_ERROR((AE_INFO,
285
"No pointer back to namespace node in buffer object %p",
286
obj_desc));
287
return_ACPI_STATUS(AE_AML_INTERNAL);
288
}
289
290
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n"));
291
292
/* Execute the AML code for the term_arg arguments */
293
294
status = acpi_ds_execute_arguments(node, node,
295
obj_desc->buffer.aml_length,
296
obj_desc->buffer.aml_start);
297
return_ACPI_STATUS(status);
298
}
299
300
/*******************************************************************************
301
*
302
* FUNCTION: acpi_ds_get_package_arguments
303
*
304
* PARAMETERS: obj_desc - A valid Package object
305
*
306
* RETURN: Status.
307
*
308
* DESCRIPTION: Get Package length and initializer byte list. This implements
309
* the late evaluation of these attributes.
310
*
311
******************************************************************************/
312
313
acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc)
314
{
315
struct acpi_namespace_node *node;
316
acpi_status status;
317
318
ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc);
319
320
if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
321
return_ACPI_STATUS(AE_OK);
322
}
323
324
/* Get the Package node */
325
326
node = obj_desc->package.node;
327
if (!node) {
328
ACPI_ERROR((AE_INFO,
329
"No pointer back to namespace node in package %p",
330
obj_desc));
331
return_ACPI_STATUS(AE_AML_INTERNAL);
332
}
333
334
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Arg Init\n"));
335
336
/* Execute the AML code for the term_arg arguments */
337
338
status = acpi_ds_execute_arguments(node, node,
339
obj_desc->package.aml_length,
340
obj_desc->package.aml_start);
341
return_ACPI_STATUS(status);
342
}
343
344
/*******************************************************************************
345
*
346
* FUNCTION: acpi_ds_get_region_arguments
347
*
348
* PARAMETERS: obj_desc - A valid region object
349
*
350
* RETURN: Status.
351
*
352
* DESCRIPTION: Get region address and length. This implements the late
353
* evaluation of these region attributes.
354
*
355
******************************************************************************/
356
357
acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
358
{
359
struct acpi_namespace_node *node;
360
acpi_status status;
361
union acpi_operand_object *extra_desc;
362
363
ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc);
364
365
if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
366
return_ACPI_STATUS(AE_OK);
367
}
368
369
extra_desc = acpi_ns_get_secondary_object(obj_desc);
370
if (!extra_desc) {
371
return_ACPI_STATUS(AE_NOT_EXIST);
372
}
373
374
/* Get the Region node */
375
376
node = obj_desc->region.node;
377
378
ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
379
(ACPI_TYPE_REGION, node, NULL));
380
381
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",
382
acpi_ut_get_node_name(node),
383
extra_desc->extra.aml_start));
384
385
/* Execute the argument AML */
386
387
status = acpi_ds_execute_arguments(node, node->parent,
388
extra_desc->extra.aml_length,
389
extra_desc->extra.aml_start);
390
return_ACPI_STATUS(status);
391
}
392
393